001package armyc2.c5isr.renderer; 002 003import java.util.ArrayList; 004import java.util.List; 005import java.util.Locale; 006import java.util.Map; 007 008import android.graphics.Bitmap; 009import android.graphics.Canvas; 010import android.graphics.DashPathEffect; 011import android.graphics.Paint; 012import android.graphics.Path; 013import android.graphics.Point; 014import android.graphics.PointF; 015import android.graphics.Rect; 016import android.graphics.RectF; 017import android.graphics.Bitmap.Config; 018import android.graphics.Paint.Cap; 019import android.graphics.Paint.Join; 020import android.graphics.Paint.Style; 021import android.graphics.Path.Direction; 022import android.graphics.Typeface; 023 024import armyc2.c5isr.renderer.utilities.Color; 025import armyc2.c5isr.renderer.utilities.ErrorLogger; 026import armyc2.c5isr.renderer.utilities.GENCLookup; 027import armyc2.c5isr.renderer.utilities.ImageInfo; 028import armyc2.c5isr.renderer.utilities.MSInfo; 029import armyc2.c5isr.renderer.utilities.MSLookup; 030import armyc2.c5isr.renderer.utilities.MilStdAttributes; 031import armyc2.c5isr.renderer.utilities.Modifier; 032import armyc2.c5isr.renderer.utilities.Modifiers; 033import armyc2.c5isr.renderer.utilities.PathUtilities; 034import armyc2.c5isr.renderer.utilities.RectUtilities; 035import armyc2.c5isr.renderer.utilities.RendererSettings; 036import armyc2.c5isr.renderer.utilities.RendererUtilities; 037import armyc2.c5isr.renderer.utilities.SVGInfo; 038import armyc2.c5isr.renderer.utilities.SVGLookup; 039import armyc2.c5isr.renderer.utilities.SVGPath; 040import armyc2.c5isr.renderer.utilities.SVGSymbolInfo; 041import armyc2.c5isr.renderer.utilities.Shape2SVG; 042import armyc2.c5isr.renderer.utilities.SymbolDimensionInfo; 043import armyc2.c5isr.renderer.utilities.SymbolID; 044import armyc2.c5isr.renderer.utilities.SymbolUtilities; 045import armyc2.c5isr.renderer.utilities.TextInfo; 046 047/** 048 * This class is used for rendering the labels/amplifiers/modifiers around the single point symbol. 049 */ 050public class ModifierRenderer 051{ 052 053 private static Paint _modifierFont = null; 054 private static float _modifierFontHeight = 10f; 055 private static float _modifierFontDescent = 2f; 056 private static RendererSettings RS = RendererSettings.getInstance(); 057 058 private static final Object modifierFontMutex = new Object(); 059 public static void setModifierFont(Paint font, float height, float descent) 060 { 061 synchronized (modifierFontMutex) { 062 _modifierFont = font; 063 _modifierFontHeight = height; 064 _modifierFontDescent = descent; 065 } 066 } 067 068 public static SymbolDimensionInfo processUnitDisplayModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Boolean hasTextModifiers, Map<String,String> attributes) 069 { 070 071 ImageInfo ii = null; 072 ImageInfo newii = null; 073 SVGSymbolInfo ssi = null; 074 SymbolDimensionInfo newsdi = null; 075 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 076 Rect imageBounds = new Rect(sdi.getImageBounds()); 077 Point centerPoint = new Point(sdi.getCenterPoint()); 078 Point symbolCenter = new Point(symbolBounds.centerX(), symbolBounds.centerY()); 079 TextInfo tiEchelon = null; 080 TextInfo tiAM = null; 081 Rect echelonBounds = null; 082 Rect amBounds = null; 083 Color textColor = Color.BLACK; 084 Color textBackgroundColor = null; 085 float strokeWidth = 3.0f; 086 float strokeWidthNL = 3.0f; 087 Color lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID); 088 Color fillColor = SymbolUtilities.getFillColorOfAffiliation(symbolID); 089 int buffer = 0; 090 int alpha = 255; 091 //ctx = null; 092 int offsetX = 0; 093 int offsetY = 0; 094 int pixelSize = RendererSettings.getInstance().getDefaultPixelSize(); 095 SVGPath svgMobilityPath = null; 096 String svgMobilityGroup = null; 097 098 Paint modifierFont = getFont(attributes); 099 float[] hd = getFontHeightandDescent(modifierFont); 100 float modifierFontHeight = hd[0]; 101 float modifierFontDescent = hd[1]; 102 103 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 104 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 105 { 106 String temp = attributes.get(MilStdAttributes.FontFamily); 107 if(temp != null && !temp.isEmpty()) 108 modifierFontName = temp; 109 } 110 111 int ss = SymbolID.getSymbolSet(symbolID); 112 113 if (attributes.containsKey(MilStdAttributes.Alpha)) 114 { 115 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 116 textColor.setAlpha(alpha); 117 } 118 if (attributes.containsKey(MilStdAttributes.TextColor)) 119 { 120 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 121 if(alpha > -1) 122 textColor.setAlpha(alpha); 123 } 124 if (attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 125 { 126 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 127 if(alpha > -1) 128 textBackgroundColor.setAlpha(alpha); 129 } 130 if (attributes.containsKey(MilStdAttributes.LineColor)) 131 { 132 lineColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.LineColor)); 133 } 134 if (attributes.containsKey(MilStdAttributes.FillColor)) 135 { 136 fillColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.FillColor)); 137 } 138 if(attributes.containsKey(MilStdAttributes.PixelSize)) 139 { 140 pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize)); 141 } 142 143 //float fontsize = RendererSettings.getInstance().getModiferFont().getTextSize(); 144 145 // <editor-fold defaultstate="collapsed" desc="Build Mobility Modifiers"> 146 float strokeWidthBasedOnDPI = 1;//min//Math.max(RendererSettings.getInstance().getDeviceDPI()/210,1);//min DPI 147 strokeWidthBasedOnDPI = Math.max(pixelSize / 25f,strokeWidthBasedOnDPI);//dpi base on symbol size 148 strokeWidthBasedOnDPI = Math.min(strokeWidthBasedOnDPI,RendererSettings.getInstance().getDeviceDPI()/32f);//max dpi 149 150 RectF mobilityBounds = null; 151 int ad = SymbolID.getAmplifierDescriptor(symbolID);//echelon/mobility 152 List<Path> shapes = new ArrayList<Path>(); 153 Path mobilityPath = null; 154 Path mobilityPathFill = null; 155 if (ad >= SymbolID.Mobility_WheeledLimitedCrossCountry && 156 (SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.R_MOBILITY_INDICATOR) || 157 SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AG_AUX_EQUIP_INDICATOR))) 158 { 159 160 //Draw Mobility 161 int fifth = (int) ((symbolBounds.width() * 0.2) + 0.5f); 162 mobilityPath = new Path(); 163 svgMobilityPath = null; 164 svgMobilityGroup = null; 165 166 int x = 0; 167 int y = 0; 168 int centerX = 0; 169 int bottomY = 0; 170 int height = 0; 171 int width = 0; 172 int middleY = 0; 173 int wheelOffset = 2; 174 int wheelSize = fifth;//10; 175 int rrHeight = fifth;//10; 176 int rrArcWidth = (int) ((fifth * 1.5) + 0.5f);//16; 177 float rad = wheelSize/2; 178 179 180 x = (int) symbolBounds.left + 1; 181 y = (int) symbolBounds.top; 182 height = Math.round(symbolBounds.height()); 183 width = Math.round(symbolBounds.width()) - 3; 184 bottomY = y + height + 2; 185 186 187 188 if (ad >= SymbolID.Mobility_WheeledLimitedCrossCountry && //31, mobility starts above 30 189 SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.R_MOBILITY_INDICATOR)) 190 { 191 bottomY = y + height + 2; 192 193 //wheelSize = width / 7; 194 //rrHeight = width / 7; 195 //rrArcWidth = width / 7; 196 if (ad == SymbolID.Mobility_WheeledLimitedCrossCountry) 197 { 198 //line 199 PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY); 200 201 //left circle 202 PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 203 204 //right circle 205 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 206 207 //SVG 208 svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n"; 209 svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" ></circle>\n"; 210 svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" ></circle>\n"; 211 } 212 else if (ad == SymbolID.Mobility_WheeledCrossCountry) 213 { 214 //line 215 PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY); 216 217 //left circle 218 PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 219 220 //right circle 221 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 222 223 //center wheel 224 PathUtilities.addEllipse(mobilityPath, x + (width / 2) - (wheelSize / 2), bottomY + wheelOffset, wheelSize, wheelSize); 225 226 //SVG 227 svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n"; 228 svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n"; 229 svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n"; 230 svgMobilityGroup += "<circle cx=\"" + (x + (width/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n"; 231 } 232 else if (ad == SymbolID.Mobility_Tracked) 233 { 234 //round rectangle 235 PathUtilities.addRoundedRect(mobilityPath, x, bottomY, width, rrHeight, rrHeight/2, rrHeight); 236 svgMobilityGroup = "<rect width=\"" + width + "\" height=\"" + rrHeight + "\" x=\"" + x + "\" y=\"" + bottomY + "\" rx=\"" + rrHeight/2 + "\" ry=\"" + rrHeight + "\" />\n"; 237 238 } 239 else if (ad == SymbolID.Mobility_Wheeled_Tracked) 240 { 241 //round rectangle 242 PathUtilities.addRoundedRect(mobilityPath, x, bottomY, width, rrHeight, wheelSize/2, rrHeight); 243 svgMobilityGroup = "<rect width=\"" + width + "\" height=\"" + rrHeight + "\" x=\"" + x + "\" y=\"" + bottomY + "\" rx=\"" + rrHeight/2 + "\" ry=\"" + rrHeight + "\" />\n"; 244 245 //left circle 246 PathUtilities.addEllipse(mobilityPath, x - wheelSize - wheelSize, bottomY, wheelSize, wheelSize); 247 svgMobilityGroup += "<circle cx=\"" + (x - wheelSize - wheelSize/2) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n"; 248 } 249 else if (ad == SymbolID.Mobility_Towed) 250 { 251 //line 252 PathUtilities.addLine(mobilityPath, x + wheelSize, bottomY + (wheelSize / 2), 253 x + width - wheelSize, bottomY + (wheelSize / 2)); 254 255 //left circle 256 PathUtilities.addEllipse(mobilityPath, x, bottomY, wheelSize, wheelSize); 257 258 //right circle 259 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY, wheelSize, wheelSize); 260 261 //SVG 262 svgMobilityGroup = "<line x1=\"" + (x + wheelSize) + "\" y1=\"" + (bottomY + (wheelSize/2) + "\" x2=\"" + (x + width - wheelSize) + "\" y2=\"" + (bottomY + (wheelSize/2))) + "\" />\n"; 263 svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" fill=\"none\" stroke=\"black\" ></circle>\n"; 264 svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" fill=\"none\" stroke=\"black\" ></circle>\n"; 265 } 266 else if (ad == SymbolID.Mobility_Rail) 267 { 268 //line 269 PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY); 270 271 //left circle 272 PathUtilities.addEllipse(mobilityPath, x + wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 273 274 //left circle2 275 PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 276 277 //right circle 278 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 279 280 //right circle2 281 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 282 283 //SVG 284 svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n"; 285 286 svgMobilityGroup += "<circle cx=\"" + (x + rad) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n"; 287 svgMobilityGroup += "<circle cx=\"" + (x + rad + wheelSize) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n"; 288 289 svgMobilityGroup += "<circle cx=\"" + (x + width - rad) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n"; 290 svgMobilityGroup += "<circle cx=\"" + (x + width - rad - wheelSize) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n"; 291 292 } 293 else if (ad == SymbolID.Mobility_OverSnow) 294 { 295 float halfWidth = (rrArcWidth * 0.5f); 296 mobilityPath.moveTo(x, bottomY); 297 mobilityPath.lineTo(x + halfWidth, bottomY + halfWidth); 298 mobilityPath.lineTo(x + width, bottomY + halfWidth); 299 300 //SVG 301 svgMobilityPath = new SVGPath(); 302 svgMobilityPath.moveTo(x,bottomY); 303 svgMobilityPath.lineTo(x + halfWidth, bottomY + halfWidth); 304 svgMobilityPath.lineTo(x + width, bottomY + halfWidth); 305 306 } 307 else if (ad == SymbolID.Mobility_Sled) 308 { 309 mobilityPath.moveTo(x, bottomY); 310 311 mobilityPath.cubicTo(x, bottomY, x - rrHeight, bottomY + rrHeight/2, x, bottomY + rrHeight); 312 //mobilityPath.bezierCurveTo(x, bottomY, x-rrArcWidth, bottomY+3, x, bottomY+rrHeight); 313 314 mobilityPath.lineTo(x + width, bottomY + rrHeight); 315 316 mobilityPath.cubicTo(x + width, bottomY + rrHeight, x + width + rrHeight, bottomY + rrHeight/2, x + width, bottomY); 317 //shapeMobility.curveTo(x + width, bottomY + rrHeight, x+ width + rrArcWidth, bottomY+3, x + width, bottomY); 318 319 //SVG 320 svgMobilityPath = new SVGPath(); 321 svgMobilityPath.moveTo(x, bottomY); 322 svgMobilityPath.bezierCurveTo(x, bottomY, x - rrHeight, bottomY + rrHeight/2, x, bottomY + rrHeight); 323 svgMobilityPath.lineTo(x + width, bottomY + rrHeight); 324 svgMobilityPath.bezierCurveTo(x + width, bottomY + rrHeight, x + width + rrHeight, bottomY + rrHeight/2, x + width, bottomY); 325 326 } 327 else if (ad == SymbolID.Mobility_PackAnimals) 328 { 329 centerX = Math.round(RectUtilities.getCenterX(symbolBounds)); 330 int angleWidth = rrHeight / 2; 331 mobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 332 mobilityPath.lineTo(centerX - angleWidth, bottomY); 333 mobilityPath.lineTo(centerX - angleWidth*2, bottomY + rrHeight + 2); 334 335 mobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 336 mobilityPath.lineTo(centerX + angleWidth, bottomY); 337 mobilityPath.lineTo(centerX + angleWidth*2, bottomY + rrHeight + 2); 338 339 //SVG 340 svgMobilityPath = new SVGPath(); 341 svgMobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 342 svgMobilityPath.lineTo(centerX - angleWidth, bottomY); 343 svgMobilityPath.lineTo(centerX - angleWidth*2, bottomY + rrHeight + 2); 344 345 svgMobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 346 svgMobilityPath.lineTo(centerX + angleWidth, bottomY); 347 svgMobilityPath.lineTo(centerX + angleWidth*2, bottomY + rrHeight + 2); 348 } 349 else if (ad == SymbolID.Mobility_Barge) 350 { 351 centerX = Math.round(RectUtilities.getCenterX(symbolBounds)); 352 PathUtilities.addLine(mobilityPath, x + width, bottomY, x, bottomY); 353 //var line = new SO.Line(x + width, bottomY,x, bottomY); 354 355 float quarterX = (centerX - x) / 2; 356 //var quarterY = (((bottomY + rrHeight) - bottomY)/2); 357 358 mobilityPath.moveTo(x, bottomY); 359 mobilityPath.cubicTo(x + quarterX, bottomY + rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY); 360 //shapes.push(new SO.BCurve(x, bottomY,x+quarterX, bottomY+rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY)); 361 362 //SVG 363 svgMobilityPath = new SVGPath(); 364 svgMobilityPath.moveTo(x + width, bottomY); 365 svgMobilityPath.lineTo(x, bottomY); 366 svgMobilityPath.moveTo(x, bottomY); 367 svgMobilityPath.bezierCurveTo(x + quarterX, bottomY + rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY); 368 } 369 370 else if (ad == SymbolID.Mobility_Amphibious) 371 { 372 float incrementX = width / 7; 373 middleY = (bottomY + (rrHeight / 2)); 374 375 x = Math.round(x + (incrementX / 2)); 376 float r = Math.round(incrementX / 2); 377 378 //mobilityPath.arcTo(oval, sAngle, sAngle, moveTo); 379 PathUtilities.arc(mobilityPath, x, middleY, r, 180, 180); 380 PathUtilities.arc(mobilityPath, x + incrementX, middleY, r, 180, -180, false); 381 PathUtilities.arc(mobilityPath, x + incrementX * 2, middleY, r, 180, 180, false); 382 PathUtilities.arc(mobilityPath, x + incrementX * 3, middleY, r, 180, -180, false); 383 PathUtilities.arc(mobilityPath, x + incrementX * 4, middleY, r, 180, 180, false); 384 PathUtilities.arc(mobilityPath, x + incrementX * 5, middleY, r, 180, -180, false); 385 PathUtilities.arc(mobilityPath, x + incrementX * 6, middleY, r, 180, 180, false); 386 387 //SVG 388 x = symbolBounds.left + 1; 389 svgMobilityGroup = "<path d=\"M" + x + " " + middleY + " "; 390 svgMobilityGroup += "C " + x + " " + bottomY + " " + (x + incrementX) + " " + bottomY + " " + (x + incrementX) + " " + middleY + " "; 391 svgMobilityGroup += "C " + (x + incrementX) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 2)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*2)) + " " + middleY + " "; 392 svgMobilityGroup += "C " + (x + (incrementX*2)) + " " + bottomY + " " + (x + (incrementX*3)) + " " + bottomY + " " + (x + incrementX*3) + " " + middleY + " "; 393 svgMobilityGroup += "C " + (x + (incrementX*3)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 4)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*4)) + " " + middleY + " "; 394 svgMobilityGroup += "C " + (x + (incrementX*4)) + " " + bottomY + " " + (x + (incrementX*5)) + " " + bottomY + " " + (x + incrementX*5) + " " + middleY + " "; 395 svgMobilityGroup += "C " + (x + (incrementX*5)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 6)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*6)) + " " + middleY + " "; 396 svgMobilityGroup += "C " + (x + (incrementX*6)) + " " + bottomY + " " + (x + (incrementX*7)) + " " + bottomY + " " + (x + incrementX*7) + " " + middleY + " "; 397 svgMobilityGroup += "\"/>"; 398 399 400 } 401 402 if(svgMobilityGroup != null) 403 svgMobilityGroup = "<g stroke-width=\"" + strokeWidthBasedOnDPI + "\" fill=\"none\"" + " stroke=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" + ">\n" + svgMobilityGroup + "</g>\n"; 404 405 } 406 //Draw Towed Array Sonar 407 if ((ad == SymbolID.Mobility_ShortTowedArray || ad == SymbolID.Mobility_LongTowedArray) && 408 SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AG_AUX_EQUIP_INDICATOR)) { 409 int boxHeight = (int) ((rrHeight * 0.8f) + 0.5f); 410 bottomY = y + height + (boxHeight / 7); 411 mobilityPathFill = new Path(); 412 offsetY = boxHeight / 7;//1; 413 centerX = Math.round(symbolBounds.left + (symbolBounds.right - symbolBounds.left) / 2); 414 int squareOffset = Math.round(boxHeight * 0.5f); 415 middleY = ((boxHeight / 2) + bottomY) + offsetY;//+1 for offset from symbol 416 if (ad == SymbolID.Mobility_ShortTowedArray) { 417 //subtract 0.5 because lines 1 pixel thick get aliased into 418 //a line two pixels wide. 419 //line 420 PathUtilities.addLine(mobilityPath, centerX - 1, bottomY - 1, centerX - 1, bottomY + offsetY + boxHeight + offsetY); 421 //shapes.push(new SO.Line(centerX-1,bottomY-1,centerX-1, bottomY + rrHeight + 3)); 422 //shapeLines.append(new Line2D.Double(centerX,bottomY - 2,centerX, bottomY + rrHeight + 1), false); 423 //line 424 PathUtilities.addLine(mobilityPath, x, middleY, x + width, middleY); 425 //shapes.push(new SO.Line(x,middleY,x + width, middleY)); 426 //shapeLines.append(new Line2D.Double(x,middleY,x + width, middleY), false); 427 //square 428 mobilityPathFill.addRect(PathUtilities.makeRectF(x - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 429 //shapes.push(new SO.Rectangle(x-squareOffset, bottomY+offsetY, 5, 5)); 430 //shapeSquares.append(new Rectangle2D.Double(x-squareOffset, bottomY, 5, 5), false); 431 //square 432 mobilityPathFill.addRect(PathUtilities.makeRectF(Math.round(centerX - squareOffset), bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 433 //shapes.push(new SO.Rectangle(Math.round(centerX-squareOffset), bottomY+offsetY, 5, 5)); 434 //shapeSquares.append(new Rectangle2D.Double(centerX-squareOffset, bottomY, 5, 5), false); 435 //square 436 mobilityPathFill.addRect(PathUtilities.makeRectF(x + width - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 437 //shapes.push(new SO.Rectangle(x + width - squareOffset, bottomY+offsetY, 5, 5)); 438 //shapeSquares.append(new Rectangle2D.Double(x + width - squareOffset, bottomY, 5, 5), false); 439 440 //SVG 441 String svgColor = RendererUtilities.colorToHexString(lineColor,false); 442 svgMobilityGroup = "<line x1=\"" + (centerX - 1) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (centerX - 1) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 443 svgMobilityGroup += "<line x1=\"" + (x) + "\" y1=\"" + (middleY) + "\" x2=\"" + (x + width) + "\" y2=\"" + (middleY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 444 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 445 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (centerX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 446 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x + width - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 447 448 449 } else if (ad == SymbolID.Mobility_LongTowedArray) { 450 int leftX = x + (centerX - x) / 2, 451 rightX = centerX + (x + width - centerX) / 2; 452 453 //line vertical left 454 PathUtilities.addLine(mobilityPath, leftX, bottomY - 1, leftX, bottomY + offsetY + boxHeight + offsetY); 455 //shapes.push(new SO.Line(leftX,bottomY - 1,leftX, bottomY + rrHeight + 3)); 456 //shapeLines.append(new Line2D.Double(leftX,bottomY - 2,leftX, bottomY + rrHeight + 1), false); 457 //line vertical right 458 PathUtilities.addLine(mobilityPath, rightX, bottomY - 1, rightX, bottomY + offsetY + boxHeight + offsetY); 459 //shapes.push(new SO.Line(rightX,bottomY - 1,rightX, bottomY + rrHeight + 3)); 460 //shapeLines.append(new Line2D.Double(rightX,bottomY - 2,rightX, bottomY + rrHeight + 1), false); 461 //line horizontal 462 PathUtilities.addLine(mobilityPath, x, middleY, x + width, middleY); 463 //shapes.push(new SO.Line(x,middleY,x + width, middleY)); 464 //shapeLines.append(new Line2D.Double(x,middleY,x + width, middleY), false); 465 //square left 466 mobilityPathFill.addRect(PathUtilities.makeRectF(x - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 467 //shapes.push(new SO.Rectangle(x-squareOffset, bottomY+offsetY, 5, 5)); 468 //shapeSquares.append(new Rectangle2D.Double(x-squareOffset, bottomY, 5, 5), false); 469 //square middle 470 mobilityPathFill.addRect(PathUtilities.makeRectF(centerX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 471 //shapes.push(new SO.Rectangle(centerX-squareOffset, bottomY+offsetY, 5, 5)); 472 //shapeSquares.append(new Rectangle2D.Double(centerX-squareOffset, bottomY, 5, 5), false); 473 //square right 474 mobilityPathFill.addRect(PathUtilities.makeRectF(x + width - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 475 //shapes.push(new SO.Rectangle(x + width - squareOffset, bottomY+offsetY, 5, 5)); 476 //shapeSquares.append(new Rectangle2D.Double(x + width - squareOffset, bottomY, 5, 5), false); 477 //square middle left 478 mobilityPathFill.addRect(PathUtilities.makeRectF(leftX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 479 //shapes.push(new SO.Rectangle(leftX - squareOffset, bottomY+offsetY, 5, 5)); 480 //shapeSquares.append(new Rectangle2D.Double(leftX - squareOffset, bottomY, 5, 5), false); 481 //square middle right 482 mobilityPathFill.addRect(PathUtilities.makeRectF(rightX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 483 //shapes.push(new SO.Rectangle(rightX - squareOffset, bottomY+offsetY, 5, 5)); 484 //shapeSquares.append(new Rectangle2D.Double(rightX - squareOffset, bottomY, 5, 5), false); 485 486 //SVG 487 String svgColor = RendererUtilities.colorToHexString(lineColor,false); 488 svgMobilityGroup = "<line x1=\"" + (leftX) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (leftX) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 489 svgMobilityGroup += "<line x1=\"" + (rightX) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (rightX) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 490 svgMobilityGroup += "<line x1=\"" + (x) + "\" y1=\"" + (middleY) + "\" x2=\"" + (x + width) + "\" y2=\"" + (middleY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 491 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 492 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (centerX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 493 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x + width - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 494 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (leftX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 495 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (rightX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 496 497 } 498 if(svgMobilityGroup != null) 499 svgMobilityGroup = "<g stroke-width=\"" + strokeWidthBasedOnDPI + "\" fill=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" + " stroke=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" + ">\n" + svgMobilityGroup + "\n</g>"; 500 } 501 502 //get mobility bounds 503 if (mobilityPath != null) 504 { 505 506 //build mobility bounds 507 mobilityBounds = new RectF(); 508 mobilityPath.computeBounds(mobilityBounds, true); 509 510 RectF mobilityFillBounds = new RectF(); 511 if (mobilityPathFill != null) 512 { 513 mobilityPathFill.computeBounds(mobilityFillBounds, true); 514 mobilityBounds.union(mobilityFillBounds); 515 } 516 517 //grow by one because we use a line thickness of 2. 518 RectUtilities.grow(mobilityBounds,Math.round(strokeWidthBasedOnDPI/2)); 519 //mobilityBounds.set(mobilityBounds.left - 1, mobilityBounds.top - 1, mobilityBounds.right + 1, mobilityBounds.bottom + 1); 520 imageBounds.union(RectUtilities.makeRectFromRectF(mobilityBounds)); 521 } 522 } 523 // </editor-fold> 524 525 // <editor-fold defaultstate="collapsed" desc="Leadership Indicator Modifier"> 526 RectF liBounds = null; 527 Path liPath = null; 528 PointF liTop = null; 529 PointF liLeft = null; 530 PointF liRight = null; 531 if(ad == SymbolID.Leadership_Individual && ss == SymbolID.SymbolSet_DismountedIndividuals && 532 (SymbolID.getFrameShape(symbolID)==SymbolID.FrameShape_DismountedIndividuals || 533 SymbolID.getFrameShape(symbolID)==SymbolID.FrameShape_Unknown)) 534 { 535 liPath = new Path(); 536 537 int si = SymbolID.getStandardIdentity(symbolID); 538 int af = SymbolID.getAffiliation(symbolID); 539 int c = SymbolID.getContext(symbolID); 540 //int fs = SymbolID.getFrameShape(symbolID); 541 double centerOffset = 0; 542 double sideOffset = 0; 543 double left = symbolBounds.left; 544 double right = symbolBounds.left + symbolBounds.width(); 545 546 if(af == SymbolID.StandardIdentity_Affiliation_Unknown || af == SymbolID.StandardIdentity_Affiliation_Pending) 547 { 548 centerOffset = (symbolBounds.height()*0.1012528735632184); 549 sideOffset = (right - left)*0.3583513488109785; 550 //left = symbolBounds.getCenterX() - ((symbolBounds.getWidth() / 2) * 0.66420458); 551 //right = symbolBounds.getCenterX() + ((symbolBounds.getWidth() / 2) * 0.66420458); 552 } 553 if(af == SymbolID.StandardIdentity_Affiliation_Neutral) 554 { 555 centerOffset = (symbolBounds.height()*0.25378787878787878); 556 sideOffset = (right - left)*0.2051402812352822; 557 } 558 if(SymbolUtilities.isReality(symbolID) || SymbolUtilities.isSimulation(symbolID)) 559 { 560 if(af==SymbolID.StandardIdentity_Affiliation_Friend || af==SymbolID.StandardIdentity_Affiliation_AssumedFriend) 561 {//hexagon friend/assumed friend 562 centerOffset = (symbolBounds.height()*0.08); 563 sideOffset = (right - left)*0.282714524168219;//(symbolBounds.getHeight()*0.29); 564 } 565 else if(af==SymbolID.StandardIdentity_Affiliation_Hostile_Faker || af==SymbolID.StandardIdentity_Affiliation_Suspect_Joker) 566 {//diamond hostile/suspect 567 568 left = symbolBounds.centerX() - ((symbolBounds.width() / 2) * 1.0653694149);//1.07);//1.0653694149); 569 right = symbolBounds.centerX() + ((symbolBounds.width() / 2) * 1.0653694149);//1.07);//1.0653694149); 570 571 centerOffset = (symbolBounds.height()*0.08);//0.0751139601139601 572 sideOffset = (right - left)*0.4923255424955992; 573 } 574 } 575 else//Exercise 576 { 577 //hexagon 578 if(af!=SymbolID.StandardIdentity_Affiliation_Unknown || 579 af==SymbolID.StandardIdentity_Affiliation_Neutral) 580 { 581 centerOffset = (symbolBounds.height()*0.08); 582 sideOffset = (right - left)*0.282714524168219; 583 } 584 } 585 586 //create leadership indicator /\ 587 liTop = new PointF(symbolBounds.centerX(), (float)(symbolBounds.top - centerOffset)); 588 liLeft = new PointF((float)left, (float)(liTop.y + sideOffset)); 589 liRight = new PointF((float)right, (float)(liTop.y + sideOffset)); 590 591 592 liPath.moveTo(liTop.x, liTop.y); 593 liPath.lineTo(liLeft.x, liLeft.y); 594 liPath.moveTo(liTop.x, liTop.y); 595 liPath.lineTo(liRight.x, liRight.y);//*/ 596 597 598 liBounds = new RectF(liLeft.x, liTop.y, liRight.x - liLeft.x, liLeft.y - liTop.y); 599 600 RectUtilities.grow(liBounds,2); 601 602 imageBounds.union(RectUtilities.makeRectFromRectF(liBounds)); 603 } 604 605 // </editor-fold> 606 607 // <editor-fold defaultstate="collapsed" desc="Build Echelon"> 608 //Draw Echelon 609 int intEchelon = SymbolID.getAmplifierDescriptor(symbolID); 610 String strEchelon = SymbolUtilities.getEchelonText(intEchelon); 611 612 if (strEchelon != null 613 && SymbolUtilities.hasModifier(symbolID, Modifiers.B_ECHELON)) 614 { 615 616 int echelonOffset = 2, 617 outlineOffset = RS.getTextOutlineWidth(); 618 619 tiEchelon = new TextInfo(strEchelon, 0, 0, modifierFont, modifierFontName); 620 echelonBounds = tiEchelon.getTextBounds(); 621 622 int y = Math.round(symbolBounds.left - echelonOffset); 623 int x = Math.round(symbolBounds.left + (symbolBounds.width() / 2) 624 - (echelonBounds.width() / 2)); 625 tiEchelon.setLocation(x, y); 626 627 //There will never be lowercase characters in an echelon so trim that fat. 628 //Remove the descent from the bounding box. 629 tiEchelon.getTextOutlineBounds();//.shiftBR(0,Math.round(-(echelonBounds.height()*0.3))); 630 631 //make echelon bounds a little more spacious for things like nearby labels and Task Force. 632 RectUtilities.grow(echelonBounds, outlineOffset); 633 //tiEchelon.getTextOutlineBounds(); 634// RectUtilities.shift(echelonBounds, x, -outlineOffset); 635 //echelonBounds.shift(0,-outlineOffset);// - Math.round(echelonOffset/2)); 636 tiEchelon.setLocation(x, y - outlineOffset); 637 638 imageBounds.union(echelonBounds); 639 640 } 641 // </editor-fold> 642 643 // <editor-fold defaultstate="collapsed" desc="Build Task Force"> 644 Rect tfBounds = null; 645 Rect tfRectangle = null; 646 if (SymbolUtilities.isTaskForce(symbolID) && SymbolUtilities.hasModifier(symbolID, Modifiers.D_TASK_FORCE_INDICATOR)) 647 { 648 649 int height = Math.round(symbolBounds.height() / 4.0f); 650 int width = Math.round(symbolBounds.width() / 3.0f); 651 652 if(!SymbolUtilities.hasRectangleFrame(symbolID)) 653 { 654 height = (int)Math.round(symbolBounds.height() / 6.0f); 655 } 656 657 tfRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 658 (int) symbolBounds.top - height, 659 width, 660 height); 661 662 tfBounds = RectUtilities.makeRect(tfRectangle.left + -1, 663 tfRectangle.top - 1, 664 tfRectangle.width() + 2, 665 tfRectangle.height() + 2); 666 667 if (echelonBounds != null) 668 { 669 /*tfRectangle = new Rect(echelonBounds.left, 670 echelonBounds.top,// + outlineOffset, 671 echelonBounds.right, 672 symbolBounds.top-1); 673 tfBounds = new Rect(tfRectangle);*/ 674 675 int tfx = tfRectangle.left; 676 int tfw = tfRectangle.width(); 677 int tfy = tfRectangle.top; 678 int tfh = tfRectangle.height(); 679 680 if(echelonBounds.width() > tfRectangle.width()) 681 { 682 tfx = symbolBounds.left + symbolBounds.width()/2 - (echelonBounds.width()/2) - 1; 683 tfw = echelonBounds.width()+2; 684 } 685 if(echelonBounds.height() > tfRectangle.height()) 686 { 687 tfy = echelonBounds.top-1; 688 tfh = echelonBounds.height()+2; 689 690 } 691 tfRectangle = RectUtilities.makeRect((int)tfx, 692 tfy,// + outlineOffset, 693 tfw, 694 tfh); 695 696 697 tfBounds = RectUtilities.makeRect((tfRectangle.left - 1), 698 (tfRectangle.top - 1), 699 (tfRectangle.width() + 2), 700 (tfRectangle.height() + 2)); 701 } 702 703 imageBounds.union(tfBounds); 704 } 705 // </editor-fold> 706 707 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 708 Rect fdiBounds = null; 709 Point fdiTop = null; 710 Point fdiLeft = null; 711 Point fdiRight = null; 712 713 714 if (SymbolUtilities.hasFDI(symbolID) 715 && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AB_FEINT_DUMMY_INDICATOR)) 716 { 717 //create feint indicator /\ 718 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 719 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 720 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f))); 721 722 723 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 724 fdiBounds.union(fdiTop.x, fdiTop.y); 725 fdiBounds.union(fdiRight.x, fdiRight.y); 726 727 float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 728 RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2)); 729 730 if (echelonBounds != null) 731 { 732 int shiftY = Math.round(symbolBounds.top - echelonBounds.height() - 2); 733 fdiLeft.offset(0, shiftY); 734 fdiTop.offset(0, shiftY); 735 fdiRight.offset(0, shiftY); 736 fdiBounds.offset(0, shiftY); 737 } 738 739 imageBounds.union(fdiBounds); 740 741 } 742 // </editor-fold> 743 744 //Using SVG files for installation indicator now 745 // <editor-fold defaultstate="collapsed" desc="Build Installation"> 746 /*//Using SVG files for the installation indicator 747 Rect instRectangle = null; 748 Rect instBounds = null; 749 if (SymbolUtilities.hasInstallationModifier(symbolID) 750 && SymbolUtilitiesD.canSymbolHaveModifier(symbolID, Modifiers.AC_INSTALLATION)) 751 {//the actual installation symbols have the modifier 752 //built in. everything else, we have to draw it. 753 // 754 ////get indicator dimensions//////////////////////////////// 755 int width; 756 int height; 757 char affiliation = SymbolUtilities.getAffiliation(symbolID); 758 759 if (affiliation == 'F' 760 || affiliation == 'A' 761 || affiliation == 'D' 762 || affiliation == 'M' 763 || affiliation == 'J' 764 || affiliation == 'K') 765 { 766 //4th height, 3rd width 767 height = Math.round(symbolBounds.height() / 4); 768 width = Math.round(symbolBounds.width() / 3); 769 } 770 else if (affiliation == 'H' || affiliation == 'S')//hostile,suspect 771 { 772 //6th height, 3rd width 773 height = Math.round(symbolBounds.height() / 6); 774 width = Math.round(symbolBounds.width() / 3); 775 } 776 else if (affiliation == 'N' || affiliation == 'L')//neutral,exercise neutral 777 { 778 //6th height, 3rd width 779 height = Math.round(symbolBounds.height() / 6); 780 width = Math.round(symbolBounds.width() / 3); 781 } 782 else if (affiliation == 'P' 783 || affiliation == 'U' 784 || affiliation == 'G' 785 || affiliation == 'W') 786 { 787 //6th height, 3rd width 788 height = Math.round(symbolBounds.height() / 6); 789 width = Math.round(symbolBounds.width() / 3); 790 } 791 else 792 { 793 //6th height, 3rd width 794 height = Math.round(symbolBounds.height() / 6); 795 width = Math.round(symbolBounds.width() / 3); 796 } 797 798// if(width * 3 < symbolBounds.width()) 799// width++; 800 //set installation position///////////////////////////////// 801 //set position of indicator 802 if (affiliation == 'F' 803 || affiliation == 'A' 804 || affiliation == 'D' 805 || affiliation == 'M' 806 || affiliation == 'J' 807 || affiliation == 'K' 808 || affiliation == 'N' 809 || affiliation == 'L') 810 { 811 instRectangle = RectUtilities.makeRect((int) (symbolBounds.left + width), 812 (int) (symbolBounds.top - height), 813 width, 814 height); 815 } 816 else if (affiliation == 'H' || affiliation == 'S')//hostile,suspect 817 { 818 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 819 Math.round((int) symbolBounds.top - (height * 0.15f)), 820 width, 821 height); 822 } 823 else if (affiliation == 'P' 824 || affiliation == 'U' 825 || affiliation == 'G' 826 || affiliation == 'W') 827 { 828 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 829 Math.round(symbolBounds.top - (height * 0.3f)), 830 width, 831 height); 832 } 833 else 834 { 835 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 836 Math.round(symbolBounds.top - (height * 0.3f)), 837 width, 838 height); 839 } 840 841 //generate installation bounds////////////////////////////// 842 instBounds = new Rect(instRectangle.left + -1, 843 instRectangle.top - 1, 844 instRectangle.width() + 2, 845 instRectangle.height() + 2); 846 847 imageBounds.union(instBounds); 848 849 }//*/ 850 // </editor-fold> 851 852 // <editor-fold defaultstate="collapsed" desc="Build Engagement Bar (AO)"> 853 //A:BBB-CC 854 String strAO = null; 855 Rect ebRectangle = null; 856 Rect ebBounds = null; 857 Rect ebTextBounds = null; 858 TextInfo ebText = null; 859 860 int ebTop = 0; 861 int ebLeft = 0; 862 int ebWidth = 0; 863 int ebHeight = 0; 864 Color ebColor = null;//SymbolUtilities.getFillColorOfAffiliation(symbolID); 865 866 if(attributes.containsKey(MilStdAttributes.EngagementBarColor)) 867 ebColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.EngagementBarColor)); 868 else 869 ebColor = fillColor; 870 871 if(SymbolUtilities.hasModifier(symbolID, Modifiers.AO_ENGAGEMENT_BAR) && 872 modifiers.containsKey(Modifiers.AO_ENGAGEMENT_BAR)) 873 strAO = modifiers.get(Modifiers.AO_ENGAGEMENT_BAR); 874 if(strAO != null) 875 { 876 ebText = new TextInfo(strAO, 0, 0, modifierFont, modifierFontName); 877 ebTextBounds = ebText.getTextBounds(); 878 ebHeight = ebTextBounds.height() + 4; 879 880 int barOffset = Math.max(RendererSettings.getInstance().getDeviceDPI()/32, 4); 881 882 if(fdiBounds != null)//set bar above FDI if present 883 { 884 ebTop = fdiBounds.top - ebHeight - barOffset; 885 } 886 else if(tfBounds != null)//set bar above TF if present 887 { 888 ebTop = tfBounds.top - ebHeight - barOffset; 889 } 890 else if(echelonBounds != null)//set bar above echelon if present 891 { 892 ebTop = echelonBounds.top - ebHeight - barOffset; 893 } 894 else if((isCOnTop(symbolID) && modifiers.containsKey(Modifiers.C_QUANTITY)) || 895 SymbolID.getContext(symbolID) == SymbolID.StandardIdentity_Context_Exercise || 896 SymbolID.getContext(symbolID) == SymbolID.StandardIdentity_Context_Simulation) 897 { 898 ebTop = symbolBounds.top - (int)(ebHeight*2.5f); 899 } 900 else if(ss == SymbolID.SymbolSet_LandInstallation) 901 { 902 ebTop = symbolBounds.top - ebHeight - (barOffset * 2); 903 } 904 else//position above symbol 905 { 906 ebTop = symbolBounds.top - ebHeight - barOffset; 907 } 908 909 //if text wider than symbol, extend the bar. 910 if(ebTextBounds.width() > symbolBounds.width()) 911 { 912 ebWidth = ebTextBounds.width() + 4; 913 ebLeft = symbolCenter.x - (ebWidth/2); 914 } 915 else 916 { 917 ebLeft = symbolBounds.left + (int)Math.ceil(strokeWidthBasedOnDPI/2f);//1;//leave room for outline 918 ebWidth = symbolBounds.width() - (int)Math.ceil(strokeWidthBasedOnDPI);//2;//leave room for outline 919 } 920 921 //set text location within the bar 922 ebText.setLocation(symbolCenter.x - (ebTextBounds.width()/2), ebTop + ebHeight - ((ebHeight - ebTextBounds.height()) / 2)); 923 924 ebRectangle = RectUtilities.makeRect(ebLeft,ebTop,ebWidth,ebHeight); 925 ebBounds = new Rect(ebRectangle); 926 RectUtilities.grow(ebBounds,(int)Math.ceil(strokeWidthBasedOnDPI/2f)); 927 928 imageBounds.union(ebBounds); 929 } 930 931 932 // </editor-fold> 933 934 // <editor-fold defaultstate="collapsed" desc="Build Affiliation Modifier"> 935 String affiliationModifier = null; 936 if (RS.getDrawAffiliationModifierAsLabel() == false) 937 { 938 affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID); 939 } 940 if (affiliationModifier != null) 941 { 942 943 int amOffset = 2; 944 int outlineOffset = RS.getTextOutlineWidth(); 945 946 tiAM = new TextInfo(affiliationModifier, 0, 0, modifierFont, modifierFontName); 947 amBounds = tiAM.getTextBounds(); 948 949 int x, y; 950 951 if (echelonBounds != null 952 && ((echelonBounds.left + echelonBounds.width() > symbolBounds.left + symbolBounds.width()))) 953 { 954 y = Math.round(symbolBounds.top - amOffset); 955 x = echelonBounds.left + echelonBounds.width(); 956 } 957 else 958 { 959 y = Math.round(symbolBounds.top - amOffset); 960 x = Math.round(symbolBounds.left + symbolBounds.width()); 961 } 962 tiAM.setLocation(x, y); 963 964 //adjust for outline. 965 RectUtilities.grow(amBounds, outlineOffset); 966 RectUtilities.shift(amBounds, 0, -outlineOffset); 967 tiAM.setLocation(x, y - outlineOffset); 968 969 imageBounds.union(amBounds); 970 } 971 // </editor-fold> 972 973 // <editor-fold defaultstate="collapsed" desc="Build HQ Staff"> 974 Point pt1HQ = null; 975 Point pt2HQ = null; 976 Rect hqBounds = null; 977 //Draw HQ Staff 978 if (SymbolUtilities.isHQ(symbolID)) 979 { 980 int affiliation = SymbolID.getAffiliation(symbolID); 981 int context = SymbolID.getContext(symbolID); 982 //get points for the HQ staff 983 if (SymbolUtilities.hasRectangleFrame(symbolID)) 984 { 985 pt1HQ = new Point((int) symbolBounds.left + 1, 986 (int) (symbolBounds.top + symbolBounds.height() - 1)); 987 } 988 else 989 { 990 pt1HQ = new Point((int) symbolBounds.left + 1, 991 (int) (symbolBounds.top + (symbolBounds.height() / 2))); 992 } 993 pt2HQ = new Point((int) pt1HQ.x, (int) (pt1HQ.y + symbolBounds.height())); 994 995 //create bounding rectangle for HQ staff. 996 hqBounds = new Rect(pt1HQ.x, pt1HQ.y, pt1HQ.x + 2, pt2HQ.y); 997 //adjust the image bounds accordingly. 998 imageBounds.union(hqBounds); 999 //imageBounds.shiftBR(0,pt2HQ.y-imageBounds.bottom); 1000 //adjust symbol center 1001 centerPoint.set(pt2HQ.x, pt2HQ.y); 1002 } 1003 1004 // </editor-fold> 1005 1006 // <editor-fold defaultstate="collapsed" desc="Build DOM Arrow"> 1007 Point[] domPoints = null; 1008 Rect domBounds = null; 1009 if (modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT) 1010 && SymbolUtilities.hasModifier(symbolID, Modifiers.Q_DIRECTION_OF_MOVEMENT)) 1011 { 1012 String strQ = modifiers.get(Modifiers.Q_DIRECTION_OF_MOVEMENT); 1013 1014 if(strQ != null && SymbolUtilities.isNumber(strQ)) 1015 { 1016 float q = Float.valueOf(strQ); 1017 1018 boolean isY = (modifiers.containsKey(Modifiers.Y_LOCATION)); 1019 1020 domPoints = createDOMArrowPoints(symbolID, symbolBounds, symbolCenter, q, isY, modifierFontHeight); 1021 1022 domBounds = new Rect(domPoints[0].x, domPoints[0].y, 1, 1); 1023 1024 Point temp = null; 1025 for (int i = 1; i < 6; i++) 1026 { 1027 temp = domPoints[i]; 1028 if (temp != null) 1029 { 1030 domBounds.union(temp.x, temp.y); 1031 } 1032 } 1033 imageBounds.union(domBounds); 1034 } 1035 } 1036 1037 // </editor-fold> 1038 1039 // <editor-fold defaultstate="collapsed" desc="Build Operational Condition Indicator"> 1040 Rect ociBounds = null; 1041 RectF ociBoundsF = null; 1042 Rect ociShape = null; 1043 Path ociSlashShape = null; 1044 int ociOffset = Math.max(RendererSettings.getInstance().getDeviceDPI()/32, 4); 1045 if (SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AL_OPERATIONAL_CONDITION)) { 1046 if (mobilityBounds != null) 1047 { 1048 ociOffset = Math.round(mobilityBounds.bottom - symbolBounds.bottom) + 4; 1049 } 1050 if(RendererSettings.getInstance().getOperationalConditionModifierType() == RendererSettings.OperationalConditionModifierType_BAR) 1051 { 1052 ociShape = processOperationalConditionIndicator(symbolID, symbolBounds, ociOffset); 1053 if (ociShape != null) 1054 { 1055 Rect temp = new Rect(ociShape); 1056 RectUtilities.grow(temp, 2); 1057 ociBounds = temp; 1058 imageBounds.union(ociBounds); 1059 } 1060 } 1061 else//slash 1062 { 1063 ociSlashShape = processOperationalConditionIndicatorSlash(symbolID, symbolBounds); 1064 if (ociSlashShape != null) 1065 { 1066 //build mobility bounds 1067 ociBoundsF = new RectF(); 1068 ociBounds = new Rect(); 1069 ociSlashShape.computeBounds(ociBoundsF, true); 1070 ociBoundsF.roundOut(ociBounds); 1071 imageBounds.union(ociBounds); 1072 ociBounds = null; 1073 } 1074 } 1075 } 1076 1077 // </editor-fold> 1078 1079 // <editor-fold defaultstate="collapsed" desc="Build Restricted Indicator"> 1080 RectF rBounds = null; 1081 Path rPath = null; 1082 Path rPath2 = null; 1083 SVGPath rsvgPath = null; 1084 SVGPath rsvgPath2 = null; 1085 PointF rcirclePt = null; 1086 PointF rdotPt = null; 1087 float rdotRadius = 0; 1088 float rStrokeWidth = 3; 1089 if(SymbolID.getContext(symbolID) == SymbolID.StandardIdentity_Context_Restricted_Target_Reality) 1090 { 1091 // <path id="primary" d="M380,320l38,-67l40,67h-78m38,-11v-1m0,-10l0,-20" fill="yellow" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="7" /> 1092 float nsTx = 0; 1093 float nsTy = 0; 1094 float ratio = 1; 1095 SVGInfo si = SVGLookup.getInstance().getSVGLInfo(SVGLookup.getFrameID(symbolID),SymbolID.getVersion(symbolID)); 1096 if(symbolBounds.height() > symbolBounds.width()) 1097 { 1098 double sHeight = si.getBbox().height(); 1099 ratio = (float)(symbolBounds.height() / sHeight); 1100 } 1101 else 1102 { 1103 double sWidth = si.getBbox().width(); 1104 ratio = (float)(symbolBounds.width() / sWidth); 1105 } 1106 1107 nsTx = (float)(si.getBbox().left * ratio) * -1; 1108 nsTy = (float)(si.getBbox().top * ratio) * -1; 1109 1110 //<path d="m373,313l53,-97l57,97l-110,0" fill="yellow" id="triangle" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="6"/> 1111 //<path d="m373,313L426,216L483,313L373,313" fill="yellow" id="triangle" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="6"/> 1112 rPath = new Path();//triangle 1113 rPath.moveTo(373f * ratio, 313f * ratio); 1114 rPath.lineTo(426f * ratio, 216f * ratio); 1115 rPath.lineTo(483f * ratio, 313f * ratio); 1116 rPath.lineTo(373f * ratio, 313f * ratio); 1117 rsvgPath = new SVGPath();//triangle 1118 rsvgPath.moveTo(373f * ratio, 313f * ratio); 1119 rsvgPath.lineTo(426f * ratio, 216f * ratio); 1120 rsvgPath.lineTo(483f * ratio, 313f * ratio); 1121 rsvgPath.lineTo(373f * ratio, 313f * ratio); 1122 1123 //<path d="M426.5,276L426.5,244" fill="none" id="line" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"/> 1124 rPath2 = new Path();//line 1125 rPath2.moveTo(426.5f * ratio, 276f * ratio); 1126 rPath2.lineTo(426.5f * ratio, 248f * ratio); 1127 rsvgPath2 = new SVGPath();//line 1128 rsvgPath2.moveTo(426.5f * ratio, 276f * ratio); 1129 rsvgPath2.lineTo(426.5f * ratio, 248f * ratio); 1130 1131 //<circle cx="426.5" cy="293" r="6" id="dot"/>//DOT 1132 rdotPt = new PointF(426.5f * ratio, 293 * ratio); 1133 rdotRadius = 5f * ratio; 1134 1135 //need to shift like we do the frame and main icons since it's based in that space 1136 rPath.offset(nsTx, nsTy); 1137 rPath2.offset(nsTx, nsTy); 1138 rsvgPath.shift(nsTx,nsTy); 1139 rsvgPath2.shift(nsTx,nsTy); 1140 rdotPt.offset(nsTx,nsTy); 1141 //rCircle = (Ellipse2D) txfm.createTransformedShape(rCircle); 1142 1143 1144 //RectF bounds = new RectF(); 1145 //bounds = rPath.computeBounds(bounds); //getBounds();//triangle bounds 1146 Rect bounds = rsvgPath.getBounds(); 1147 rBounds = RectUtilities.makeRectF(bounds.left,bounds.top,bounds.width(), bounds.height()); 1148 rStrokeWidth = (2/66.666667f) * ((float)symbolBounds.height() / SymbolUtilities.getUnitRatioHeight(symbolID)); 1149 RectUtilities.grow(rBounds,(int)Math.ceil(rStrokeWidth/2)); 1150 RectUtilities.grow(bounds,(int)Math.ceil(rStrokeWidth/2)); 1151 imageBounds.union(bounds); 1152 } 1153 // </editor-fold> 1154 1155 // <editor-fold defaultstate="collapsed" desc="Build No Strike Indicator"> 1156 RectF nsBounds = null; 1157 PointF nsCirclePt = null; 1158 float nsRadius = 0; 1159 Path nsLine = null; 1160 SVGPath nssvgLine = null; 1161 double nsStrokeWidth = 3; 1162 if(SymbolID.getContext(symbolID) == SymbolID.StandardIdentity_Context_No_Strike_Entity_Reality) 1163 { 1164 //octagon~182.08058166503906~272.0794677734375~245.8407440185547~244.85235595703125 1165 //restricted~375.44801678047673~248.63298320770264~85.1039714496415~79.36734275822477 1166 //no-strike~378.0~248.0~80.0~80.0 1167 //<circle cx="418" cy="288" fill="yellow" r="36" stroke="black" stroke-width="8"/> 1168 //<line fill="none" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" x1="390" x2="446" y1="265" y2="310"/> 1169 //nsCircle = new Ellipse(x,y,radius * 2, radius * 2); 1170 //nsLine = new Line(390 * ratio, 265 * ratio, 446 * ratio, 310 * ratio); 1171 float nsTx = 0; 1172 float nsTy = 0; 1173 float ratio = 1; 1174 SVGInfo si = SVGLookup.getInstance().getSVGLInfo(SVGLookup.getFrameID(symbolID),SymbolID.getVersion(symbolID)); 1175 if(symbolBounds.height() > symbolBounds.width()) 1176 { 1177 float sHeight = si.getBbox().height(); 1178 ratio = symbolBounds.height() / sHeight; 1179 } 1180 else 1181 { 1182 float sWidth = si.getBbox().width(); 1183 ratio = symbolBounds.width() / sWidth; 1184 } 1185 1186 nsTx = (si.getBbox().left * ratio) * -1; 1187 nsTy = (si.getBbox().top * ratio) * -1; 1188 1189 float radius = 50f * ratio; 1190 float x = 426f * ratio; 1191 float y = 267f * ratio; 1192 nsCirclePt = new PointF(x,y); 1193 nsRadius = radius; 1194 nsLine = new Path(); 1195 nsLine.moveTo(390 * ratio, 235 * ratio); 1196 nsLine.lineTo(463 * ratio, 298 * ratio); 1197 nssvgLine = new SVGPath(); 1198 nssvgLine.moveTo(390 * ratio, 235 * ratio); 1199 nssvgLine.lineTo(463 * ratio, 298 * ratio); 1200 1201 //need to shift like we do the frame and main icons since it's based in that space 1202 nsCirclePt.offset(nsTx,nsTy); 1203 nsLine.offset(nsTx,nsTy); 1204 nssvgLine.shift(nsTx,nsTy); 1205 1206 nsBounds = RectUtilities.makeRectF(nsCirclePt.x - radius, nsCirclePt.y - radius, radius * 2, radius * 2); 1207 1208 nsStrokeWidth = (2/66.666667) * (symbolBounds.height() / SymbolUtilities.getUnitRatioHeight(symbolID)); 1209 RectUtilities.grow(nsBounds,(int)Math.ceil(nsStrokeWidth/2)); 1210 imageBounds.union(RectUtilities.makeRectFromRectF(nsBounds)); 1211 } 1212 // </editor-fold> 1213 1214 // <editor-fold defaultstate="collapsed" desc="Shift Modifiers"> 1215 //adjust points if necessary 1216 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 1217 { 1218 int shiftX = Math.abs(imageBounds.left); 1219 int shiftY = Math.abs(imageBounds.top); 1220 1221 if (hqBounds != null) 1222 { 1223 pt1HQ.offset(shiftX, shiftY); 1224 pt2HQ.offset(shiftX, shiftY); 1225 } 1226 if (echelonBounds != null) 1227 { 1228 tiEchelon.setLocation(tiEchelon.getLocation().x + shiftX, tiEchelon.getLocation().y + shiftY); 1229 } 1230 if (amBounds != null) 1231 { 1232 tiAM.setLocation(tiAM.getLocation().x + shiftX, tiAM.getLocation().y + shiftY); 1233 } 1234 if (tfBounds != null) 1235 { 1236 tfRectangle.offset(shiftX, shiftY); 1237 tfBounds.offset(shiftX, shiftY); 1238 } 1239 if(ebBounds != null) 1240 { 1241 ebRectangle.offset(shiftX, shiftY); 1242 ebBounds.offset(shiftX, shiftY); 1243 ebText.shift(shiftX, shiftY); 1244 ebTextBounds.offset(shiftX, shiftY); 1245 } 1246 /*if (instBounds != null)//part of symbol bounds now 1247 { 1248 instRectangle.offset(shiftX, shiftY); 1249 instBounds.offset(shiftX, shiftY); 1250 }//*/ 1251 if (fdiBounds != null) 1252 { 1253 fdiBounds.offset(shiftX, shiftY); 1254 fdiLeft.offset(shiftX, shiftY); 1255 fdiTop.offset(shiftX, shiftY); 1256 fdiRight.offset(shiftX, shiftY); 1257 } 1258 if (liBounds != null) 1259 { 1260 liBounds.offset(shiftX, shiftY); 1261 liLeft.offset(shiftX, shiftY); 1262 liTop.offset(shiftX, shiftY); 1263 liRight.offset(shiftX, shiftY); 1264 if(liPath != null) 1265 { 1266 liPath.offset(shiftX,shiftY); 1267 } 1268 } 1269 if (ociBounds != null) 1270 { 1271 ociBounds.offset(shiftX, shiftY); 1272 ociShape.offset(shiftX, shiftY); 1273 } 1274 if(ociBoundsF != null) 1275 { 1276 ociBoundsF.offset(shiftX, shiftY); 1277 ociSlashShape.offset(shiftX, shiftY); 1278 } 1279 if(rBounds != null) 1280 { 1281 rBounds.offset(shiftX, shiftY);//bounds 1282 rPath.offset(shiftX, shiftY);//triangle 1283 rPath2.offset(shiftX, shiftY);//exclamation 1284 rdotPt.offset(shiftX, shiftY);//dot 1285 } 1286 if(nsBounds != null) 1287 { 1288 nsBounds.offset(shiftX, shiftY);//bounds 1289 nsCirclePt.offset(shiftX, shiftY);//circle 1290 nsLine.offset(shiftX, shiftY);//line 1291 } 1292 if (domBounds != null) 1293 { 1294 for (int i = 0; i < 6; i++) 1295 { 1296 Point temp = domPoints[i]; 1297 if (temp != null) 1298 { 1299 temp.offset(shiftX, shiftY); 1300 } 1301 } 1302 domBounds.offset(shiftX, shiftY); 1303 } 1304 if (mobilityBounds != null) 1305 { 1306 //shift mobility points 1307 mobilityPath.offset(shiftX, shiftY); 1308 if (mobilityPathFill != null) 1309 { 1310 mobilityPathFill.offset(shiftX, shiftY); 1311 } 1312 1313 mobilityBounds.offset(shiftX, shiftY); 1314 } 1315 1316 centerPoint.offset(shiftX, shiftY); 1317 symbolBounds.offset(shiftX, shiftY); 1318 imageBounds.offset(shiftX, shiftY); 1319 } 1320 // </editor-fold> 1321 1322 // <editor-fold defaultstate="collapsed" desc="Convert to SVG (SVGSymbolInfo)"> 1323 if(sdi instanceof SVGSymbolInfo) 1324 { 1325 StringBuilder sbSVG = new StringBuilder(); 1326 Path temp = null; 1327 SVGPath svgtemp = null; 1328 String svgStroke = RendererUtilities.colorToHexString(lineColor,false); 1329 String svgFill = RendererUtilities.colorToHexString(fillColor,false); 1330 String svgTextColor = RendererUtilities.colorToHexString(textColor,false); 1331 String svgTextBGColor = RendererUtilities.colorToHexString(textBackgroundColor,false); 1332 String svgStrokeWidth = String.valueOf(strokeWidthBasedOnDPI); 1333 String svgTextOutlineWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth()); 1334 String svgAlpha = "1"; 1335 if(alpha >= 0 && alpha <= 1) 1336 svgAlpha = String.valueOf(alpha); 1337 String svgDashArray = null; 1338 1339 if(hqBounds != null) 1340 { 1341 /*Line2D hqStaff = new Line2D.Double(pt1HQ,pt2HQ); 1342 temp = new Path2D.Double(); 1343 temp.append(hqStaff,false); 1344 sbSVG.append(Shape2SVG.Convert(temp, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, null));//*/ 1345 1346 svgtemp = new SVGPath(); 1347 svgtemp.moveTo(pt1HQ.x, pt1HQ.y); 1348 svgtemp.lineTo(pt2HQ.x, pt2HQ.y); 1349 svgtemp.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,Float.parseFloat(svgAlpha),Float.parseFloat(svgAlpha),null); 1350 } 1351 if (echelonBounds != null) 1352 { 1353 sbSVG.append(Shape2SVG.Convert(tiEchelon, svgTextBGColor, svgTextColor, svgTextOutlineWidth, svgAlpha, svgAlpha, null)); 1354 } 1355 if (amBounds != null) 1356 { 1357 sbSVG.append(Shape2SVG.Convert(tiAM, svgTextBGColor, svgTextColor, svgTextOutlineWidth, svgAlpha, svgAlpha, null)); 1358 } 1359 if (tfBounds != null) 1360 { 1361 sbSVG.append(Shape2SVG.Convert(tfRectangle, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, null,null)); 1362 } 1363 if(ebBounds != null) 1364 { 1365 String svgEBFill = RendererUtilities.colorToHexString(ebColor,false); 1366 //create fill and outline 1367 sbSVG.append(Shape2SVG.Convert(ebRectangle, svgStroke, svgEBFill, svgStrokeWidth, svgAlpha, svgAlpha, null,null)); 1368 //create internal text 1369 sbSVG.append(Shape2SVG.Convert(ebText, null, "#000000", null, svgAlpha, svgAlpha, null)); 1370 } 1371 if (fdiBounds != null) 1372 { 1373 /*int dpi = RendererSettings.getInstance().getDeviceDPI(); 1374 int lineLength = dpi / 96 * 6; 1375 int lineGap = dpi / 96 * 4; 1376 String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/ 1377 1378 /// /////////////////////////////////// 1379 //Divide line in 14 parts. line is 3 parts to 2 parts gap 1380 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 1381 //distance = distance / 14f; 1382 int lineGap = (int)((distance / 14f) * 2); 1383 int lineLength = (int)((distance / 14f) * 3); 1384 String svgFDIDashArray = "" + lineLength + " " + lineGap; 1385 /// ////////////////////////////////// 1386 1387 SVGPath fdiPath = new SVGPath(); 1388 1389 fdiPath.moveTo(fdiTop.x, fdiTop.y); 1390 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 1391 fdiPath.moveTo(fdiTop.x, fdiTop.y); 1392 fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/ 1393 1394 sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray,"round")); 1395 1396 } 1397 if (liBounds != null) 1398 { 1399 SVGPath svgliPath = new SVGPath(); 1400 svgliPath.moveTo(liTop.x, liTop.y); 1401 svgliPath.lineTo(liLeft.x, liLeft.y); 1402 svgliPath.moveTo(liTop.x, liTop.y); 1403 svgliPath.lineTo(liRight.x, liRight.y); 1404 1405 sbSVG.append(svgliPath.toSVGElement(svgStroke,strokeWidthBasedOnDPI,null,Float.parseFloat(svgAlpha),Float.parseFloat(svgAlpha),"round")); 1406 //sbSVG.append(Shape2SVG.Convert(liPath, svgStroke, null, String.valueOf(liStrokeWidth), svgAlpha, svgAlpha, null)); 1407 } 1408 if (ociBounds != null && ociShape != null) 1409 { 1410 1411 int status = SymbolID.getStatus(symbolID); 1412 Color statusColor = null; 1413 1414 switch (status) { 1415 //Fully Capable 1416 case SymbolID.Status_Present_FullyCapable: 1417 statusColor = Color.green; 1418 break; 1419 //Damaged 1420 case SymbolID.Status_Present_Damaged: 1421 statusColor = Color.yellow; 1422 break; 1423 //Destroyed 1424 case SymbolID.Status_Present_Destroyed: 1425 statusColor = Color.red; 1426 break; 1427 //full to capacity(hospital) 1428 case SymbolID.Status_Present_FullToCapacity: 1429 statusColor = Color.blue; 1430 break; 1431 default: 1432 break; 1433 } 1434 1435 String svgOCIStatusColor = RendererUtilities.colorToHexString(statusColor,false); 1436 sbSVG.append(Shape2SVG.Convert(ociBounds, null, svgStroke, svgStrokeWidth, svgAlpha, svgAlpha, null,null)); 1437 sbSVG.append(Shape2SVG.Convert(ociShape, null, svgOCIStatusColor, svgStrokeWidth, svgAlpha, svgAlpha, null,null)); 1438 1439 ociBounds = null; 1440 ociShape = null; 1441 1442 } 1443 1444 if (mobilityBounds != null) 1445 { 1446 if(svgMobilityGroup != null) 1447 sbSVG.append(svgMobilityGroup); 1448 else if (svgMobilityPath != null) 1449 sbSVG.append(svgMobilityPath.toSVGElement(svgStroke,strokeWidthBasedOnDPI,null,Float.parseFloat(svgAlpha),Float.parseFloat(svgAlpha),null)); 1450 1451 mobilityBounds = null; 1452 } 1453 1454 //add symbol 1455 ssi = (SVGSymbolInfo)sdi; 1456 sbSVG.append(ssi.getSVG()); 1457 1458 if (ociBounds != null && ociSlashShape != null) 1459 { 1460 SVGPath svgociSlash = processOperationalConditionIndicatorSlashSVG(symbolID,symbolBounds); 1461 1462 double size = symbolBounds.width(); 1463 float ociStrokeWidth = 3f; 1464 1465 ociStrokeWidth = (float) size / 20f; 1466 if (ociStrokeWidth < 1f) 1467 ociStrokeWidth = 1f; 1468 1469 sbSVG.append(svgociSlash.toSVGElement(svgStroke,ociStrokeWidth,null,Float.parseFloat(svgAlpha),Float.parseFloat(svgAlpha),null)); 1470 //sbSVG.append(Shape2SVG.Convert(ociSlashShape, svgStroke, null, String.valueOf(ociStrokeWidth), svgAlpha, svgAlpha, null)); 1471 ociBounds = null; 1472 ociSlashShape = null; 1473 } 1474 1475 if(rBounds != null) 1476 { 1477 String restrictedGroup = "<g id=\"restricted\" stroke-linecap=\"round\" stroke-linejoin=\"round\">"; 1478 //triangle 1479 restrictedGroup += Shape2SVG.Convert(rsvgPath, "#000000", "#FFFF00", String.valueOf(rStrokeWidth),svgAlpha,svgAlpha,null,null); 1480 //exclamation 1481 restrictedGroup += Shape2SVG.Convert(rsvgPath2, "#000000", null, String.valueOf(rStrokeWidth * 1.66667),svgAlpha,svgAlpha,null,null); 1482 //dot 1483 restrictedGroup += Shape2SVG.ConvertCircle(rdotPt, rdotRadius, "#000000", "#000000", String.valueOf(rStrokeWidth),svgAlpha,svgAlpha,null); 1484 restrictedGroup += "</g>"; 1485 1486 sbSVG.append(restrictedGroup); 1487 } 1488 1489 if(nsBounds != null) 1490 { 1491 String noStrikeGroup = "<g id=\"nostrike\">"; 1492 noStrikeGroup += Shape2SVG.ConvertCircle(nsCirclePt, nsRadius,"#000000", "#FFFF00", String.valueOf(nsStrokeWidth),svgAlpha,svgAlpha,null); 1493 noStrikeGroup += Shape2SVG.Convert(nssvgLine, "#000000", null, String.valueOf(nsStrokeWidth),svgAlpha,svgAlpha,null,null); 1494 noStrikeGroup += "</g>"; 1495 sbSVG.append(noStrikeGroup); 1496 } 1497 1498 if (domBounds != null) 1499 { 1500 //Path2D domPath = new Path2D.Double(); 1501 SVGPath domPath = new SVGPath(); 1502 1503 domPath.moveTo(domPoints[0].x, domPoints[0].y); 1504 if (domPoints[1] != null) 1505 { 1506 domPath.lineTo(domPoints[1].x, domPoints[1].y); 1507 } 1508 if (domPoints[2] != null) 1509 { 1510 domPath.lineTo(domPoints[2].x, domPoints[2].y); 1511 } 1512 //sbSVG.append(Shape2SVG.Convert(domPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, null)); 1513 sbSVG.append(domPath.toSVGElement(svgStroke, Float.parseFloat(svgStrokeWidth), null,Float.parseFloat(svgAlpha), Float.parseFloat(svgAlpha),null)); 1514 1515 1516 //domPath.reset(); 1517 domPath = new SVGPath(); 1518 1519 domPath.moveTo(domPoints[3].x, domPoints[3].y); 1520 domPath.lineTo(domPoints[4].x, domPoints[4].y); 1521 domPath.lineTo(domPoints[5].x, domPoints[5].y); 1522 sbSVG.append(Shape2SVG.Convert(domPath, "none", svgStroke, "0", svgAlpha, svgAlpha, null,null)); 1523 sbSVG.append(domPath.toSVGElement("none", 0f, svgStroke,Float.parseFloat(svgAlpha), Float.parseFloat(svgAlpha),null)); 1524 1525 domBounds = null; 1526 domPoints = null; 1527 } 1528 1529 newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds); 1530 } 1531 1532 // </editor-fold> 1533 1534 // <editor-fold defaultstate="collapsed" desc="Draw Modifiers (ImageInfo)"> 1535 if(sdi instanceof ImageInfo) 1536 { 1537 ii = (ImageInfo) sdi; 1538 1539 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 1540 Canvas ctx = new Canvas(bmp); 1541 1542 if (echelonBounds != null || amBounds != null) { 1543 // ctx.font = RendererSettings.getModifierFont(); 1544 } 1545 1546 //render//////////////////////////////////////////////////////// 1547 Paint paint = new Paint(); 1548 paint.setStyle(Style.STROKE); 1549 //paint.setColor(Color.black.toInt()); 1550 paint.setColor(lineColor.toInt()); 1551 if (alpha > -1) 1552 paint.setAlpha(alpha); 1553 paint.setStrokeWidth(2.0f); 1554 1555 paint.setStrokeWidth(strokeWidthBasedOnDPI); 1556 1557 if (hqBounds != null) { 1558 ctx.drawLine(pt1HQ.x, pt1HQ.y, pt2HQ.x, pt2HQ.y, paint); 1559 } 1560 1561 if (tfBounds != null) { 1562 ctx.drawRect(tfRectangle, paint); 1563 } 1564 1565 /*if (instBounds != null) Part of frame SVG now 1566 { 1567 paint.setStyle(Style.FILL); 1568 ctx.drawRect(instRectangle, paint); 1569 }//*/ 1570 1571 if (ebBounds != null) { 1572 //draw bar fill 1573 paint.setStyle(Style.FILL); 1574 paint.setColor(ebColor.toInt()); 1575 ctx.drawRect(ebRectangle, paint); 1576 1577 //draw bar outline 1578 paint.setStyle(Style.STROKE); 1579 paint.setStrokeWidth(4.0f); 1580 paint.setColor(lineColor.toInt()); 1581 ctx.drawRect(ebRectangle, paint); 1582 1583 //draw bar text 1584 modifierFont.setColor(Color.BLACK.toInt()); 1585 modifierFont.setStyle(Style.FILL); 1586 ctx.drawText(ebText.getText(), ebText.getLocation().x, ebText.getLocation().y, modifierFont); 1587 1588 ebBounds = null; 1589 ebText = null; 1590 ebRectangle = null; 1591 paint.setStrokeWidth(strokeWidthBasedOnDPI);//2.0f 1592 } 1593 1594 if (echelonBounds != null) { 1595 TextInfo[] aTiEchelon = 1596 { 1597 tiEchelon 1598 }; 1599 renderText(ctx, aTiEchelon, textColor, textBackgroundColor, modifierFont); 1600 1601 echelonBounds = null; 1602 tiEchelon = null; 1603 } 1604 1605 if (amBounds != null) { 1606 TextInfo[] aTiAM = 1607 { 1608 tiAM 1609 }; 1610 renderText(ctx, aTiAM, textColor, textBackgroundColor, modifierFont); 1611 amBounds = null; 1612 tiAM = null; 1613 } 1614 1615 if (fdiBounds != null) { 1616 1617 Paint fdiPaint = new Paint(); 1618 fdiPaint.setAntiAlias(true); 1619 fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 1620 if (alpha > -1) 1621 fdiPaint.setAlpha(alpha); 1622 fdiPaint.setStyle(Style.STROKE); 1623 1624 /*int dpi = RendererSettings.getInstance().getDeviceDPI(); 1625 1626 int lineLength = dpi / 96 * 6; 1627 int lineGap = dpi / 96 * 4;//*/ 1628 1629 /// /////////////////////////////////// 1630 //Divide line in 14 parts. line is 3 parts to 2 parts gap 1631 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 1632 //distance = distance / 14f; 1633 int lineGap = (int)((distance / 14f) * 2); 1634 int lineLength = (int)((distance / 14f) * 3); 1635 /// ////////////////////////////////// 1636 1637 fdiPaint.setPathEffect(new DashPathEffect(new float[] 1638 { 1639 lineLength, lineGap 1640 }, 0)); 1641 1642 1643 fdiPaint.setStrokeCap(Cap.ROUND); 1644 fdiPaint.setStrokeJoin(Join.MITER); 1645 fdiPaint.setStrokeWidth(strokeWidthBasedOnDPI); 1646 1647 Path fdiPath = new Path(); 1648 1649 fdiPath.moveTo(fdiTop.x, fdiTop.y); 1650 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 1651 fdiPath.moveTo(fdiTop.x, fdiTop.y); 1652 fdiPath.lineTo(fdiRight.x, fdiRight.y); 1653 ctx.drawPath(fdiPath, fdiPaint); 1654 1655 fdiBounds = null; 1656 1657 } 1658 1659 if (liBounds != null) { 1660 1661 Paint liPaint = new Paint(); 1662 liPaint.setAntiAlias(true); 1663 liPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 1664 if (alpha > -1) 1665 liPaint.setAlpha(alpha); 1666 liPaint.setStyle(Style.STROKE); 1667 1668 int dpi = RendererSettings.getInstance().getDeviceDPI(); 1669 1670 liPaint.setStrokeCap(Cap.BUTT); 1671 liPaint.setStrokeJoin(Join.MITER); 1672 liPaint.setStrokeWidth(strokeWidthBasedOnDPI); 1673 1674 ctx.drawPath(liPath, liPaint); 1675 1676 liBounds = null; 1677 1678 } 1679 1680 if (mobilityBounds != null) { 1681 Paint mobilityPaint = new Paint(); 1682 mobilityPaint.setStyle(Style.STROKE); 1683 //mobilityPaint.setColor(Color.black.toInt()); 1684 mobilityPaint.setColor(lineColor.toInt()); 1685 if (alpha > -1) 1686 mobilityPaint.setAlpha(alpha); 1687 1688 //ctx.lineCap = "butt"; 1689 //ctx.lineJoin = "miter"; 1690 if (ad >= SymbolID.Mobility_WheeledLimitedCrossCountry && ad < SymbolID.Mobility_ShortTowedArray)//mobility 1691 { 1692 //mobilityPaint.setStrokeWidth(3f); 1693 mobilityPaint.setStrokeWidth(strokeWidthBasedOnDPI); 1694 mobilityPaint.setAntiAlias(true); 1695 } else //towed-array 1696 { 1697 //mobilityPaint.setStrokeWidth(3f); 1698 mobilityPaint.setStrokeWidth(strokeWidthBasedOnDPI); 1699 //mobilityPaint.setAntiAlias(true); 1700 } 1701 1702 ctx.drawPath(mobilityPath, mobilityPaint); 1703 1704 if (mobilityPathFill != null) { 1705 mobilityPaint.setStyle(Style.FILL); 1706 ctx.drawPath(mobilityPathFill, mobilityPaint); 1707 } 1708 1709 mobilityBounds = null; 1710 1711 } 1712 1713 if (ociBounds != null) { 1714 Paint ociPaint = new Paint(); 1715 1716 int statusColor = 0; 1717 int status = SymbolID.getStatus(symbolID); 1718 if (status == (SymbolID.Status_Present_FullyCapable))//Fully Capable 1719 { 1720 statusColor = Color.green.toInt(); 1721 } else if (status == (SymbolID.Status_Present_Damaged))//Damage 1722 { 1723 statusColor = Color.yellow.toInt(); 1724 } else if (status == (SymbolID.Status_Present_Destroyed)) { 1725 statusColor = Color.red.toInt(); 1726 } else if (status == (SymbolID.Status_Present_FullToCapacity))//full to capacity(hospital) 1727 { 1728 statusColor = Color.blue.toInt(); 1729 } 1730 1731 ociPaint.setColor(lineColor.toInt()); 1732 ociPaint.setStyle(Style.FILL); 1733 1734 if (alpha > -1) 1735 ociPaint.setAlpha(alpha); 1736 ctx.drawRect(ociBounds, ociPaint); 1737 ociPaint.setColor(statusColor); 1738 if (alpha > -1) 1739 ociPaint.setAlpha(alpha); 1740 ctx.drawRect(ociShape, ociPaint); 1741 1742 ociBounds = null; 1743 ociShape = null; 1744 } 1745 1746 //draw original icon. 1747 //ctx.drawImage(ii.getImage(),symbolBounds.left, symbolBounds.top); 1748 ctx.drawBitmap(ii.getImage(), null, symbolBounds, null); 1749 1750 if(rBounds != null) 1751 { 1752 Paint rPaint = new Paint(); 1753 rPaint.setColor(Color.YELLOW.toInt()); 1754 rPaint.setAlpha(alpha); 1755 rPaint.setStrokeCap(Cap.ROUND); 1756 rPaint.setStrokeJoin(Join.ROUND); 1757 rPaint.setStyle(Style.FILL); 1758 //triangle fill 1759 ctx.drawPath(rPath, rPaint); 1760 1761 //triangle outline 1762 rPaint.setStrokeWidth(rStrokeWidth); 1763 rPaint.setStyle(Style.STROKE); 1764 rPaint.setColor(Color.BLACK.toInt()); 1765 ctx.drawPath(rPath, rPaint); 1766 1767 //exclamation line 1768 rPaint.setStrokeWidth(rStrokeWidth * 1.66667f); 1769 ctx.drawPath(rPath2, rPaint); 1770 1771 //exclamation dot 1772 rPaint.setStrokeWidth(rStrokeWidth); 1773 rPaint.setStyle(Style.FILL_AND_STROKE); 1774 ctx.drawCircle(rdotPt.x,rdotPt.y,rdotRadius,rPaint); 1775 1776 } 1777 if(nsBounds != null) 1778 { 1779 Paint nsPaint = new Paint(); 1780 nsPaint.setColor(Color.YELLOW.toInt()); 1781 nsPaint.setAlpha(alpha); 1782 nsPaint.setStrokeCap(Cap.ROUND); 1783 nsPaint.setStrokeJoin(Join.ROUND); 1784 nsPaint.setStyle(Style.FILL); 1785 1786 //circle fill 1787 ctx.drawCircle(nsCirclePt.x, nsCirclePt.y,nsRadius,nsPaint); 1788 1789 //circle outline 1790 nsPaint.setStyle(Style.STROKE); 1791 nsPaint.setColor(Color.BLACK.toInt()); 1792 nsPaint.setStrokeWidth((float)nsStrokeWidth); 1793 ctx.drawCircle(nsCirclePt.x,nsCirclePt.y,nsRadius,nsPaint); 1794 1795 //draw slash 1796 ctx.drawPath(nsLine,nsPaint); 1797 1798 } 1799 1800 if (domBounds != null) { 1801 drawDOMArrow(ctx, domPoints, alpha, lineColor); 1802 1803 domBounds = null; 1804 domPoints = null; 1805 } 1806 1807 if (ociBoundsF != null) { 1808 Paint ociPaint = new Paint(); 1809 int size = symbolBounds.width(); 1810 float ociStrokeWidth = 3f; 1811 1812 ociStrokeWidth = size / 20f; 1813 if (ociStrokeWidth < 1f) 1814 ociStrokeWidth = 1f; 1815 /*if(size > 50 && size < 100) 1816 ociStrokeWidth = 5f; 1817 else if(size >= 100 && size < 200) 1818 ociStrokeWidth = 7f; 1819 else if(size >= 200) 1820 ociStrokeWidth = 10f;*/ 1821 //ociPaint.setColor(Color.black.toInt()); 1822 ociPaint.setColor(lineColor.toInt()); 1823 if (alpha > -1) 1824 ociPaint.setAlpha(alpha); 1825 ociPaint.setStrokeWidth(ociStrokeWidth); 1826 ociPaint.setStrokeCap(Cap.BUTT); 1827 ociPaint.setStyle(Style.STROKE); 1828 ociPaint.setAntiAlias(true); 1829 ctx.drawPath(ociSlashShape, ociPaint); 1830 1831 ociBoundsF = null; 1832 ociSlashShape = null; 1833 } 1834 1835 1836 if (bmp != null) 1837 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 1838 } 1839 // </editor-fold> 1840 1841 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 1842 // </editor-fold> 1843 if (newsdi != null) 1844 { 1845 return newsdi; 1846 } 1847 else 1848 { 1849 return null; 1850 } 1851 1852 } 1853 1854 /** 1855 * 1856 * @param symbolID 1857 * @return 1858 * @deprecated no longer a thing in 2525D 1859 * TODO: remove 1860 */ 1861 private static double getYPositionForSCC(String symbolID) 1862 { 1863 double yPosition = 0.32; 1864 /*int aff = SymbolID.getAffiliation(symbolID); 1865 int context = SymbolID.getContext(symbolID); 1866 char affiliation = symbolID.charAt(1); 1867 1868 if(temp.equals("WMGC--"))//GROUND (BOTTOM) MILCO 1869 { 1870 if(affiliation == 'H' || 1871 affiliation == 'S')//suspect 1872 yPosition = 0.29; 1873 else if(affiliation == 'N' || 1874 affiliation == 'L')//exercise neutral 1875 yPosition = 0.32; 1876 else if(affiliation == 'F' || 1877 affiliation == 'A' ||//assumed friend 1878 affiliation == 'D' ||//exercise friend 1879 affiliation == 'M' ||//exercise assumed friend 1880 affiliation == 'K' ||//faker 1881 affiliation == 'J')//joker 1882 yPosition = 0.32; 1883 else 1884 yPosition = 0.34; 1885 } 1886 else if(temp.equals("WMMC--"))//MOORED MILCO 1887 { 1888 if(affiliation == 'H' || 1889 affiliation == 'S')//suspect 1890 yPosition = 0.25; 1891 else if(affiliation == 'N' || 1892 affiliation == 'L')//exercise neutral 1893 yPosition = 0.25; 1894 else if(affiliation == 'F' || 1895 affiliation == 'A' ||//assumed friend 1896 affiliation == 'D' ||//exercise friend 1897 affiliation == 'M' ||//exercise assumed friend 1898 affiliation == 'K' ||//faker 1899 affiliation == 'J')//joker 1900 yPosition = 0.25; 1901 else 1902 yPosition = 0.28; 1903 } 1904 else if(temp.equals("WMFC--"))//FLOATING MILCO 1905 { 1906 if(affiliation == 'H' || 1907 affiliation == 'S')//suspect 1908 yPosition = 0.29; 1909 else if(affiliation == 'N' || 1910 affiliation == 'L')//exercise neutral 1911 yPosition = 0.32; 1912 else if(affiliation == 'F' || 1913 affiliation == 'A' ||//assumed friend 1914 affiliation == 'D' ||//exercise friend 1915 affiliation == 'M' ||//exercise assumed friend 1916 affiliation == 'K' ||//faker 1917 affiliation == 'J')//joker 1918 yPosition = 0.32; 1919 else 1920 yPosition= 0.34; 1921 } 1922 else if(temp.equals("WMC---"))//GENERAL MILCO 1923 { 1924 if(affiliation == 'H' || 1925 affiliation == 'S')//suspect 1926 yPosition = 0.33; 1927 else if(affiliation == 'N' || 1928 affiliation == 'L')//exercise neutral 1929 yPosition = 0.36; 1930 else if(affiliation == 'F' || 1931 affiliation == 'A' ||//assumed friend 1932 affiliation == 'D' ||//exercise friend 1933 affiliation == 'M' ||//exercise assumed friend 1934 affiliation == 'K' ||//faker 1935 affiliation == 'J')//joker 1936 yPosition = 0.36; 1937 else 1938 yPosition = 0.36; 1939 }*/ 1940 1941 return yPosition; 1942 } 1943 1944 /** 1945 * 1946 * @param {type} symbolID 1947 * @param {type} bounds symbolBounds SO.Rectangle 1948 * @param {type} center SO.Point Location where symbol is centered. 1949 * @param {type} angle in degrees 1950 * @param {Boolean} isY Boolean. 1951 * @returns {Array} of SO.Point. First 3 items are the line. Last three are 1952 * the arrowhead. 1953 */ 1954 private static Point[] createDOMArrowPoints(String symbolID, Rect bounds, Point center, float angle, boolean isY, float modifierFontHeight) 1955 { 1956 Point[] arrowPoints = new Point[6]; 1957 Point pt1 = null; 1958 Point pt2 = null; 1959 Point pt3 = null; 1960 1961 int affiliation = SymbolID.getAffiliation(symbolID); 1962 int context = SymbolID.getContext(symbolID); 1963 int length = 40; 1964 if (SymbolUtilities.isCBRNEvent(symbolID)) 1965 { 1966 length = Math.round(bounds.height() / 2); 1967 } 1968 else if((SymbolUtilities.isHQ(symbolID))) 1969 { 1970 if(SymbolUtilities.hasRectangleFrame(symbolID)) 1971 length = bounds.height(); 1972 else 1973 length = (int)Math.round(bounds.height() * 0.7); 1974 } 1975 else// if(bounds.height() >= 100) 1976 { 1977 length = (int)Math.round(bounds.height() * 0.7); 1978 } 1979 1980 //get endpoint 1981 int dx2, dy2, 1982 x1, y1, 1983 x2, y2; 1984 1985 x1 = Math.round(center.x); 1986 y1 = Math.round(center.y); 1987 1988 pt1 = new Point(x1, y1); 1989 1990 if (SymbolUtilities.hasModifier(symbolID, Modifiers.Q_DIRECTION_OF_MOVEMENT ) && 1991 SymbolUtilities.isCBRNEvent(symbolID) || 1992 SymbolUtilities.isLand(symbolID) || 1993 SymbolID.getSymbolSet(symbolID)==SymbolID.SymbolSet_DismountedIndividuals) 1994 { 1995 //drawStaff = true; 1996 if(SymbolUtilities.isHQ(symbolID)==false)//has HQ staff to start from 1997 { 1998 y1 = bounds.top + bounds.height(); 1999 pt1 = new Point(x1, y1); 2000 2001 if (isY == true && SymbolUtilities.isCBRNEvent(symbolID))//make room for y modifier 2002 { 2003 int yModifierOffset = (int) modifierFontHeight; 2004 2005 yModifierOffset += RS.getTextOutlineWidth(); 2006 2007 pt1.offset(0, yModifierOffset); 2008 } 2009 2010 y1 = y1 + length; 2011 pt2 = new Point(x1, y1); 2012 } 2013 else 2014 { 2015 x1 = bounds.left+1; 2016 pt2 = new Point(x1, y1); 2017 if(SymbolUtilities.hasRectangleFrame(symbolID)) 2018 { 2019 /*y1 = bounds.top + bounds.height(); 2020 pt1 = new Point(x1, y1); 2021 y1 = y1 + length; 2022 pt2 = new Point(x1, y1);//*/ 2023 2024 pt1.x = x1; 2025 y1 = bounds.top + (bounds.height()); 2026 pt1.y = y1; 2027 x2 = x1; 2028 pt2.x = x2; 2029 y1 = pt1.y + bounds.height(); 2030 pt2.y = y1;//*/ 2031 2032 } 2033 else 2034 { 2035 pt1.x = x1; 2036 y1 = bounds.top + (bounds.height() / 2); 2037 pt1.y = y1; 2038 x2 = x1; 2039 pt2.x = x2; 2040 y1 = pt1.y + bounds.height(); 2041 pt2.y = y1; 2042 } 2043 } 2044 } 2045 2046 //get endpoint given start point and an angle 2047 //x2 = x1 + (length * Math.cos(radians))); 2048 //y2 = y1 + (length * Math.sin(radians))); 2049 angle = angle - 90;//in java, east is zero, we want north to be zero 2050 double radians = 0; 2051 radians = (angle * (Math.PI / 180));//convert degrees to radians 2052 2053 dx2 = x1 + (int) (length * Math.cos(radians)); 2054 dy2 = y1 + (int) (length * Math.sin(radians)); 2055 x2 = Math.round(dx2); 2056 y2 = Math.round(dy2); 2057 2058 2059 //UPDATED ARROWHEAD CODE 2060 Point[] head = null; 2061 Point endPoint = new Point((int) x2, (int) y2); 2062 if(pt2 != null) 2063 head = createDOMArrowHead(pt2, endPoint);//pt3); 2064 else 2065 head = createDOMArrowHead(pt1, endPoint);//pt3); 2066 2067 if(head != null) 2068 { 2069 arrowPoints[0] = pt1; 2070 arrowPoints[1] = pt2; 2071 arrowPoints[2] = pt3; 2072 arrowPoints[3] = head[0]; 2073 arrowPoints[4] = head[1]; 2074 arrowPoints[5] = head[2]; 2075 2076 //adjusted endpoint 2077 if(head.length >= 4 && head[3] != null) 2078 { 2079 arrowPoints[2] = head[3]; 2080 } 2081 } 2082 2083 return arrowPoints; 2084 2085 } 2086 2087 private static Point[] createDOMArrowHead(Point lpt1, Point lpt2) 2088 { 2089 Point[] arrowPoints = new Point[6]; 2090 Point pt1 = null; 2091 Point pt2 = null; 2092 Point pt3 = null; 2093 2094 int x1 = lpt1.x; 2095 int y1 = lpt1.y; 2096 int x2 = lpt2.x; 2097 int y2 = lpt2.y; 2098 2099 // Compute direction vector 2100 double dx = x2 - x1; 2101 double dy = y2 - y1; 2102 double length = Math.sqrt(dx * dx + dy * dy); 2103 2104 // Scale triangle size 2105 double scale = length * 0.1; // Scaling factor for size 2106 double offset = scale * 1.5; // Move triangle further down the line 2107 2108 // Normalize direction vector 2109 double unitX = dx / length; 2110 double unitY = dy / length; 2111 2112 // Compute perpendicular vector for triangle base 2113 double nx = -unitY; 2114 double ny = unitX; 2115 2116 // Compute adjusted triangle vertices 2117 int tipX = x2; 2118 int tipY = y2; 2119 int baseX1 = (int) (x2 - offset * unitX + scale * nx); 2120 int baseY1 = (int) (y2 - offset * unitY + scale * ny); 2121 int baseX2 = (int) (x2 - offset * unitX - scale * nx); 2122 int baseY2 = (int) (y2 - offset * unitY - scale * ny); 2123 2124 2125 //arrowHead = new Polygon(xPoints, yPoints, 3); 2126 arrowPoints[0] = new Point(tipX,tipY); 2127 arrowPoints[1] = new Point(baseX1,baseY1); 2128 arrowPoints[2] = new Point(baseX2,baseY2); 2129 // Adjust line endpoint to be the middle of the base line of the arrowhead 2130 int adjustedX2 = (baseX1 + baseX2) / 2; 2131 int adjustedY2 = (baseY1 + baseY2) / 2; 2132 arrowPoints[3] = new Point(adjustedX2,adjustedY2); 2133 2134 return arrowPoints; 2135 2136 } 2137 2138 private static void drawDOMArrow(Canvas ctx, Point[] domPoints, int alpha, Color lineColor) 2139 { 2140 float domStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 2141 if(domStrokeWidth < 1) 2142 domStrokeWidth=1; 2143 2144 2145 Paint domPaint = new Paint(); 2146 domPaint.setAntiAlias(true); 2147 domPaint.setStrokeCap(Cap.BUTT); 2148 domPaint.setStrokeJoin(Join.MITER); 2149 domPaint.setStrokeWidth(domStrokeWidth);//3 2150 domPaint.setColor(lineColor.toInt()); 2151 domPaint.setStyle(Style.STROKE); 2152 if(alpha > -1) 2153 domPaint.setAlpha(alpha); 2154 2155 Path domPath = new Path(); 2156 domPath.moveTo(domPoints[0].x, domPoints[0].y); 2157 if (domPoints[1] != null) 2158 { 2159 domPath.lineTo(domPoints[1].x, domPoints[1].y); 2160 } 2161 if (domPoints[2] != null) 2162 { 2163 domPath.lineTo(domPoints[2].x, domPoints[2].y); 2164 } 2165 ctx.drawPath(domPath, domPaint); 2166 2167 domPath.reset(); 2168 domPaint.setStyle(Style.FILL); 2169 domPath.moveTo(domPoints[3].x, domPoints[3].y); 2170 domPath.lineTo(domPoints[4].x, domPoints[4].y); 2171 domPath.lineTo(domPoints[5].x, domPoints[5].y); 2172 ctx.drawPath(domPath, domPaint); 2173 } 2174 2175 private static Rect processOperationalConditionIndicator(String symbolID, Rect symbolBounds, int offsetY) 2176 { 2177 //create Operational Condition Indicator 2178 //set color 2179 Rect bar = null; 2180 int status; 2181 Color statusColor; 2182 int barSize = 0; 2183 int pixelSize = symbolBounds.height(); 2184 2185 status = SymbolID.getStatus(symbolID); 2186 if (status == SymbolID.Status_Present_FullyCapable || 2187 status == SymbolID.Status_Present_Damaged || 2188 status == SymbolID.Status_Present_Destroyed || 2189 status == SymbolID.Status_Present_FullToCapacity) 2190 { 2191 if (pixelSize > 0) 2192 { 2193 barSize = Math.round(pixelSize / 5); 2194 } 2195 2196 if (barSize < 2) 2197 { 2198 barSize = 2; 2199 } 2200 2201 offsetY += Math.round(symbolBounds.top + symbolBounds.height()); 2202 2203 bar = RectUtilities.makeRect(symbolBounds.left + 2, offsetY, Math.round(symbolBounds.width()) - 4, barSize); 2204 } 2205 2206 return bar; 2207 } 2208 2209 private static Path processOperationalConditionIndicatorSlash(String symbolID, Rect symbolBounds) 2210 { 2211 //create Operational Condition Indicator 2212 Path path = null; 2213 int status; 2214 status = SymbolID.getStatus(symbolID); 2215 2216 if (status == SymbolID.Status_Present_Damaged || status == SymbolID.Status_Present_Destroyed) 2217 { 2218 float widthRatio = SymbolUtilities.getUnitRatioWidth(symbolID); 2219 float heightRatio = SymbolUtilities.getUnitRatioHeight(symbolID); 2220 2221 float slashHeight = (symbolBounds.height() / heightRatio * 1.47f); 2222 float slashWidth = (symbolBounds.width() / widthRatio * 0.85f); 2223 float centerX = symbolBounds.exactCenterX(); 2224 float centerY = symbolBounds.exactCenterY(); 2225 path = new Path(); 2226 if(status == SymbolID.Status_Present_Damaged)//Damaged / 2227 { 2228 path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2)); 2229 path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2)); 2230 } 2231 else if(status == SymbolID.Status_Present_Destroyed)//Destroyed X 2232 { 2233 path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2)); 2234 path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2)); 2235 path.moveTo(centerX - (slashWidth/2),centerY-(slashHeight/2)); 2236 path.lineTo(centerX + (slashWidth/2),centerY+(slashHeight/2)); 2237 } 2238 return path; 2239 2240 } 2241 2242 return path; 2243 } 2244 2245 private static SVGPath processOperationalConditionIndicatorSlashSVG(String symbolID, Rect symbolBounds) 2246 { 2247 //create Operational Condition Indicator 2248 SVGPath path = null; 2249 int status; 2250 status = SymbolID.getStatus(symbolID); 2251 2252 if (status == SymbolID.Status_Present_Damaged || status == SymbolID.Status_Present_Destroyed) 2253 { 2254 float widthRatio = SymbolUtilities.getUnitRatioWidth(symbolID); 2255 float heightRatio = SymbolUtilities.getUnitRatioHeight(symbolID); 2256 2257 float slashHeight = (symbolBounds.height() / heightRatio * 1.47f); 2258 float slashWidth = (symbolBounds.width() / widthRatio * 0.85f); 2259 float centerX = symbolBounds.exactCenterX(); 2260 float centerY = symbolBounds.exactCenterY(); 2261 path = new SVGPath(); 2262 if(status == SymbolID.Status_Present_Damaged)//Damaged / 2263 { 2264 path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2)); 2265 path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2)); 2266 } 2267 else if(status == SymbolID.Status_Present_Destroyed)//Destroyed X 2268 { 2269 path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2)); 2270 path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2)); 2271 path.moveTo(centerX - (slashWidth/2),centerY-(slashHeight/2)); 2272 path.lineTo(centerX + (slashWidth/2),centerY+(slashHeight/2)); 2273 } 2274 return path; 2275 2276 } 2277 2278 return path; 2279 } 2280 2281 2282 public static SymbolDimensionInfo processSpeedLeader(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 2283 { 2284 SymbolDimensionInfo rsdi = sdi; 2285 2286 Rect imageBounds = sdi.getImageBounds(); 2287 Rect symbolBounds = sdi.getSymbolBounds(); 2288 Point symbolCenter = sdi.getCenterPoint(); 2289 int ss = SymbolID.getSymbolSet(symbolID); 2290 int pixelSize = RendererSettings.getInstance().getDefaultPixelSize(); 2291 int dpi = RendererSettings.getInstance().getDeviceDPI(); 2292 if(attributes != null && attributes.containsKey(MilStdAttributes.PixelSize)) 2293 pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize)); 2294 float strokeWidth = 3f; 2295 strokeWidth = (float) dpi / 48f; 2296 if (strokeWidth < 1f) 2297 strokeWidth = 1f; 2298 2299 Path slPath = null; 2300 SVGPath slsvgPath = null; 2301 Rect slBounds = null; 2302 try { 2303 if (SymbolUtilities.hasModifier(symbolID, Modifiers.AJ_SPEED_LEADER) && 2304 (modifiers != null && modifiers.containsKey(Modifiers.AJ_SPEED_LEADER))) 2305 { 2306 String aj = modifiers.get(Modifiers.AJ_SPEED_LEADER); 2307 String[] values = aj.split(" "); 2308 if (values.length >= 3) { 2309 int speed = Integer.parseInt(values[0]); 2310 String speedUnit = values[1]; 2311 int angle = 0; 2312 if (values[2].length() == 3) 2313 angle = Integer.parseInt(values[2]) - 90; 2314 else 2315 angle = (int) (Integer.parseInt(values[2]) * 0.05625) - 90; 2316 2317 slPath = new Path(); 2318 slPath.moveTo(symbolCenter.x, symbolCenter.y); 2319 slsvgPath = new SVGPath(); 2320 slsvgPath.moveTo(symbolCenter.x, symbolCenter.y); 2321 2322 //convert to Knots 2323 switch (speedUnit)//KPH, KPS, MPH, NMH, KTS//https://www.aviationhunt.com/speed-converter/ 2324 { 2325 case "KPH": 2326 speed = (int) (speed * 0.539957); 2327 break; 2328 case "KPS"://https://www.metric-conversions.org/speed/kilometers-per-second-to-knots.htm 2329 speed = (int) (speed * 1943.84); 2330 break; 2331 case "MPH": 2332 speed = (int) (speed * 0.86897); 2333 break; 2334 } 2335 2336 int distance = 0; 2337 char frame = SymbolID.getFrameShape(symbolID); 2338 boolean fast = false; 2339 if (frame == '0' && ss == SymbolID.SymbolSet_Air || 2340 ss == SymbolID.SymbolSet_AirMissile || 2341 ss == SymbolID.SymbolSet_SignalsIntelligence_Air || 2342 ss == SymbolID.SymbolSet_SpaceMissile || 2343 ss == SymbolID.SymbolSet_Space || 2344 (SymbolID.getVersion(symbolID) <= SymbolID.Version_2525Dch1 && ss == SymbolID.SymbolSet_SignalsIntelligence_Space)) 2345 { 2346 fast = true; 2347 } 2348 else if(frame == SymbolID.FrameShape_Air || frame == SymbolID.FrameShape_Space) 2349 { 2350 fast = true; 2351 } 2352 2353 float distanceScaler = dpi;//spec does scale by inch, but if the symbol is too big, scale by pixel size 2354 if(dpi < pixelSize) 2355 distanceScaler = pixelSize; 2356 2357 if(fast) 2358 {//aircraft might be 1/4 inch if its speed is less than 300 knots, 1/2 inch if its speed is between 300 and 600 knots and 3/4 inch if its speed is more than 600 knots. 2359 if (speed < 300) 2360 distance = (int) (distanceScaler * 0.25)/300 * speed; 2361 else if (speed < 600) 2362 distance = (int) (distanceScaler * 0.5)/600 * speed; 2363 else 2364 distance = (int) (distanceScaler * 0.75); 2365 } 2366 else//submarine might be 1/4 inch if its speed is less than 15 knots, 1/2 inch if its speed is between 15 and 30 knots and 3/4 inch if its speed is more than 30 knots 2367 { 2368 if (speed < 15) 2369 distance = (int) (distanceScaler * 0.25)/15 * speed; 2370 else if (speed < 30) 2371 distance = (int) (distanceScaler * 0.5)/30 * speed; 2372 else 2373 distance = (int) (distanceScaler * 0.75); 2374 } 2375 double radians = (angle * (Math.PI / 180));//convert degrees to radians 2376 int x2 = (int) (symbolCenter.x + distance * Math.cos(radians)); 2377 int y2 = (int) (symbolCenter.y + distance * Math.sin(radians)); 2378 2379 slPath.lineTo(x2, y2); 2380 slsvgPath.lineTo(x2, y2); 2381 slBounds = slsvgPath.getBounds(); 2382 imageBounds.union(slBounds); 2383 } 2384 2385 if (sdi instanceof ImageInfo) { 2386 Bitmap bmp = Bitmap.createBitmap((int) Math.ceil(imageBounds.width()), (int) Math.ceil(imageBounds.height()), Config.ARGB_8888); 2387 Canvas ctx = new Canvas(bmp); 2388 2389 int alpha = 1; 2390 if (attributes.containsKey(MilStdAttributes.Alpha)) 2391 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 2392 2393 2394 Paint slPaint = new Paint(); 2395 slPaint.setColor(Color.BLACK.toInt()); 2396 slPaint.setAlpha(alpha * 255); 2397 slPaint.setStyle(Style.STROKE); 2398 slPaint.setStrokeWidth(strokeWidth); 2399 2400 2401 float offsetX = 0; 2402 float offsetY = 0; 2403 if (imageBounds.left < 0) 2404 offsetX = imageBounds.left * -1; 2405 if (imageBounds.top < 0) 2406 offsetY = imageBounds.top * -1; 2407 2408 slPath.offset(offsetX,offsetY); 2409 2410 ctx.drawBitmap(((ImageInfo) sdi).getImage(), offsetX, offsetY, null); 2411 ctx.drawPath(slPath,slPaint); 2412 2413 imageBounds.offset((int)offsetX,(int)offsetY); 2414 symbolBounds.offset((int)offsetX,(int)offsetY); 2415 symbolCenter.offset((int)offsetX,(int)offsetY); 2416 2417 rsdi = new ImageInfo(bmp, symbolCenter, symbolBounds); 2418 } 2419 else if (sdi instanceof SVGSymbolInfo) 2420 {//public static String Convert(Shape shape,String stroke, String fill, String strokeWidth, String strokeOpacity, String fillOpacity, String dashArray, String lineCap) 2421 String svg = ((SVGSymbolInfo) sdi).getSVG(); 2422 svg += slsvgPath.toSVGElement("#000000",strokeWidth,"none",1,1,null); 2423 //svg += (Shape2SVG.Convert(slPath, "#000000", "none", String.valueOf(strokeWidth),null,null,null, null)); 2424 rsdi = new SVGSymbolInfo(svg,symbolCenter,symbolBounds,imageBounds); 2425 } 2426 } 2427 } 2428 catch(Exception exc) 2429 { 2430 ErrorLogger.LogException("ModifierRenderer","processSpeedLineIndicator",exc); 2431 } 2432 2433 return rsdi; 2434 } 2435 2436 /** 2437 * uses 2525C layout which shows most modifiers 2438 * @param sdi 2439 * @param symbolID 2440 * @param modifiers 2441 * @param attributes 2442 * @return 2443 */ 2444 public static SymbolDimensionInfo processUnknownTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 2445 { 2446 Paint modifierFont = getFont(attributes); 2447 float[] hd = getFontHeightandDescent(modifierFont); 2448 float modifierFontHeight = hd[0]; 2449 float modifierFontDescent = hd[1]; 2450 2451 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 2452 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 2453 { 2454 String temp = attributes.get(MilStdAttributes.FontFamily); 2455 if(temp != null && !temp.isEmpty()) 2456 modifierFontName = temp; 2457 } 2458 2459 int bufferHorizontal = (int)modifierFontHeight/2; 2460 int bufferXL = bufferHorizontal; 2461 int bufferXR = bufferHorizontal; 2462 int bufferY = 2; 2463 int bufferText = 2; 2464 int x = 0; 2465 int y = 0;//best y 2466 2467 SymbolDimensionInfo newsdi = null; 2468 2469 ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size()); 2470 2471 int descent = (int) (modifierFontDescent + 0.5); 2472 2473 Rect labelBounds = null; 2474 int labelWidth, labelHeight; 2475 2476 Rect bounds = new Rect(sdi.getSymbolBounds()); 2477 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 2478 Point centerPoint = new Point(sdi.getCenterPoint()); 2479 Rect imageBounds = new Rect(sdi.getImageBounds()); 2480 2481 int echelon = SymbolID.getAmplifierDescriptor(symbolID); 2482 String echelonText = SymbolUtilities.getEchelonText(echelon); 2483 String amText = SymbolUtilities.getStandardIdentityModifier(symbolID); 2484 int mobility = SymbolID.getAmplifierDescriptor(symbolID); 2485 2486 //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol 2487 bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height()); 2488 2489 2490 //check if text is too tall: 2491 boolean byLabelHeight = false; 2492 labelHeight = (int) (modifierFontHeight + 0.5);/* RendererUtilities.measureTextHeight(RendererSettings.getModifierFontName(), 2493 RendererSettings.getModifierFontSize(), 2494 RendererSettings.getModifierFontStyle()).fullHeight;*/ 2495 2496 int maxHeight = (bounds.height()); 2497 if ((labelHeight * 3) > maxHeight) 2498 { 2499 byLabelHeight = true; 2500 } 2501 2502 //Affiliation Modifier being drawn as a display modifier 2503 String affiliationModifier = null; 2504 if (RS.getDrawAffiliationModifierAsLabel() == true) 2505 { 2506 affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID); 2507 } 2508 if (affiliationModifier != null) 2509 { //Set affiliation modifier 2510 modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier); 2511 //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier; 2512 }//*/ 2513 2514 2515 // int y0 = 0;//W E/F 2516 // int y1 = 0;//X/Y G 2517 // int y2 = 0;//V/AD/AE H/AF 2518 // int y3 = 0;//T M CC 2519 // int y4 = 0;//Z J/K/L/N/P 2520 // 2521 2522 // <editor-fold defaultstate="collapsed" desc="Build Modifiers"> 2523 String modifierValue = null; 2524 TextInfo tiTemp = null; 2525 //if(Modifiers.C_QUANTITY in modifiers 2526 if (modifiers.containsKey(Modifiers.C_QUANTITY) 2527 && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.C_QUANTITY)) 2528 { 2529 String text = modifiers.get(Modifiers.C_QUANTITY); 2530 if(text != null) 2531 { 2532 //bounds = armyc2.c5isr.renderer.utilities.RendererUtilities.getTextOutlineBounds(modifierFont, text, new SO.Point(0,0)); 2533 tiTemp = new TextInfo(text, 0, 0, modifierFont, modifierFontName); 2534 labelBounds = tiTemp.getTextBounds(); 2535 labelWidth = labelBounds.width(); 2536 x = Math.round((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f)); 2537 y = Math.round(symbolBounds.top - bufferY - descent); 2538 tiTemp.setLocation(x, y); 2539 tiArray.add(tiTemp); 2540 } 2541 } 2542 2543 //if(Modifiers.X_ALTITUDE_DEPTH in modifiers || Modifiers.Y_LOCATION in modifiers) 2544 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 2545 { 2546 modifierValue = null; 2547 2548 String xm = null, 2549 ym = null; 2550 2551 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.X_ALTITUDE_DEPTH)) 2552 { 2553 xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);// xm = modifiers.X; 2554 } 2555 if (modifiers.containsKey(Modifiers.Y_LOCATION)) 2556 { 2557 ym = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y; 2558 } 2559 if (xm == null && ym != null) 2560 { 2561 modifierValue = ym; 2562 } 2563 else if (xm != null && ym == null) 2564 { 2565 modifierValue = xm; 2566 } 2567 else if (xm != null && ym != null) 2568 { 2569 modifierValue = xm + " " + ym; 2570 } 2571 2572 if(modifierValue != null) 2573 { 2574 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2575 labelBounds = tiTemp.getTextBounds(); 2576 labelWidth = labelBounds.width(); 2577 2578 if (!byLabelHeight) 2579 { 2580 x = bounds.left - labelBounds.width() - bufferXL; 2581 y = bounds.top + labelHeight - descent; 2582 } 2583 else 2584 { 2585 x = bounds.left - labelBounds.width() - bufferXL; 2586 2587 y = (bounds.height()); 2588 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2589 2590 y = y - ((labelHeight + bufferText)); 2591 y = bounds.top + y; 2592 } 2593 2594 tiTemp.setLocation(x, y); 2595 tiArray.add(tiTemp); 2596 } 2597 } 2598 2599 if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) ) 2600 { 2601 modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS); 2602 2603 if(modifierValue != null) 2604 { 2605 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2606 labelBounds = tiTemp.getTextBounds(); 2607 labelWidth = labelBounds.width(); 2608 2609 x = bounds.left + bounds.width() + bufferXR; 2610 if (!byLabelHeight) 2611 { 2612 y = bounds.top + labelHeight - descent; 2613 } 2614 else 2615 { 2616 y = (bounds.height()); 2617 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2618 2619 y = y - ((labelHeight + bufferText)); 2620 y = bounds.top + y; 2621 } 2622 2623 tiTemp.setLocation(x, y); 2624 tiArray.add(tiTemp); 2625 2626 } 2627 } 2628 2629 if ((modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) || 2630 (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) || 2631 (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))) 2632 { 2633 String vm = null, 2634 adm = null, 2635 aem = null; 2636 2637 if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.V_EQUIP_TYPE)) 2638 { 2639 vm = modifiers.get(Modifiers.V_EQUIP_TYPE); 2640 } 2641 if (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AD_PLATFORM_TYPE)) 2642 { 2643 adm = modifiers.get(Modifiers.AD_PLATFORM_TYPE); 2644 } 2645 if (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 2646 { 2647 aem = modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 2648 } 2649 2650 modifierValue = ""; 2651 if(vm != null && vm.equals("") == false) 2652 modifierValue = vm; 2653 if(adm != null && adm.equals("") == false) 2654 modifierValue += " " + adm; 2655 if(aem != null && aem.equals("") == false) 2656 modifierValue += " " + aem; 2657 2658 if(modifierValue != null) 2659 modifierValue = modifierValue.trim(); 2660 if(modifierValue != null && modifierValue.equals("") == false) 2661 { 2662 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2663 labelBounds = tiTemp.getTextBounds(); 2664 labelWidth = labelBounds.width(); 2665 2666 x = bounds.left - labelBounds.width() - bufferXL; 2667 2668 y = (bounds.height()); 2669 y = (int) ((y * 0.5f) + ((labelHeight - descent) * 0.5f)); 2670 y = bounds.top + y; 2671 2672 tiTemp.setLocation(x, y); 2673 tiArray.add(tiTemp); 2674 } 2675 } 2676 2677 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 2678 { 2679 modifierValue = ""; 2680 String hm = "", 2681 afm = ""; 2682 2683 hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 2684 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 2685 { 2686 hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 2687 } 2688 if (modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AF_COMMON_IDENTIFIER)) 2689 { 2690 afm = modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 2691 } 2692 2693 modifierValue = hm + " " + afm; 2694 modifierValue = modifierValue.trim(); 2695 2696 if(modifierValue != null && modifierValue.equals("") == false) 2697 { 2698 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2699 labelBounds = tiTemp.getTextBounds(); 2700 labelWidth = labelBounds.width(); 2701 2702 x = bounds.left + bounds.width() + bufferXR; 2703 2704 y = (bounds.height()); 2705 y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5)); 2706 y = bounds.top + y; 2707 2708 tiTemp.setLocation(x, y); 2709 tiArray.add(tiTemp); 2710 2711 } 2712 } 2713 2714 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 2715 { 2716 modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 2717 2718 if(modifierValue != null) 2719 { 2720 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2721 labelBounds = tiTemp.getTextBounds(); 2722 labelWidth = labelBounds.width(); 2723 2724 if (!byLabelHeight) 2725 { 2726 x = bounds.left - labelWidth - bufferXL; 2727 y = bounds.top + bounds.height(); 2728 } 2729 else 2730 { 2731 x = bounds.left - labelWidth - bufferXL; 2732 2733 y = (bounds.height()); 2734 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2735 2736 y = y + ((labelHeight + bufferText) - descent); 2737 y = bounds.top + y; 2738 } 2739 2740 tiTemp.setLocation(x, y); 2741 tiArray.add(tiTemp); 2742 } 2743 } 2744 2745 if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 2746 { 2747 modifierValue = ""; 2748 2749 if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.M_HIGHER_FORMATION)) 2750 { 2751 modifierValue += modifiers.get(Modifiers.M_HIGHER_FORMATION); 2752 } 2753 if (modifiers.containsKey(Modifiers.AS_COUNTRY)) 2754 { 2755 if (modifierValue.length() > 0) 2756 { 2757 modifierValue += " "; 2758 } 2759 modifierValue += modifiers.get(Modifiers.AS_COUNTRY); 2760 } 2761 2762 if(modifierValue.equals("")==false) 2763 { 2764 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2765 labelBounds = tiTemp.getTextBounds(); 2766 labelWidth = labelBounds.width(); 2767 2768 x = bounds.left + bounds.width() + bufferXR; 2769 if (!byLabelHeight) 2770 { 2771 y = bounds.top + bounds.height(); 2772 } 2773 else 2774 { 2775 y = (bounds.height()); 2776 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2777 2778 y = y + ((labelHeight + bufferText - descent)); 2779 y = bounds.top + y; 2780 } 2781 2782 tiTemp.setLocation(x, y); 2783 tiArray.add(tiTemp); 2784 2785 } 2786 } 2787 2788 if (modifiers.containsKey(Modifiers.Z_SPEED) ) 2789 { 2790 modifierValue = modifiers.get(Modifiers.Z_SPEED); 2791 2792 if(modifierValue != null) 2793 { 2794 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2795 labelBounds = tiTemp.getTextBounds(); 2796 labelWidth = labelBounds.width(); 2797 2798 x = bounds.left - labelWidth - bufferXL; 2799 if (!byLabelHeight) 2800 { 2801 y = Math.round(bounds.top + bounds.height() + labelHeight + bufferText); 2802 } 2803 else 2804 { 2805 y = (bounds.height()); 2806 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2807 2808 y = y + ((labelHeight + bufferText) * 2) - (descent * 2); 2809 y = Math.round(bounds.top + y); 2810 } 2811 2812 tiTemp.setLocation(x, y); 2813 tiArray.add(tiTemp); 2814 } 2815 } 2816 2817 if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING) 2818 || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)// 2819 || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)// 2820 || modifiers.containsKey(Modifiers.N_HOSTILE)// 2821 || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))// 2822 { 2823 modifierValue = null; 2824 2825 String jm = null, 2826 km = null, 2827 lm = null, 2828 nm = null, 2829 pm = null; 2830 2831 if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 2832 { 2833 jm = modifiers.get(Modifiers.J_EVALUATION_RATING); 2834 } 2835 if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.K_COMBAT_EFFECTIVENESS)) 2836 { 2837 km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS); 2838 } 2839 if (modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.L_SIGNATURE_EQUIP)) 2840 { 2841 lm = modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 2842 } 2843 if (modifiers.containsKey(Modifiers.N_HOSTILE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.N_HOSTILE)) 2844 { 2845 nm = modifiers.get(Modifiers.N_HOSTILE); 2846 } 2847 if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.P_IFF_SIF_AIS)) 2848 { 2849 pm = modifiers.get(Modifiers.P_IFF_SIF_AIS); 2850 } 2851 2852 modifierValue = ""; 2853 if (jm != null && jm.equals("") == false) 2854 { 2855 modifierValue = modifierValue + jm; 2856 } 2857 if (km != null && km.equals("") == false) 2858 { 2859 modifierValue = modifierValue + " " + km; 2860 } 2861 if (lm != null && lm.equals("") == false) 2862 { 2863 modifierValue = modifierValue + " " + lm; 2864 } 2865 if (nm != null && nm.equals("") == false) 2866 { 2867 modifierValue = modifierValue + " " + nm; 2868 } 2869 if (pm != null && pm.equals("") == false) 2870 { 2871 modifierValue = modifierValue + " " + pm; 2872 } 2873 2874 if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ') 2875 { 2876 modifierValue = modifierValue.substring(1); 2877 } 2878 2879 modifierValue = modifierValue.trim(); 2880 2881 if(modifierValue.equals("")==false) 2882 { 2883 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2884 labelBounds = tiTemp.getTextBounds(); 2885 labelWidth = labelBounds.width(); 2886 2887 x = bounds.left + bounds.width() + bufferXR; 2888 if (!byLabelHeight) 2889 { 2890 y = Math.round(bounds.top + bounds.height() + labelHeight + bufferText); 2891 } 2892 else 2893 { 2894 y = (bounds.height()); 2895 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2896 2897 y = y + ((labelHeight + bufferText) * 2) - (descent * 2); 2898 y = Math.round(bounds.top + y); 2899 } 2900 2901 tiTemp.setLocation(x, y); 2902 tiArray.add(tiTemp); 2903 2904 } 2905 2906 } 2907 2908 if (modifiers.containsKey(Modifiers.W_DTG_1)) 2909 { 2910 modifierValue = modifiers.get(Modifiers.W_DTG_1); 2911 2912 if(modifierValue != null) 2913 { 2914 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2915 labelBounds = tiTemp.getTextBounds(); 2916 labelWidth = labelBounds.width(); 2917 2918 if (!byLabelHeight) 2919 { 2920 x = bounds.left - labelWidth - bufferXL; 2921 y = bounds.top - bufferY - descent; 2922 } 2923 else 2924 { 2925 x = bounds.left - labelWidth - bufferXL; 2926 2927 y = (bounds.height()); 2928 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2929 2930 y = y - ((labelHeight + bufferText) * 2); 2931 y = bounds.top + y; 2932 } 2933 2934 tiTemp.setLocation(x, y); 2935 tiArray.add(tiTemp); 2936 } 2937 } 2938 2939 if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER)) 2940 { 2941 modifierValue = null; 2942 String E = null, 2943 F = null; 2944 2945 if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER)) 2946 { 2947 E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER); 2948 modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER); 2949 } 2950 if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.F_REINFORCED_REDUCED)) 2951 { 2952 F = modifiers.get(Modifiers.F_REINFORCED_REDUCED); 2953 } 2954 2955 if (E != null && E.equals("") == false) 2956 { 2957 modifierValue = E; 2958 } 2959 2960 if (F != null && F.equals("") == false) 2961 { 2962 if (F.toUpperCase(Locale.US) == ("R")) 2963 { 2964 F = "(+)"; 2965 } 2966 else if (F.toUpperCase(Locale.US) == ("D")) 2967 { 2968 F = "(-)"; 2969 } 2970 else if (F.toUpperCase(Locale.US) == ("RD")) 2971 { 2972 F = "(" + (char) (177) + ")"; 2973 } 2974 } 2975 2976 if (F != null && F.equals("") == false) 2977 { 2978 if (modifierValue != null && modifierValue.equals("") == false) 2979 { 2980 modifierValue = modifierValue + " " + F; 2981 } 2982 else 2983 { 2984 modifierValue = F; 2985 } 2986 } 2987 2988 if(modifierValue != null) 2989 { 2990 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2991 labelBounds = tiTemp.getTextBounds(); 2992 labelWidth = labelBounds.width(); 2993 2994 if (!byLabelHeight) 2995 { 2996 x = bounds.left + bounds.width() + bufferXR; 2997 y = bounds.top - bufferY - descent; 2998 } 2999 else 3000 { 3001 x = bounds.left + bounds.width() + bufferXR; 3002 3003 y = (bounds.height()); 3004 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 3005 3006 y = y - ((labelHeight + bufferText) * 2); 3007 y = bounds.top + y; 3008 } 3009 3010 tiTemp.setLocation(x, y); 3011 tiArray.add(tiTemp); 3012 3013 } 3014 } 3015 3016 if (modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AA_SPECIAL_C2_HQ)) 3017 { 3018 modifierValue = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ); 3019 3020 if(modifierValue != null) 3021 { 3022 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 3023 labelBounds = tiTemp.getTextBounds(); 3024 labelWidth = labelBounds.width(); 3025 3026 x = (int) ((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f)); 3027 3028 y = (symbolBounds.height());//checkpoint, get box above the point 3029 y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5)); 3030 y = symbolBounds.top + y; 3031 3032 tiTemp.setLocation(x, y); 3033 tiArray.add(tiTemp); 3034 } 3035 } 3036 3037 3038 // </editor-fold> 3039 3040 //Shift Points and Draw 3041 newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes, modifierFont); 3042 3043 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 3044 tiArray = null; 3045 tiTemp = null; 3046 //tempShape = null; 3047 //ctx = null; 3048 //buffer = null; 3049 // </editor-fold> 3050 3051 return newsdi; 3052 } 3053 3054 3055 public static SymbolDimensionInfo processSPTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 3056 { 3057 Paint modifierFont = getFont(attributes); 3058 float[] hd = getFontHeightandDescent(modifierFont); 3059 float modifierFontHeight = hd[0]; 3060 float modifierFontDescent = hd[1]; 3061 3062 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 3063 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 3064 { 3065 String temp = attributes.get(MilStdAttributes.FontFamily); 3066 if(temp != null && !temp.isEmpty()) 3067 modifierFontName = temp; 3068 } 3069 3070 int bufferXL = 7; 3071 int bufferXR = 7; 3072 int bufferY = 2; 3073 int bufferText = 2; 3074 int x = 0; 3075 int y = 0;//best y 3076 SymbolDimensionInfo newsdi = null; 3077 3078 ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size()); 3079 3080 int descent = (int) (modifierFontDescent + 0.5); 3081 3082 3083 Rect labelBounds = null; 3084 int labelWidth, labelHeight; 3085 3086 Rect bounds = new Rect(sdi.getSymbolBounds()); 3087 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 3088 Rect imageBounds = new Rect(sdi.getImageBounds()); 3089 3090 //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol 3091 bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height()); 3092 3093 labelHeight = (int) (modifierFontHeight + 0.5); 3094 3095 //Affiliation Modifier being drawn as a display modifier 3096 String affiliationModifier = null; 3097 if (RS.getDrawAffiliationModifierAsLabel() == true) 3098 { 3099 affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID); 3100 } 3101 if (affiliationModifier != null) 3102 { //Set affiliation modifier 3103 modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier); 3104 //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier; 3105 }//*/ 3106 3107 //Check for Valid Country Code 3108 int cc = SymbolID.getCountryCode(symbolID); 3109 String scc = ""; 3110 if(cc > 0) 3111 { 3112 scc = GENCLookup.getInstance().get3CharCode(cc); 3113 } 3114 if(!scc.isEmpty()) 3115 modifiers.put(Modifiers.AS_COUNTRY, scc); 3116 3117 // <editor-fold defaultstate="collapsed" desc="Build Modifiers"> 3118 String modifierValue = null; 3119 TextInfo tiTemp = null; 3120 3121 3122 List<Modifier> mods = getLabelPositionIndexes(symbolID, modifiers, attributes); 3123 3124 Modifier mod = null; 3125 if(mods != null) { 3126 for (int i = 0; i < mods.size(); i++) { 3127 mod = mods.get(i); 3128 3129 tiTemp = new TextInfo(mod.getText(), 0, 0, modifierFont, modifierFontName); 3130 labelBounds = tiTemp.getTextBounds(); 3131 labelWidth = (int) labelBounds.width(); 3132 3133 //centered 3134 if(mod.getIndexX()==0) 3135 x = (int) getLabelXPosition(symbolBounds, labelWidth, mod.getIndexX(), modifierFontHeight); 3136 else//on left 3137 x = (int) getLabelXPosition(bounds, labelWidth, mod.getIndexX(), modifierFontHeight); 3138 //above center V 3139 y = (int) getLabelYPosition(bounds, labelHeight, descent, bufferText, mod.getCentered(), mod.getIndexY()); 3140 3141 tiTemp.setLocation(x, y); 3142 tiArray.add(tiTemp); 3143 } 3144 } 3145 3146 3147 // </editor-fold> 3148 3149 //Shift Points and Draw 3150 newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes, modifierFont); 3151 3152 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 3153 tiArray = null; 3154 tiTemp = null; 3155 //tempShape = null; 3156 //ctx = null; 3157 //buffer = null; 3158 // </editor-fold> 3159 3160 return newsdi; 3161 } 3162 3163 public static SymbolDimensionInfo ProcessTGSPWithSpecialModifierLayout(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes, Color lineColor) 3164 { 3165 Paint modifierFont = getFont(attributes); 3166 float[] hd = getFontHeightandDescent(modifierFont); 3167 float modifierFontHeight = hd[0]; 3168 float modifierFontDescent = hd[1]; 3169 3170 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 3171 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 3172 { 3173 String temp = attributes.get(MilStdAttributes.FontFamily); 3174 if(temp != null && !temp.isEmpty()) 3175 modifierFontName = temp; 3176 } 3177 3178 ImageInfo ii = null; 3179 SVGSymbolInfo ssi = null; 3180 3181 int bufferXL = 6; 3182 int bufferXR = 4; 3183 int bufferY = 2; 3184 int bufferText = 2; 3185 int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel 3186 int x = 0; 3187 int y = 0; 3188 int x2 = 0; 3189 int y2 = 0; 3190 3191 int outlineOffset = RS.getTextOutlineWidth(); 3192 int labelHeight = 0; 3193 int labelWidth = 0; 3194 int alpha = -1; 3195 SymbolDimensionInfo newsdi = null; 3196 Color textColor = lineColor; 3197 Color textBackgroundColor = null; 3198 int ss = SymbolID.getSymbolSet(symbolID); 3199 int ec = SymbolID.getEntityCode(symbolID); 3200 int e = SymbolID.getEntity(symbolID); 3201 int et = SymbolID.getEntityType(symbolID); 3202 int est = SymbolID.getEntitySubtype(symbolID); 3203 3204 //Feint Dummy Indicator variables 3205 Rect fdiBounds = null; 3206 Point fdiTop = null; 3207 Point fdiLeft = null; 3208 Point fdiRight = null; 3209 3210 ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>(); 3211 boolean duplicate = false; 3212 3213 Rect bounds = new Rect(sdi.getSymbolBounds()); 3214 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 3215 Point centerPoint = new Point(sdi.getCenterPoint()); 3216 Rect imageBounds = new Rect(sdi.getImageBounds()); 3217 3218 if (attributes.containsKey(MilStdAttributes.Alpha)) 3219 { 3220 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 3221 textColor.setAlpha(alpha); 3222 } 3223 3224 centerPoint = new Point(Math.round(sdi.getCenterPoint().x), Math.round(sdi.getCenterPoint().y)); 3225 3226 boolean byLabelHeight = false; 3227 labelHeight = (int) (modifierFontHeight + 0.5f); 3228 3229 int maxHeight = (symbolBounds.height()); 3230 if ((labelHeight * 3) > maxHeight) 3231 { 3232 byLabelHeight = true; 3233 } 3234 3235 int descent = (int) (modifierFontDescent + 0.5f); 3236 int yForY = -1; 3237 3238 Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0); 3239 Rect labelBounds2 = null; 3240 String strText = ""; 3241 String strText1 = ""; 3242 String strText2 = ""; 3243 TextInfo text1 = null; 3244 TextInfo text2 = null; 3245 3246 3247 if (outlineOffset > 2) 3248 { 3249 outlineOffset = ((outlineOffset - 1) / 2); 3250 } 3251 else 3252 { 3253 outlineOffset = 0; 3254 } 3255 3256 //Check for Valid Country Code 3257 int cc = SymbolID.getCountryCode(symbolID); 3258 String scc = ""; 3259 if(cc > 0) 3260 { 3261 scc = GENCLookup.getInstance().get3CharCode(cc); 3262 } 3263 if(!scc.isEmpty()) 3264 modifiers.put(Modifiers.AS_COUNTRY, scc); 3265 3266 // <editor-fold defaultstate="collapsed" desc="Process Special Modifiers"> 3267 TextInfo ti = null; 3268 if (SymbolUtilities.isCBRNEvent(symbolID))//chemical 3269 { 3270 if ((labelHeight * 3) > bounds.height()) 3271 { 3272 byLabelHeight = true; 3273 } 3274 } 3275 3276 if(ss == SymbolID.SymbolSet_ControlMeasure) { 3277 if (ec == 130500) //contact point 3278 { 3279 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3280 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3281 if (strText != null) { 3282 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3283 labelWidth = Math.round(ti.getTextBounds().width()); 3284 //One modifier symbols and modifier goes in center 3285 x = bounds.left + (int) (bounds.width() * 0.5f); 3286 x = x - (int) (labelWidth * 0.5f); 3287 y = bounds.top + (int) (bounds.height() * 0.4f); 3288 y = y + (int) (labelHeight * 0.5f); 3289 3290 ti.setLocation(Math.round(x), Math.round(y)); 3291 arrMods.add(ti); 3292 } 3293 } 3294 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3295 strText = modifiers.get(Modifiers.W_DTG_1); 3296 if (strText != null) { 3297 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3298 labelWidth = ti.getTextBounds().width(); 3299 3300 x = (bounds.left - labelWidth - bufferXL); 3301 y = (bounds.top + labelHeight - descent); 3302 3303 ti.setLocation(x, y); 3304 arrMods.add(ti); 3305 } 3306 } 3307 } 3308 else if (ec == 130700) //decision point 3309 { 3310 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3311 3312 strText = ""; 3313 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 3314 strText += modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3315 if (modifiers.containsKey(Modifiers.AS_COUNTRY)) 3316 strText += " " + modifiers.get(Modifiers.AS_COUNTRY); 3317 strText = strText.trim(); 3318 3319 if (!strText.isEmpty()) { 3320 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3321 labelWidth = Math.round(ti.getTextBounds().width()); 3322 //One modifier symbols and modifier goes in center 3323 x = bounds.left + (int) (bounds.width() * 0.5f); 3324 x = x - (int) (labelWidth * 0.5f); 3325 y = bounds.top + (int) (bounds.height() * 0.5f); 3326 y = y + (int) (labelHeight * 0.5f); 3327 3328 ti.setLocation(Math.round(x), Math.round(y)); 3329 arrMods.add(ti); 3330 } 3331 } 3332 } 3333 else if (ec == 212800)//harbor 3334 { 3335 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3336 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3337 if (strText != null) { 3338 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3339 labelWidth = Math.round(ti.getTextBounds().width()); 3340 //One modifier symbols and modifier goes in center 3341 x = bounds.left + (int) (bounds.width() * 0.5f); 3342 x = x - (int) (labelWidth * 0.5f); 3343 y = bounds.top + (int) (bounds.height() * 0.5f); 3344 y = y + (int) (labelHeight * 0.5f); 3345 3346 ti.setLocation(Math.round(x), Math.round(y)); 3347 arrMods.add(ti); 3348 } 3349 } 3350 } else if (ec == 131300)//point of interest 3351 { 3352 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3353 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3354 if (strText != null) { 3355 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3356 labelWidth = Math.round(ti.getTextBounds().width()); 3357 //One modifier symbols, top third & center 3358 x = bounds.left + (int) (bounds.width() * 0.5f); 3359 x = x - (int) (labelWidth * 0.5f); 3360 y = bounds.top + (int) (bounds.height() * 0.25f); 3361 y = y + (int) (labelHeight * 0.5f); 3362 3363 ti.setLocation(Math.round(x), Math.round(y)); 3364 arrMods.add(ti); 3365 } 3366 } 3367 } else if (ec == 131800//waypoint 3368 || ec == 240900)//fire support station 3369 { 3370 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3371 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3372 if (strText != null) { 3373 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3374 3375 //One modifier symbols and modifier goes right of center 3376 if (ec == 131800) 3377 x = bounds.left + (int) (bounds.width() * 0.75f); 3378 else 3379 x = bounds.left + (bounds.width()); 3380 y = bounds.top + (int) (bounds.height() * 0.5f); 3381 y = y + (int) ((labelHeight - descent) * 0.5f); 3382 3383 ti.setLocation(Math.round(x), Math.round(y)); 3384 arrMods.add(ti); 3385 } 3386 } 3387 } 3388 else if (ec == 131900)//Airfield (AEGIS Only) 3389 { 3390 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3391 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3392 if (strText != null) { 3393 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3394 3395 //One modifier symbols and modifier goes right of symbol 3396 3397 x = bounds.left + (bounds.width() + bufferXR); 3398 3399 y = bounds.top + (int) (bounds.height() * 0.5f); 3400 y = y + (int) ((labelHeight - descent) * 0.5f); 3401 3402 ti.setLocation(Math.round(x), Math.round(y)); 3403 arrMods.add(ti); 3404 } 3405 } 3406 } 3407 else if (ec == 180100 //Air Control point 3408 || ec == 180200) //Communications Check point 3409 { 3410 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3411 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3412 if (strText != null) { 3413 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3414 labelWidth = ti.getTextBounds().width(); 3415 //One modifier symbols and modifier goes just below of center 3416 x = bounds.left + (int) (bounds.width() * 0.5); 3417 x = x - (int) (labelWidth * 0.5); 3418 y = bounds.top + (int) (bounds.height() * 0.5f); 3419 y = y + (int) (((bounds.height() * 0.5f) - labelHeight) / 2) + labelHeight - descent; 3420 3421 ti.setLocation(Math.round(x), Math.round(y)); 3422 arrMods.add(ti); 3423 } 3424 } 3425 } else if (ec == 160300 || //T (target reference point) 3426 ec == 132000 || //T (Target Handover) 3427 ec == 240601 || //ap,ap1,x,h (Point/Single Target) 3428 ec == 240602) //ap (nuclear target) 3429 { //Targets with special modifier positions 3430 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) 3431 && ec == 240601)//H //point single target 3432 { 3433 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3434 if (strText != null) { 3435 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3436 3437 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3438 y = bounds.top + (int) (bounds.height() * 0.75f); 3439 y = y + (int) (labelHeight * 0.5f); 3440 3441 ti.setLocation(Math.round(x), Math.round(y)); 3442 arrMods.add(ti); 3443 } 3444 } 3445 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) 3446 && ec == 240601)//X point or single target 3447 { 3448 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3449 if (strText != null) { 3450 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3451 labelWidth = Math.round(ti.getTextBounds().width()); 3452 x = RectUtilities.getCenterX(bounds) - (int) (bounds.width() * 0.15f); 3453 x = x - (labelWidth); 3454 y = bounds.top + (int) (bounds.height() * 0.75f); 3455 y = y + (int) (labelHeight * 0.5f); 3456 3457 ti.setLocation(Math.round(x), Math.round(y)); 3458 arrMods.add(ti); 3459 } 3460 } 3461 strText = null; 3462 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) && (ec == 160300 || ec == 132000)) { 3463 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3464 if (strText != null) { 3465 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3466 3467 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3468 y = bounds.top + (int) (bounds.height() * 0.30f); 3469 3470 ti.setLocation(Math.round(x), Math.round(y)); 3471 arrMods.add(ti); 3472 } 3473 } 3474 if (ec == 240601 || ec == 240602) 3475 { 3476 if (modifiers.containsKey(Modifiers.AP_TARGET_NUMBER)) { 3477 strText = modifiers.get(Modifiers.AP_TARGET_NUMBER); 3478 } 3479 if (ec == 240601 && modifiers.containsKey(Modifiers.AP1_TARGET_NUMBER_EXTENSION)) { 3480 if (strText != null) 3481 strText = strText + " " + modifiers.get(Modifiers.AP1_TARGET_NUMBER_EXTENSION); 3482 else 3483 strText = modifiers.get(Modifiers.AP1_TARGET_NUMBER_EXTENSION); 3484 } 3485 if (strText != null) { 3486 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3487 3488 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3489 y = bounds.top + (int) (bounds.height() * 0.30f); 3490 3491 ti.setLocation(Math.round(x), Math.round(y)); 3492 arrMods.add(ti); 3493 } 3494 } 3495 } 3496 else if (ec == 213400 && SymbolID.getVersion(symbolID)==SymbolID.Version_APP6Ech2) //Navigation Reference Point 3497 { 3498 if (modifiers.containsKey(Modifiers.W_DTG_1)) 3499 { 3500 strText = modifiers.get(Modifiers.W_DTG_1); 3501 if (strText != null) { 3502 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3503 3504 x = (int)(bounds.left + (bounds.width() * 0.75f)); 3505 y = (int)(bounds.top + (bounds.height() * 0.75f)); 3506 y = y + labelHeight; 3507 3508 ti.setLocation(Math.round(x), Math.round(y)); 3509 arrMods.add(ti); 3510 } 3511 } 3512 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3513 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3514 if (strText != null) { 3515 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3516 3517 x = (int)(bounds.left + (bounds.width() * 0.25f)-ti.getTextBounds().width()); 3518 y = (int)(bounds.top + (bounds.height() * 0.25f)); 3519 3520 ti.setLocation(Math.round(x), Math.round(y)); 3521 arrMods.add(ti); 3522 } 3523 } 3524 } 3525 else if (ec == 132100)//Key Terrain 3526 { 3527 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3528 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3529 if (strText != null) { 3530 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3531 3532 //One modifier symbols and modifier goes right of symbol 3533 3534 x = bounds.left + (int)(bounds.width() * 0.5) + bufferXL; 3535 3536 y = bounds.top + (int) (bounds.height() * 0.5f); 3537 y = y + (int) ((labelHeight - descent) * 0.5f); 3538 3539 ti.setLocation(Math.round(x), Math.round(y)); 3540 arrMods.add(ti); 3541 } 3542 } 3543 } 3544 else if (ec == 132300) //Vital Ground 3545 { 3546 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3547 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3548 if (strText != null) { 3549 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3550 3551 //One modifier symbols and modifier goes bottom right of symbol 3552 x = (int)(bounds.left + (bounds.width() * 0.88f)); 3553 3554 y = (int)(bounds.top + (bounds.height() * 0.88f)); 3555 y = y + (labelHeight - descent); 3556 3557 ti.setLocation(Math.round(x), Math.round(y)); 3558 arrMods.add(ti); 3559 } 3560 } 3561 } 3562 else if(ec == 182600)//Isolated Personnel Location 3563 { 3564 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3565 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3566 if (strText != null) { 3567 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3568 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3569 3570 x = (int)(bounds.left + (bounds.width() * 0.5)); 3571 x = x - (int) (labelWidth * 0.5); 3572 y = (int)bounds.top - descent; 3573 ti.setLocation(Math.round(x), Math.round(y)); 3574 arrMods.add(ti); 3575 } 3576 } 3577 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3578 strText = modifiers.get(Modifiers.W_DTG_1); 3579 if (strText != null) { 3580 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3581 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3582 3583 x = (int)bounds.left - labelWidth - bufferXL; 3584 if (!byLabelHeight) { 3585 y = (int)bounds.top + labelHeight - descent; 3586 } else { 3587 //y = bounds.y + ((bounds.getHeight * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3588 y = (int)(bounds.top + ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText))); 3589 } 3590 3591 ti.setLocation(Math.round(x), Math.round(y)); 3592 arrMods.add(ti); 3593 } 3594 } 3595 if (modifiers.containsKey(Modifiers.W1_DTG_2)) { 3596 strText = modifiers.get(Modifiers.W1_DTG_2); 3597 if (strText != null) { 3598 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3599 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3600 3601 x = (int)bounds.left - labelWidth - bufferXL; 3602 if (!byLabelHeight) { 3603 y = (int)bounds.top + labelHeight - descent; 3604 } else { 3605 //y = bounds.y + ((bounds.getHeight * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3606 y = (int)(bounds.top + ((bounds.height() * 0.5) - (((labelHeight * 2) - descent) * 0.5) + (-descent - bufferText))); 3607 } 3608 3609 ti.setLocation(Math.round(x), Math.round(y)); 3610 arrMods.add(ti); 3611 } 3612 } 3613 } 3614 else if (SymbolUtilities.isCBRNEvent(symbolID)) //CBRN 3615 { 3616 if (modifiers.containsKey(Modifiers.N_HOSTILE)) { 3617 strText = modifiers.get(Modifiers.N_HOSTILE); 3618 if (strText != null) { 3619 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3620 3621 x = bounds.left + bounds.width() + bufferXR; 3622 3623 if (!byLabelHeight) { 3624 y = bounds.top + bounds.height(); 3625 } else { 3626 y = bounds.top + (int) ((bounds.height() * 0.5f) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText)); 3627 } 3628 3629 ti.setLocation(Math.round(x), Math.round(y)); 3630 arrMods.add(ti); 3631 } 3632 3633 } 3634 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3635 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3636 if (strText != null) { 3637 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3638 3639 x = bounds.left + bounds.width() + bufferXR; 3640 if (!byLabelHeight) { 3641 y = bounds.top + labelHeight - descent; 3642 } else { 3643 //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3644 y = bounds.top + (int) ((bounds.height() * 0.5f) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)); 3645 } 3646 3647 ti.setLocation(Math.round(x), Math.round(y)); 3648 arrMods.add(ti); 3649 } 3650 } 3651 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3652 strText = modifiers.get(Modifiers.W_DTG_1); 3653 if (strText != null) { 3654 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3655 labelWidth = Math.round(ti.getTextBounds().width()); 3656 3657 x = bounds.left - labelWidth - bufferXL; 3658 if (!byLabelHeight) { 3659 y = bounds.top + labelHeight - descent; 3660 } else { 3661 //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3662 y = bounds.top + (int) ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)); 3663 } 3664 3665 ti.setLocation(Math.round(x), Math.round(y)); 3666 arrMods.add(ti); 3667 } 3668 } 3669 if ((ec == 281500 || ec == 281600) && modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) {//nuclear event or nuclear fallout producing event 3670 strText = modifiers.get(Modifiers.V_EQUIP_TYPE); 3671 if (strText != null) { 3672 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3673 3674 //subset of nbc, just nuclear 3675 labelWidth = Math.round(ti.getTextBounds().width()); 3676 x = bounds.left - labelWidth - bufferXL; 3677 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5));//((bounds.height / 2) - (labelHeight/2)); 3678 3679 ti.setLocation(Math.round(x), Math.round(y)); 3680 arrMods.add(ti); 3681 } 3682 } 3683 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3684 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3685 if (strText != null) { 3686 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3687 labelWidth = Math.round(ti.getTextBounds().width()); 3688 x = bounds.left - labelWidth - bufferXL; 3689 if (!byLabelHeight) { 3690 y = bounds.top + bounds.height(); 3691 } else { 3692 //y = bounds.y + ((bounds.height * 0.5) + ((labelHeight-descent) * 0.5) + (labelHeight + bufferText)); 3693 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText)); 3694 } 3695 ti.setLocation(Math.round(x), Math.round(y)); 3696 arrMods.add(ti); 3697 } 3698 } 3699 if (modifiers.containsKey(Modifiers.Y_LOCATION)) { 3700 strText = modifiers.get(Modifiers.Y_LOCATION); 3701 if (strText != null) { 3702 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3703 labelWidth = Math.round(ti.getTextBounds().width()); 3704 //just NBC 3705 //x = bounds.left + (bounds.width() * 0.5); 3706 //x = x - (labelWidth * 0.5); 3707 x = bounds.left + (int) (bounds.width() * 0.5f); 3708 x = x - (int) (labelWidth * 0.5f); 3709 3710 if (!byLabelHeight) { 3711 y = bounds.top + bounds.height() + labelHeight - descent + bufferY; 3712 } else { 3713 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + ((labelHeight + bufferText) * 2) - descent); 3714 3715 } 3716 yForY = y + descent; //so we know where to start the DOM arrow. 3717 ti.setLocation(Math.round(x), Math.round(y)); 3718 arrMods.add(ti); 3719 } 3720 3721 } 3722 if (modifiers.containsKey(Modifiers.C_QUANTITY)) { 3723 strText = modifiers.get(Modifiers.C_QUANTITY); 3724 if (strText != null) { 3725 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3726 labelWidth = Math.round(ti.getTextBounds().width()); 3727 //subset of NBC, just nuclear 3728 x = bounds.left + (int) (bounds.width() * 0.5); 3729 x = x - (int) (labelWidth * 0.5); 3730 y = bounds.top - descent; 3731 ti.setLocation(Math.round(x), Math.round(y)); 3732 arrMods.add(ti); 3733 } 3734 3735 } 3736 } 3737 else if (ec == 270701)//static depiction 3738 { 3739 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3740 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3741 if (strText != null) { 3742 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3743 labelWidth = Math.round(ti.getTextBounds().width()); 3744 x = bounds.left + (int) (bounds.width() * 0.5); 3745 x = x - (int) (labelWidth * 0.5); 3746 y = bounds.top - descent;// + (bounds.height * 0.5); 3747 //y = y + (labelHeight * 0.5); 3748 3749 ti.setLocation(Math.round(x), Math.round(y)); 3750 arrMods.add(ti); 3751 } 3752 3753 } 3754 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3755 strText = modifiers.get(Modifiers.W_DTG_1); 3756 if (strText != null) { 3757 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3758 labelWidth = Math.round(ti.getTextBounds().width()); 3759 x = bounds.left + (int) (bounds.width() * 0.5); 3760 x = x - (int) (labelWidth * 0.5); 3761 y = bounds.top + (bounds.height()); 3762 y = y + (labelHeight); 3763 3764 ti.setLocation(Math.round(x), Math.round(y)); 3765 arrMods.add(ti); 3766 } 3767 } 3768 if (modifiers.containsKey(Modifiers.N_HOSTILE)) { 3769 strText = modifiers.get(Modifiers.N_HOSTILE); 3770 if (strText != null) { 3771 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3772 TextInfo ti2 = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3773 labelWidth = Math.round(ti.getTextBounds().width()); 3774 x = bounds.left + (bounds.width()) + bufferXR;//right 3775 //x = x + labelWidth;//- (labelBounds.width * 0.75); 3776 3777 duplicate = true; 3778 3779 x2 = bounds.left;//left 3780 x2 = x2 - labelWidth - bufferXL;// - (labelBounds.width * 0.25); 3781 3782 y = bounds.top + (int) (bounds.height() * 0.5);//center 3783 y = y + (int) ((labelHeight - descent) * 0.5); 3784 3785 y2 = y; 3786 3787 ti.setLocation(Math.round(x), Math.round(y)); 3788 ti2.setLocation(Math.round(x2), Math.round(y2)); 3789 arrMods.add(ti); 3790 arrMods.add(ti2); 3791 } 3792 } 3793 3794 } 3795 else if(e == 21 && et == 35)//sonobuoys 3796 { 3797 boolean is2525E = (SymbolID.getVersion(symbolID) >= SymbolID.Version_2525E); 3798 //H sitting on center of circle to the right 3799 //T above H 3800 centerPoint = SymbolUtilities.getCMSymbolAnchorPoint(symbolID,RectUtilities.makeRectFFromRect(bounds)); 3801 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3802 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3803 if (strText != null) { 3804 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3805 TextInfo ti2 = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3806 labelWidth = Math.round(ti.getTextBounds().width()); 3807 x = bounds.left + (bounds.width()) + bufferXR;//right 3808 y = centerPoint.y; 3809 3810 if(is2525E) { 3811 x = x - (int)(bounds.width() * 0.2); 3812 y = (int) (bounds.top + (bounds.height() / 2)); 3813 } 3814 3815 ti.setLocation(Math.round(x), Math.round(y)); 3816 arrMods.add(ti); 3817 } 3818 } 3819 if (est == 0 || est == 1 || est == 4 || est == 7 || est == 8 || est == 15) { 3820 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3821 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3822 if (strText != null) { 3823 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3824 TextInfo ti2 = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3825 labelWidth = Math.round(ti.getTextBounds().width()); 3826 x = (bounds.left + (bounds.width()) + bufferXR - (int)(bounds.width() * 0.2) );//right 3827 y = centerPoint.y - labelHeight; 3828 3829 if(is2525E) { 3830 y = (bounds.top + (bounds.height() / 2)) - labelHeight; 3831 } 3832 3833 ti.setLocation(Math.round(x), Math.round(y)); 3834 arrMods.add(ti); 3835 } 3836 } 3837 } 3838 } 3839 else if(ec == 282001 || //tower, low 3840 ec == 282002) //tower, high 3841 { 3842 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) { 3843 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3844 if (strText != null) { 3845 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3846 labelWidth = Math.round(ti.getTextBounds().width()); 3847 x = bounds.left + (int) (bounds.width() * 0.7); 3848 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3849 //y = y + (labelHeight * 0.5); 3850 3851 ti.setLocation(Math.round(x), Math.round(y)); 3852 arrMods.add(ti); 3853 } 3854 3855 } 3856 } 3857 else if(ec == 180600)//TACAN 3858 { 3859 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3860 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3861 if (strText != null) { 3862 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3863 labelWidth = Math.round(ti.getTextBounds().width()); 3864 x = bounds.left + bounds.width() + bufferXR; 3865 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3866 //y = y + (labelHeight * 0.5); 3867 3868 ti.setLocation(Math.round(x), Math.round(y)); 3869 arrMods.add(ti); 3870 } 3871 3872 } 3873 } 3874 else if(ec == 210300)//Defended Asset 3875 { 3876 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3877 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3878 if (strText != null) { 3879 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3880 labelWidth = Math.round(ti.getTextBounds().width()); 3881 x = bounds.left - labelWidth - bufferXL; 3882 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3883 //y = y + (labelHeight * 0.5); 3884 3885 ti.setLocation(Math.round(x), Math.round(y)); 3886 arrMods.add(ti); 3887 } 3888 3889 } 3890 } 3891 else if(ec == 210600)//Air Detonation 3892 { 3893 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) { 3894 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3895 if (strText != null) { 3896 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3897 labelWidth = Math.round(ti.getTextBounds().width()); 3898 x = bounds.left + (bounds.width() + bufferXR); 3899 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3900 //y = y + (labelHeight * 0.5); 3901 3902 ti.setLocation(Math.round(x), Math.round(y)); 3903 arrMods.add(ti); 3904 } 3905 3906 } 3907 } 3908 else if(ec == 210800)//Impact Point 3909 { 3910 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3911 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3912 if (strText != null) { 3913 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3914 labelWidth = Math.round(ti.getTextBounds().width()); 3915 x = bounds.left + (int) (bounds.width() * 0.65f); 3916// x = x - (labelBounds.width * 0.5); 3917 y = bounds.top + (int) (bounds.height() * 0.25f); 3918 y = y + (int) (labelHeight * 0.5f); 3919 //y = y + (labelHeight * 0.5); 3920 3921 ti.setLocation(Math.round(x), Math.round(y)); 3922 arrMods.add(ti); 3923 } 3924 3925 } 3926 } 3927 else if(ec == 211000)//Launched Torpedo 3928 { 3929 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3930 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3931 if (strText != null) { 3932 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3933 labelWidth = Math.round(ti.getTextBounds().width()); 3934 x = (int)(bounds.left + (bounds.width() * 0.5) - (labelWidth/2)); 3935 y = bounds.top - bufferY; 3936 3937 ti.setLocation(Math.round(x), Math.round(y)); 3938 arrMods.add(ti); 3939 } 3940 3941 } 3942 } 3943 else if(ec == 214900 || ec == 215600)//General Sea SubSurface Station & General Sea Surface Station 3944 { 3945 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3946 strText = modifiers.get(Modifiers.W_DTG_1); 3947 if (strText != null) { 3948 ti = new TextInfo(strText + " - ", 0, 0, modifierFont, modifierFontName); 3949 x = bounds.left + (bounds.width() + bufferXR); 3950 y = bounds.top + labelHeight; 3951 3952 ti.setLocation(Math.round(x), Math.round(y)); 3953 arrMods.add(ti); 3954 } 3955 3956 } 3957 if (modifiers.containsKey(Modifiers.W1_DTG_2)) { 3958 strText = modifiers.get(Modifiers.W1_DTG_2); 3959 if (strText != null) { 3960 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3961 x = bounds.left + (bounds.width() + bufferXR); 3962 y = bounds.top + (labelHeight * 2); 3963 3964 ti.setLocation(Math.round(x), Math.round(y)); 3965 arrMods.add(ti); 3966 } 3967 3968 } 3969 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3970 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3971 if (strText != null) { 3972 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3973 x = bounds.left + (bounds.width() + bufferXR); 3974 y = bounds.top + (labelHeight * 3); 3975 3976 ti.setLocation(Math.round(x), Math.round(y)); 3977 arrMods.add(ti); 3978 } 3979 3980 } 3981 } 3982 else if(ec == 217000)//Shore Control Station 3983 { 3984 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3985 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3986 if (strText != null) { 3987 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3988 labelWidth = Math.round(ti.getTextBounds().width()); 3989 x = (int)(bounds.left + (bounds.width() * 0.5) - (labelWidth/2)); 3990 y = bounds.top + bounds.height() + labelHeight + bufferY; 3991 3992 ti.setLocation(Math.round(x), Math.round(y)); 3993 arrMods.add(ti); 3994 } 3995 3996 } 3997 } 3998 else if(ec == 250600)//Known Point 3999 { 4000 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 4001 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 4002 if (strText != null) { 4003 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4004 labelWidth = Math.round(ti.getTextBounds().width()); 4005 x = bounds.left + (bounds.width() + bufferXR); 4006 4007 if(!RendererSettings.getInstance().getOutlineSPControlMeasures() && 4008 !(attributes.containsKey(MilStdAttributes.OutlineSymbol) && Boolean.parseBoolean(attributes.get(MilStdAttributes.OutlineSymbol)))) 4009 x += bufferXR; 4010 4011 y = bounds.top + (int) (bounds.height() * 0.30f); 4012 4013 ti.setLocation(Math.round(x), Math.round(y)); 4014 arrMods.add(ti); 4015 } 4016 4017 } 4018 } 4019 else if(ec == 360100 || ec == 360200 || ec == 360300)//Protection of Cultural Property 4020 { 4021 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 4022 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 4023 if (strText != null) { 4024 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4025 4026 //One modifier symbols and modifier goes right of center 4027 x = (int)(bounds.left + bounds.width() + bufferXR); 4028 y = (int)(bounds.top + (bounds.height() * 0.6)); 4029 4030 ti.setLocation(Math.round(x), Math.round(y)); 4031 arrMods.add(ti); 4032 } 4033 } 4034 } 4035 } 4036 else if(ss == SymbolID.SymbolSet_Atmospheric) 4037 { 4038 String modX = null; 4039 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 4040 modX = (modifiers.get(Modifiers.X_ALTITUDE_DEPTH)); 4041 4042 if(ec == 162300)//Freezing Level 4043 { 4044 strText = "0" + (char)(176) + ":"; 4045 if(modX != null) 4046 strText += modX; 4047 else 4048 strText += "?"; 4049 4050 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4051 labelWidth = Math.round(ti.getTextBounds().width()); 4052 //One modifier symbols and modifier goes in center 4053 x = bounds.left + (int) (bounds.width() * 0.5f); 4054 x = x - (int) (labelWidth * 0.5f); 4055 y = bounds.top + (int) (bounds.height() * 0.5f); 4056 y = y + (int) ((labelHeight - modifierFontDescent) * 0.5f); 4057 4058 ti.setLocation(Math.round(x), Math.round(y)); 4059 arrMods.add(ti); 4060 } 4061 else if(ec == 162200)//tropopause Level 4062 { 4063 strText = "X?"; 4064 if(modX != null) 4065 strText = modX; 4066 4067 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4068 labelWidth = Math.round(ti.getTextBounds().width()); 4069 //One modifier symbols and modifier goes in center 4070 x = bounds.left + (int) (bounds.width() * 0.5f); 4071 x = x - (int) (labelWidth * 0.5f); 4072 y = bounds.top + (int) (bounds.height() * 0.5f); 4073 y = y + (int) ((labelHeight - modifierFontDescent) * 0.5f); 4074 4075 ti.setLocation(Math.round(x), Math.round(y)); 4076 arrMods.add(ti); 4077 } 4078 else if(ec == 110102)//tropopause Low 4079 { 4080 strText = "X?"; 4081 if(modX != null) 4082 strText = modX; 4083 4084 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4085 labelWidth = Math.round(ti.getTextBounds().width()); 4086 //One modifier symbols and modifier goes in center 4087 x = bounds.left + (int) (bounds.width() * 0.5f); 4088 x = x - (int) (labelWidth * 0.5f); 4089 y = bounds.top + (int) (bounds.height() * 0.5f); 4090 y = y - descent; 4091 4092 ti.setLocation(Math.round(x), Math.round(y)); 4093 arrMods.add(ti); 4094 } 4095 else if(ec == 110202)//tropopause High 4096 { 4097 strText = "X?"; 4098 if(modX != null) 4099 strText = modX; 4100 4101 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4102 labelWidth = Math.round(ti.getTextBounds().width()); 4103 //One modifier symbols and modifier goes in center 4104 x = bounds.left + (int) (bounds.width() * 0.5f); 4105 x = x - (int) (labelWidth * 0.5f); 4106 y = bounds.top + (int) (bounds.height() * 0.5f); 4107 //y = y + (int) ((labelHeight * 0.5f) + (labelHeight/2)); 4108 y = y + (int) (((labelHeight * 0.5f) - (labelHeight/2)) + labelHeight - descent); 4109 4110 ti.setLocation(Math.round(x), Math.round(y)); 4111 arrMods.add(ti); 4112 } 4113 } 4114 // </editor-fold> 4115 4116 // <editor-fold defaultstate="collapsed" desc="DOM Arrow"> 4117 Point[] domPoints = null; 4118 Rect domBounds = null; 4119 4120 if (modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT) && 4121 SymbolUtilities.isCBRNEvent(symbolID))//CBRN events 4122 { 4123 strText = modifiers.get(Modifiers.Q_DIRECTION_OF_MOVEMENT); 4124 if(strText != null && SymbolUtilities.isNumber(strText)) 4125 { 4126 float q = Float.parseFloat(strText); 4127 Rect tempBounds = new Rect(bounds); 4128 tempBounds.union(RectUtilities.getCenterX(bounds), yForY); 4129 4130 domPoints = createDOMArrowPoints(symbolID, tempBounds, sdi.getCenterPoint(), q, false, modifierFontHeight); 4131 4132 domBounds = RectUtilities.makeRect(domPoints[0].x, domPoints[0].y, 1, 1); 4133 4134 Point temp = null; 4135 for (int i = 1; i < 6; i++) 4136 { 4137 temp = domPoints[i]; 4138 if (temp != null) 4139 { 4140 domBounds.union(temp.x, temp.y); 4141 } 4142 } 4143 imageBounds.union(domBounds); 4144 } 4145 } 4146 // </editor-fold> 4147 4148 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 4149 if (SymbolUtilities.hasFDI(symbolID)) 4150 { 4151 //create feint indicator /\ 4152 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 4153 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 4154 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f))); 4155 4156 4157 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 4158 fdiBounds.union(fdiTop.x, fdiTop.y); 4159 fdiBounds.union(fdiRight.x, fdiRight.y); 4160 4161 float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4162 RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2)); 4163 4164 ti = new TextInfo("TEST",0,0, modifierFont, modifierFontName); 4165 if (ti != null && SymbolUtilities.isCBRNEvent(symbolID)) 4166 { 4167 int shiftY = Math.round(symbolBounds.top - ti.getTextBounds().height() - 2); 4168 fdiLeft.offset(0, shiftY); 4169 fdiTop.offset(0, shiftY); 4170 fdiRight.offset(0, shiftY); 4171 fdiBounds.offset(0, shiftY); 4172 } 4173 4174 imageBounds.union(fdiBounds); 4175 4176 } 4177 // </editor-fold> 4178 4179 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 4180 Rect modifierBounds = null; 4181 if (arrMods != null && arrMods.size() > 0) 4182 { 4183 4184 //build modifier bounds///////////////////////////////////////// 4185 modifierBounds = arrMods.get(0).getTextOutlineBounds(); 4186 int size = arrMods.size(); 4187 TextInfo tempShape = null; 4188 for (int i = 1; i < size; i++) 4189 { 4190 tempShape = arrMods.get(i); 4191 modifierBounds.union(tempShape.getTextOutlineBounds()); 4192 } 4193 4194 } 4195 4196 if (modifierBounds != null || domBounds != null || fdiBounds != null) 4197 { 4198 4199 if (modifierBounds != null) 4200 { 4201 imageBounds.union(modifierBounds); 4202 } 4203 if (domBounds != null) 4204 { 4205 imageBounds.union(domBounds); 4206 } 4207 if (fdiBounds != null) 4208 { 4209 imageBounds.union(fdiBounds); 4210 } 4211 4212 //shift points if needed//////////////////////////////////////// 4213 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4214 { 4215 int shiftX = Math.abs(imageBounds.left); 4216 int shiftY = Math.abs(imageBounds.top); 4217 4218 //shift mobility points 4219 int size = arrMods.size(); 4220 TextInfo tempShape = null; 4221 for (int i = 0; i < size; i++) 4222 { 4223 tempShape = arrMods.get(i); 4224 tempShape.shift(shiftX, shiftY); 4225 } 4226 if(modifierBounds != null) 4227 modifierBounds.offset(shiftX, shiftY); 4228 4229 if (domBounds != null) 4230 { 4231 for (int i = 0; i < 6; i++) 4232 { 4233 Point temp = domPoints[i]; 4234 if (temp != null) 4235 { 4236 temp.offset(shiftX, shiftY); 4237 } 4238 } 4239 domBounds.offset(shiftX, shiftY); 4240 } 4241 4242 //If there's an FDI 4243 if (fdiBounds != null) 4244 { 4245 fdiBounds.offset(shiftX, shiftY); 4246 fdiLeft.offset(shiftX, shiftY); 4247 fdiTop.offset(shiftX, shiftY); 4248 fdiRight.offset(shiftX, shiftY); 4249 } 4250 4251 //shift image points 4252 centerPoint.offset(shiftX, shiftY); 4253 symbolBounds.offset(shiftX, shiftY); 4254 imageBounds.offset(shiftX, shiftY); 4255 } 4256 4257 4258 if (attributes.containsKey(MilStdAttributes.TextColor)) 4259 { 4260 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4261 if(alpha > -1) 4262 textColor.setAlpha(alpha); 4263 } 4264 if (attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4265 { 4266 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4267 if(alpha > -1) 4268 textBackgroundColor.setAlpha(alpha); 4269 } 4270 4271 if(sdi instanceof ImageInfo) { 4272 ii = (ImageInfo)sdi; 4273 //Render modifiers////////////////////////////////////////////////// 4274 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 4275 Canvas ctx = new Canvas(bmp); 4276 4277 //render//////////////////////////////////////////////////////// 4278 //draw original icon with potential modifiers. 4279 ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null); 4280 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 4281 4282 4283 renderText(ctx, arrMods, textColor, textBackgroundColor, modifierFont); 4284 4285 //draw DOM arrow 4286 if (domBounds != null) 4287 { 4288 drawDOMArrow(ctx, domPoints, alpha, lineColor); 4289 } 4290 4291 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4292 if (fdiBounds != null) { 4293 4294 Paint fdiPaint = new Paint(); 4295 fdiPaint.setAntiAlias(true); 4296 fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 4297 if (alpha > -1) 4298 fdiPaint.setAlpha(alpha); 4299 fdiPaint.setStyle(Style.STROKE); 4300 4301 int dpi = RendererSettings.getInstance().getDeviceDPI(); 4302 int lineLength = dpi / 96 * 6; 4303 int lineGap = dpi / 96 * 4; 4304 4305 /// /////////////////////////////////// 4306 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4307 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4308 //distance = distance / 14f; 4309 lineGap = (int)((distance / 14f) * 2); 4310 lineLength = (int)((distance / 14f) * 3); 4311 /// ////////////////////////////////// 4312 4313 fdiPaint.setPathEffect(new DashPathEffect(new float[] 4314 { 4315 lineLength, lineGap 4316 }, 0)); 4317 4318 float fdiStrokeWidth = Math.round(dpi / 96f); 4319 if (fdiStrokeWidth < 2) 4320 fdiStrokeWidth = 2; 4321 4322 fdiPaint.setStrokeCap(Cap.ROUND); 4323 fdiPaint.setStrokeJoin(Join.MITER); 4324 fdiPaint.setStrokeWidth(fdiStrokeWidth); 4325 4326 Path fdiPath = new Path(); 4327 4328 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4329 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4330 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4331 fdiPath.lineTo(fdiRight.x, fdiRight.y); 4332 ctx.drawPath(fdiPath, fdiPaint); 4333 4334 fdiBounds = null; 4335 4336 } 4337 //</editor-fold> 4338 4339 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 4340 ctx = null; 4341 } 4342 else if(sdi instanceof SVGSymbolInfo) 4343 { 4344 float strokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4345 if(strokeWidth < 1) 4346 strokeWidth=1; 4347 String svgStroke = RendererUtilities.colorToHexString(lineColor,false); 4348 String svgStrokeWidth = String.valueOf(strokeWidth);//"3"; 4349 4350 ssi = (SVGSymbolInfo)sdi; 4351 StringBuilder sbSVG = new StringBuilder(); 4352 sbSVG.append(ssi.getSVG()); 4353 sbSVG.append(renderTextElements(arrMods,textColor,textBackgroundColor)); 4354 4355 // <editor-fold defaultstate="collapsed" desc="DOM arrow"> 4356 if (domBounds != null && domPoints.length == 6) 4357 { 4358 SVGPath domPath = new SVGPath() ; 4359 4360 domPath.moveTo(domPoints[0].x, domPoints[0].y); 4361 if (domPoints[1] != null) 4362 { 4363 domPath.lineTo(domPoints[1].x, domPoints[1].y); 4364 } 4365 if (domPoints[2] != null) 4366 { 4367 domPath.lineTo(domPoints[2].x, domPoints[2].y); 4368 } 4369 sbSVG.append(domPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,null)); 4370 4371 domPath = new SVGPath(); 4372 4373 domPath.moveTo(domPoints[3].x, domPoints[3].y); 4374 domPath.lineTo(domPoints[4].x, domPoints[4].y); 4375 domPath.lineTo(domPoints[5].x, domPoints[5].y); 4376 sbSVG.append(domPath.toSVGElement(null,0f,svgStroke,1f,1f,null)); 4377 4378 domBounds = null; 4379 domPoints = null; 4380 } 4381 // </editor-fold> 4382 4383 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4384 if (fdiBounds != null) 4385 { 4386 4387 /*int dpi = RendererSettings.getInstance().getDeviceDPI(); 4388 int lineLength = dpi / 96 * 6; 4389 int lineGap = dpi / 96 * 4; 4390 String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/ 4391 4392 /// /////////////////////////////////// 4393 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4394 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4395 //distance = distance / 14f; 4396 int lineGap = (int)((distance / 14f) * 2); 4397 int lineLength = (int)((distance / 14f) * 3); 4398 String svgFDIDashArray = "" + lineLength + " " + lineGap; 4399 /// ////////////////////////////////// 4400 4401 SVGPath fdiPath = new SVGPath(); 4402 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4403 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4404 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4405 fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/ 4406 4407 fdiPath.setLineDash(svgFDIDashArray); 4408 4409 sbSVG.append(fdiPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,"round")); 4410 //sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray)); 4411 } 4412 //</editor-fold> 4413 4414 newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds); 4415 } 4416 4417 4418 4419 4420 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 4421 //ctx = null; 4422 // </editor-fold> 4423 4424 return newsdi; 4425 4426 } 4427 else 4428 { 4429 return null; 4430 } 4431 // </editor-fold> 4432 4433 } 4434 4435 /** 4436 * Process modifiers for action points 4437 */ 4438 public static SymbolDimensionInfo ProcessTGSPModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes, Color lineColor) 4439 { 4440 4441 Paint modifierFont = getFont(attributes); 4442 float[] hd = getFontHeightandDescent(modifierFont); 4443 float modifierFontHeight = hd[0]; 4444 float modifierFontDescent = hd[1]; 4445 4446 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 4447 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 4448 { 4449 String temp = attributes.get(MilStdAttributes.FontFamily); 4450 if(temp != null && !temp.isEmpty()) 4451 modifierFontName = temp; 4452 } 4453 4454 // <editor-fold defaultstate="collapsed" desc="Variables"> 4455 ImageInfo ii = null; 4456 SVGSymbolInfo ssi = null; 4457 4458 int bufferXL = 6; 4459 int bufferXR = 4; 4460 int bufferY = 2; 4461 int bufferText = 2; 4462 int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel 4463 int x = 0; 4464 int y = 0; 4465 int x2 = 0; 4466 int y2 = 0; 4467 4468 //Feint Dummy Indicator variables 4469 Rect fdiBounds = null; 4470 Point fdiTop = null; 4471 Point fdiLeft = null; 4472 Point fdiRight = null; 4473 4474 int outlineOffset = RS.getTextOutlineWidth(); 4475 int labelHeight = 0; 4476 int labelWidth = 0; 4477 int alpha = -1; 4478 SymbolDimensionInfo newsdi = null; 4479 4480 Color textColor = lineColor; 4481 Color textBackgroundColor = null; 4482 4483 ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>(); 4484 boolean duplicate = false; 4485 4486 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 4487 4488 4489 if (attributes.containsKey(MilStdAttributes.Alpha)) 4490 { 4491 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 4492 } 4493 4494 Rect bounds = new Rect(sdi.getSymbolBounds()); 4495 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 4496 Point centerPoint = new Point(sdi.getCenterPoint()); 4497 Rect imageBounds = new Rect(sdi.getImageBounds()); 4498 4499 centerPoint = new Point(Math.round(sdi.getCenterPoint().x), Math.round(sdi.getCenterPoint().y)); 4500 4501 boolean byLabelHeight = false; 4502 4503 labelHeight = Math.round(modifierFontHeight + 0.5f); 4504 int maxHeight = (symbolBounds.height()); 4505 if ((labelHeight * 3) > maxHeight) 4506 { 4507 byLabelHeight = true; 4508 } 4509 4510 int descent = (int) (modifierFontDescent + 0.5f); 4511 int yForY = -1; 4512 4513 Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0); 4514 Rect labelBounds2 = null; 4515 String strText = ""; 4516 String strText1 = ""; 4517 String strText2 = ""; 4518 TextInfo text1 = null; 4519 TextInfo text2 = null; 4520 4521 String basicID = SymbolUtilities.getBasicSymbolID(symbolID); 4522 4523 if (outlineOffset > 2) 4524 { 4525 outlineOffset = ((outlineOffset - 1) / 2); 4526 } 4527 else 4528 { 4529 outlineOffset = 0; 4530 } 4531 4532 /*bufferXL += outlineOffset; 4533 bufferXR += outlineOffset; 4534 bufferY += outlineOffset; 4535 bufferText += outlineOffset;*/ 4536 // </editor-fold> 4537 // <editor-fold defaultstate="collapsed" desc="Process Modifiers"> 4538 TextInfo ti = null; 4539 4540 { 4541 if (msi.getModifiers().contains(Modifiers.N_HOSTILE) && modifiers.containsKey(Modifiers.N_HOSTILE)) 4542 { 4543 strText = modifiers.get(Modifiers.N_HOSTILE); 4544 if(strText != null) 4545 { 4546 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4547 4548 x = bounds.left + bounds.width() + bufferXR; 4549 4550 if (!byLabelHeight) 4551 { 4552 y = ((bounds.height() / 3) * 2);//checkpoint, get box above the point 4553 y = bounds.top + y; 4554 } 4555 else 4556 { 4557 //y = ((labelHeight + bufferText) * 3); 4558 //y = bounds.y + y - descent; 4559 y = bounds.top + bounds.height(); 4560 } 4561 4562 ti.setLocation(x, y); 4563 arrMods.add(ti); 4564 } 4565 4566 } 4567 if (msi.getModifiers().contains(Modifiers.H_ADDITIONAL_INFO_1) && modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 4568 { 4569 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 4570 if(strText != null) 4571 { 4572 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4573 labelWidth = Math.round(ti.getTextBounds().width()); 4574 4575 x = bounds.left + (int) (bounds.width() * 0.5f); 4576 x = x - (int) (labelWidth * 0.5f); 4577 y = bounds.top - descent; 4578 4579 ti.setLocation(x, y); 4580 arrMods.add(ti); 4581 } 4582 } 4583 if (msi.getModifiers().contains(Modifiers.H1_ADDITIONAL_INFO_2) && modifiers.containsKey(Modifiers.H1_ADDITIONAL_INFO_2)) 4584 { 4585 strText = modifiers.get(Modifiers.H1_ADDITIONAL_INFO_2); 4586 if(strText != null) 4587 { 4588 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4589 labelWidth = Math.round(ti.getTextBounds().width()); 4590 4591 x = bounds.left + (int) (bounds.width() * 0.5); 4592 x = x - (int) (labelWidth * 0.5); 4593 y = bounds.top + labelHeight - descent + (int) (bounds.height() * 0.07); 4594 4595 ti.setLocation(x, y); 4596 arrMods.add(ti); 4597 } 4598 } 4599 if (msi.getModifiers().contains(Modifiers.A_SYMBOL_ICON)) 4600 { 4601 if(modifiers.containsKey(Modifiers.A_SYMBOL_ICON)) 4602 strText = modifiers.get(Modifiers.A_SYMBOL_ICON); 4603 else if(SymbolID.getEntityCode(symbolID)==321706)//NATO Multiple Supply Class Point 4604 strText = "ALL?";//make it clear the required 'A' value wasn't set for this symbol. 4605 4606 if(strText != null) 4607 { 4608 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4609 labelWidth = Math.round(ti.getTextBounds().width()); 4610 4611 x = bounds.left + (int) (bounds.width() * 0.5); 4612 x = x - (int) (labelWidth * 0.5); 4613 y = bounds.top + labelHeight - descent + (int) (bounds.height() * 0.07); 4614 4615 ti.setLocation(x, y); 4616 arrMods.add(ti); 4617 } 4618 } 4619 if (msi.getModifiers().contains(Modifiers.W_DTG_1) && modifiers.containsKey(Modifiers.W_DTG_1)) 4620 { 4621 strText = modifiers.get(Modifiers.W_DTG_1); 4622 if(strText != null) 4623 { 4624 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4625 labelWidth = Math.round(ti.getTextBounds().width()); 4626 4627 x = bounds.left - labelWidth - bufferXL; 4628 y = bounds.top + labelHeight - descent; 4629 4630 ti.setLocation(x, y); 4631 arrMods.add(ti); 4632 } 4633 } 4634 if (msi.getModifiers().contains(Modifiers.W1_DTG_2) && modifiers.containsKey(Modifiers.W1_DTG_2)) 4635 { 4636 strText = modifiers.get(Modifiers.W1_DTG_2); 4637 if(strText != null) 4638 { 4639 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4640 labelWidth = Math.round(ti.getTextBounds().width()); 4641 4642 x = bounds.left - labelWidth - bufferXL; 4643 4644 y = ((labelHeight - descent + bufferText) * 2); 4645 y = bounds.top + y; 4646 4647 ti.setLocation(x, y); 4648 arrMods.add(ti); 4649 } 4650 } 4651 if (msi.getModifiers().contains(Modifiers.T_UNIQUE_DESIGNATION_1) && modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 4652 { 4653 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 4654 if(strText != null) 4655 { 4656 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4657 4658 x = bounds.left + bounds.width() + bufferXR; 4659 y = bounds.top + labelHeight - descent; 4660 4661 ti.setLocation(x, y); 4662 arrMods.add(ti); 4663 } 4664 } 4665 if (msi.getModifiers().contains(Modifiers.T1_UNIQUE_DESIGNATION_2) && modifiers.containsKey(Modifiers.T1_UNIQUE_DESIGNATION_2)) 4666 { 4667 strText = modifiers.get(Modifiers.T1_UNIQUE_DESIGNATION_2); 4668 if(strText != null) 4669 { 4670 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4671 labelWidth = Math.round(ti.getTextBounds().width()); 4672 4673 //points 4674 x = bounds.left + (int) (bounds.width() * 0.5); 4675 x = x - (int) (labelWidth * 0.5); 4676 //y = bounds.y + (bounds.height * 0.5); 4677 4678 y = (int) ((bounds.height() * 0.55));//633333333 4679 y = bounds.top + y; 4680 4681 int ec = SymbolID.getEntityCode(symbolID); 4682 if((ec >= 281800 && ec <= 281809) || ec == 321100) 4683 { 4684 y = (int) ((bounds.height() * 0.63)); 4685 y = (int)bounds.top + y; 4686 } 4687 4688 ti.setLocation(x, y); 4689 arrMods.add(ti); 4690 } 4691 } 4692 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 4693 if (SymbolUtilities.hasFDI(symbolID)) 4694 { 4695 //create feint indicator /\ 4696 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 4697 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 4698 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f))); 4699 4700 4701 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 4702 fdiBounds.union(fdiTop.x, fdiTop.y); 4703 fdiBounds.union(fdiRight.x, fdiRight.y); 4704 4705 float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4706 RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2)); 4707 4708 ti = new TextInfo("TEST",0,0, modifierFont, modifierFontName); 4709 if (ti != null) 4710 { 4711 int shiftY = Math.round(symbolBounds.top - ti.getTextBounds().height() - 2); 4712 fdiLeft.offset(0, shiftY); 4713 fdiTop.offset(0, shiftY); 4714 fdiRight.offset(0, shiftY); 4715 fdiBounds.offset(0, shiftY); 4716 } 4717 4718 imageBounds.union(fdiBounds); 4719 4720 } 4721 // </editor-fold> 4722 } 4723 4724 // </editor-fold> 4725 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 4726 Rect modifierBounds = null; 4727 if (arrMods != null && arrMods.size() > 0) 4728 { 4729 4730 //build modifier bounds///////////////////////////////////////// 4731 modifierBounds = arrMods.get(0).getTextOutlineBounds(); 4732 int size = arrMods.size(); 4733 TextInfo tempShape = null; 4734 for (int i = 1; i < size; i++) 4735 { 4736 tempShape = arrMods.get(i); 4737 modifierBounds.union(tempShape.getTextOutlineBounds()); 4738 } 4739 4740 } 4741 4742 if(fdiBounds != null) 4743 { 4744 if(modifierBounds != null) 4745 modifierBounds.union(fdiBounds); 4746 else 4747 modifierBounds = fdiBounds; 4748 } 4749 4750 if (modifierBounds != null) 4751 { 4752 4753 imageBounds.union(modifierBounds); 4754 4755 //shift points if needed//////////////////////////////////////// 4756 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4757 { 4758 int shiftX = Math.abs(imageBounds.left); 4759 int shiftY = Math.abs(imageBounds.top); 4760 4761 //shift mobility points 4762 int size = arrMods.size(); 4763 TextInfo tempShape = null; 4764 for (int i = 0; i < size; i++) 4765 { 4766 tempShape = arrMods.get(i); 4767 tempShape.shift(shiftX, shiftY); 4768 } 4769 modifierBounds.offset(shiftX, shiftY); 4770 4771 //shift image points 4772 centerPoint.offset(shiftX, shiftY); 4773 symbolBounds.offset(shiftX, shiftY); 4774 imageBounds.offset(shiftX, shiftY); 4775 4776 //If there's an FDI 4777 if (fdiBounds != null) 4778 { 4779 fdiBounds.offset(shiftX, shiftY); 4780 fdiLeft.offset(shiftX, shiftY); 4781 fdiTop.offset(shiftX, shiftY); 4782 fdiRight.offset(shiftX, shiftY); 4783 } 4784 } 4785 4786 if (attributes.containsKey(MilStdAttributes.TextColor)) 4787 { 4788 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4789 if(alpha > -1) 4790 textColor.setAlpha(alpha); 4791 } 4792 if (attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4793 { 4794 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4795 if(alpha > -1) 4796 textBackgroundColor.setAlpha(alpha); 4797 } 4798 4799 if(sdi instanceof ImageInfo) 4800 { 4801 ii = (ImageInfo) sdi; 4802 //Render modifiers////////////////////////////////////////////////// 4803 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 4804 Canvas ctx = new Canvas(bmp); 4805 4806 //draw original icon with potential modifiers. 4807 ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null); 4808 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 4809 4810 4811 renderText(ctx, arrMods, textColor, textBackgroundColor, modifierFont); 4812 4813 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4814 if (fdiBounds != null) { 4815 4816 Paint fdiPaint = new Paint(); 4817 fdiPaint.setAntiAlias(true); 4818 fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 4819 if (alpha > -1) 4820 fdiPaint.setAlpha(alpha); 4821 fdiPaint.setStyle(Style.STROKE); 4822 4823 int dpi = RendererSettings.getInstance().getDeviceDPI(); 4824 int lineLength = dpi / 96 * 6; 4825 int lineGap = dpi / 96 * 4; 4826 4827 /// /////////////////////////////////// 4828 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4829 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4830 //distance = distance / 14f; 4831 lineGap = (int)((distance / 14f) * 2); 4832 lineLength = (int)((distance / 14f) * 3); 4833 /// ////////////////////////////////// 4834 4835 fdiPaint.setPathEffect(new DashPathEffect(new float[] 4836 { 4837 lineLength, lineGap 4838 }, 0)); 4839 4840 float fdiStrokeWidth = Math.round(dpi / 96f); 4841 if (fdiStrokeWidth < 2) 4842 fdiStrokeWidth = 2; 4843 4844 fdiPaint.setStrokeCap(Cap.ROUND); 4845 fdiPaint.setStrokeJoin(Join.MITER); 4846 fdiPaint.setStrokeWidth(fdiStrokeWidth); 4847 4848 Path fdiPath = new Path(); 4849 4850 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4851 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4852 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4853 fdiPath.lineTo(fdiRight.x, fdiRight.y); 4854 ctx.drawPath(fdiPath, fdiPaint); 4855 4856 fdiBounds = null; 4857 4858 } 4859 //</editor-fold> 4860 4861 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 4862 } 4863 else if(sdi instanceof SVGSymbolInfo) 4864 { 4865 String svgStroke = RendererUtilities.colorToHexString(lineColor,false); 4866 String svgStrokeWidth = "3"; 4867 String svgAlpha = null; 4868 if(alpha > -1) 4869 svgAlpha = String.valueOf(alpha); 4870 ssi = (SVGSymbolInfo)sdi; 4871 StringBuilder sbSVG = new StringBuilder(); 4872 sbSVG.append(ssi.getSVG()); 4873 sbSVG.append(renderTextElements(arrMods,textColor,textBackgroundColor)); 4874 4875 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4876 if (fdiBounds != null) 4877 { 4878 /*int dpi = RendererSettings.getInstance().getDeviceDPI(); 4879 int lineLength = dpi / 96 * 6; 4880 int lineGap = dpi / 96 * 4; 4881 String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/ 4882 4883 /// /////////////////////////////////// 4884 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4885 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4886 //distance = distance / 14f; 4887 int lineGap = (int)((distance / 14f) * 2); 4888 int lineLength = (int)((distance / 14f) * 3); 4889 String svgFDIDashArray = "" + lineLength + " " + lineGap; 4890 /// ////////////////////////////////// 4891 4892 SVGPath fdiPath = new SVGPath(); 4893 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4894 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4895 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4896 fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/ 4897 4898 fdiPath.setLineDash(svgFDIDashArray); 4899 sbSVG.append(fdiPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,"round")); 4900 //sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray)); 4901 } 4902 //</editor-fold> 4903 4904 newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds); 4905 } 4906 4907 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 4908 //ctx = null; 4909 4910 // </editor-fold> 4911 } 4912 // </editor-fold> 4913 return newsdi; 4914 4915 } 4916 4917 private static SymbolDimensionInfo shiftUnitPointsAndDraw(ArrayList<TextInfo> tiArray, SymbolDimensionInfo sdi, Map<String,String> attributes, Paint modifierFont) 4918 { 4919 4920 ImageInfo ii = null; 4921 SVGSymbolInfo ssi = null; 4922 SymbolDimensionInfo newsdi = null; 4923 4924 int alpha = -1; 4925 4926 4927 if (attributes != null && attributes.containsKey(MilStdAttributes.Alpha)) 4928 { 4929 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 4930 } 4931 4932 Color textColor = Color.BLACK; 4933 Color textBackgroundColor = null; 4934 4935 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 4936 Point centerPoint = new Point(sdi.getCenterPoint()); 4937 Rect imageBounds = new Rect(sdi.getImageBounds()); 4938 Rect imageBoundsOld = new Rect(sdi.getImageBounds()); 4939 4940 Rect modifierBounds = null; 4941 if (tiArray != null && tiArray.size() > 0) 4942 { 4943 4944 //build modifier bounds///////////////////////////////////////// 4945 modifierBounds = tiArray.get(0).getTextOutlineBounds(); 4946 int size = tiArray.size(); 4947 TextInfo tempShape = null; 4948 for (int i = 1; i < size; i++) 4949 { 4950 tempShape = tiArray.get(i); 4951 modifierBounds.union(tempShape.getTextOutlineBounds()); 4952 } 4953 4954 } 4955 4956 if (modifierBounds != null) 4957 { 4958 4959 imageBounds.union(modifierBounds); 4960 4961 //shift points if needed//////////////////////////////////////// 4962 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4963 { 4964 int shiftX = Math.round(Math.abs(imageBounds.left)), 4965 shiftY = Math.round(Math.abs(imageBounds.top)); 4966 4967 //shift mobility points 4968 int size = tiArray.size(); 4969 TextInfo tempShape = null; 4970 for (int i = 0; i < size; i++) 4971 { 4972 tempShape = tiArray.get(i); 4973 tempShape.shift(shiftX, shiftY); 4974 } 4975 RectUtilities.shift(modifierBounds, shiftX, shiftY); 4976 //modifierBounds.shift(shiftX,shiftY); 4977 4978 //shift image points 4979 centerPoint.offset(shiftX, shiftY); 4980 RectUtilities.shift(symbolBounds, shiftX, shiftY); 4981 RectUtilities.shift(imageBounds, shiftX, shiftY); 4982 RectUtilities.shift(imageBoundsOld, shiftX, shiftY); 4983 /*centerPoint.shift(shiftX, shiftY); 4984 symbolBounds.shift(shiftX, shiftY); 4985 imageBounds.shift(shiftX, shiftY); 4986 imageBoundsOld.shift(shiftX, shiftY);//*/ 4987 } 4988 4989 if (attributes != null && attributes.containsKey(MilStdAttributes.TextColor)) 4990 { 4991 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4992 if(alpha > -1) 4993 textColor.setAlpha(alpha); 4994 } 4995 if (attributes != null && attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4996 { 4997 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4998 if(alpha > -1) 4999 textBackgroundColor.setAlpha(alpha); 5000 } 5001 5002 if(sdi instanceof ImageInfo) 5003 { 5004 ii = (ImageInfo) sdi; 5005 5006 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 5007 Canvas ctx = new Canvas(bmp); 5008 5009 //render//////////////////////////////////////////////////////// 5010 //draw original icon with potential modifiers. 5011 ctx.drawBitmap(ii.getImage(), imageBoundsOld.left, imageBoundsOld.top, null); 5012 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 5013 5014 renderText(ctx, tiArray, textColor, textBackgroundColor, modifierFont); 5015 5016 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 5017 } 5018 else if(sdi instanceof SVGSymbolInfo) 5019 { 5020 ssi = (SVGSymbolInfo)sdi; 5021 StringBuilder sb = new StringBuilder(); 5022 sb.append(ssi.getSVG()); 5023 sb.append(renderTextElements(tiArray,textColor,textBackgroundColor)); 5024 newsdi = new SVGSymbolInfo(sb.toString(),centerPoint,symbolBounds,imageBounds); 5025 } 5026 } 5027 5028 if(newsdi == null) 5029 newsdi = sdi; 5030 5031 return newsdi; 5032 } 5033 private static String renderTextElement(ArrayList<TextInfo> tiArray, Color color, Color backgroundColor) 5034 { 5035 StringBuilder sbSVG = new StringBuilder(); 5036 5037 String svgStroke = RendererUtilities.colorToHexString(RendererUtilities.getIdealOutlineColor(color),false); 5038 if(backgroundColor != null) 5039 svgStroke = RendererUtilities.colorToHexString(backgroundColor,false); 5040 5041 String svgFill = RendererUtilities.colorToHexString(color,false); 5042 String svgStrokeWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth()); 5043 for (TextInfo ti : tiArray) { 5044 sbSVG.append(Shape2SVG.Convert(ti, svgStroke,svgFill,svgStrokeWidth,null,null,null)); 5045 sbSVG.append("\n"); 5046 } 5047 5048 return sbSVG.toString(); 5049 } 5050 5051 private static String renderTextElements(ArrayList<TextInfo> tiArray, Color color, Color backgroundColor) 5052 { 5053 String style = null; 5054 String name = tiArray.get(0).getFontName();//"SansSerif"; 5055 if(!name.endsWith("serif")) 5056 name += ", sans-serif"; 5057 String size = String.valueOf(tiArray.get(0).getFontSize()); 5058 String weight = null; 5059 String anchor = null;//"start"; 5060 if(tiArray.get(0).getFontStyle() == Typeface.BOLD) 5061 weight = "bold"; 5062 StringBuilder sbSVG = new StringBuilder(); 5063 5064 String svgStroke = RendererUtilities.colorToHexString(RendererUtilities.getIdealOutlineColor(color),false); 5065 if(backgroundColor != null) 5066 svgStroke = RendererUtilities.colorToHexString(backgroundColor,false); 5067 5068 String svgFill = RendererUtilities.colorToHexString(color,false); 5069 String svgStrokeWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth()); 5070 sbSVG.append("\n<g"); 5071 sbSVG.append(" font-family=\"").append(name).append('"'); 5072 sbSVG.append(" font-size=\"").append(size).append("px\""); 5073 if(weight != null) 5074 sbSVG.append(" font-weight=\"").append(weight).append("\""); 5075 sbSVG.append(" alignment-baseline=\"alphabetic\"");// 5076 sbSVG.append(">"); 5077 5078 for (TextInfo ti : tiArray) { 5079 sbSVG.append(Shape2SVG.ConvertForGroup(ti, svgStroke,svgFill,svgStrokeWidth,null,null,null)); 5080 sbSVG.append("\n"); 5081 } 5082 sbSVG.append("</g>\n"); 5083 5084 return sbSVG.toString(); 5085 } 5086 private static void renderText(Canvas ctx, ArrayList<TextInfo> tiArray, Color color, Color backgroundColor, Paint font) 5087 { 5088 ModifierRenderer.renderText(ctx, (TextInfo[]) tiArray.toArray(new TextInfo[0]), color, backgroundColor, font); 5089 } 5090 5091 /** 5092 * 5093 * @param ctx 5094 * @param tiArray 5095 * @param color 5096 * @param backgroundColor 5097 */ 5098 public static void renderText(Canvas ctx, TextInfo[] tiArray, Color color, Color backgroundColor, Paint modifierFont) 5099 { 5100 /*for (TextInfo textInfo : tiArray) 5101 { 5102 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5103 }*/ 5104 5105 int size = tiArray.length; 5106 5107 int tbm = RS.getTextBackgroundMethod(); 5108 int outlineWidth = RS.getTextOutlineWidth(); 5109 5110 if (color == null) 5111 { 5112 color = Color.BLACK; 5113 } 5114 5115 Color outlineColor = null; 5116 5117 if(backgroundColor != null) 5118 outlineColor = backgroundColor; 5119 else 5120 outlineColor = RendererUtilities.getIdealOutlineColor(color); 5121 5122 if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE_QUICK) 5123 { 5124 synchronized (modifierFontMutex) { 5125 //draw text outline 5126 modifierFont.setStyle(Style.FILL); 5127 modifierFont.setStrokeWidth(RS.getTextOutlineWidth()); 5128 modifierFont.setColor(outlineColor.toInt()); 5129 5130 if (outlineWidth > 2) 5131 outlineWidth = 2; 5132 5133 if (outlineWidth > 0) { 5134 for (int i = 0; i < size; i++) { 5135 TextInfo textInfo = tiArray[i]; 5136 if (outlineWidth > 0) { 5137 for (int j = 1; j <= outlineWidth; j++) { 5138 if (j == 1) { 5139 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, modifierFont); 5140 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, modifierFont); 5141 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, modifierFont); 5142 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, modifierFont); 5143 5144 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, modifierFont); 5145 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, modifierFont); 5146 5147 } else { 5148 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, modifierFont); 5149 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, modifierFont); 5150 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, modifierFont); 5151 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, modifierFont); 5152 5153 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, modifierFont); 5154 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, modifierFont); 5155 5156 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y + j, modifierFont); 5157 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y - j, modifierFont); 5158 } 5159 5160 } 5161 5162 } 5163 5164 } 5165 } 5166 //draw text 5167 modifierFont.setColor(color.toInt()); 5168 5169 for (int j = 0; j < size; j++) { 5170 TextInfo textInfo = tiArray[j]; 5171 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5172 /*Paint outline = new Paint(); 5173 outline.setStyle(Style.STROKE); 5174 outline.setColor(Color.red.toInt()); 5175 outline.setAlpha(155); 5176 outline.setStrokeWidth(1f); 5177 ctx.drawRect(textInfo.getTextBounds(), outline); 5178 outline.setColor(Color.blue.toInt()); 5179 ctx.drawRect(textInfo.getTextOutlineBounds(), outline);//*/ 5180 } 5181 } 5182 } 5183 else if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE) 5184 { 5185 synchronized (modifierFontMutex) { 5186 //draw text outline 5187 //draw text outline 5188 modifierFont.setStyle(Style.STROKE); 5189 modifierFont.setStrokeWidth(RS.getTextOutlineWidth()); 5190 modifierFont.setColor(outlineColor.toInt()); 5191 if (outlineWidth > 0) { 5192 for (int i = 0; i < size; i++) { 5193 TextInfo textInfo = tiArray[i]; 5194 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5195 } 5196 } 5197 //draw text 5198 modifierFont.setColor(color.toInt()); 5199 modifierFont.setStyle(Style.FILL); 5200 for (int j = 0; j < size; j++) { 5201 TextInfo textInfo = tiArray[j]; 5202 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5203 } 5204 } 5205 } 5206 else if (tbm == RendererSettings.TextBackgroundMethod_COLORFILL) 5207 { 5208 synchronized (modifierFontMutex) { 5209 Paint rectFill = new Paint(); 5210 rectFill.setStyle(Paint.Style.FILL); 5211 rectFill.setColor(outlineColor.toARGB()); 5212 5213 5214 //draw rectangle 5215 for (int k = 0; k < size; k++) { 5216 TextInfo textInfo = tiArray[k]; 5217 ctx.drawRect(textInfo.getTextOutlineBounds(), rectFill); 5218 } 5219 //draw text 5220 modifierFont.setColor(color.toInt()); 5221 modifierFont.setStyle(Style.FILL); 5222 for (int j = 0; j < size; j++) { 5223 TextInfo textInfo = tiArray[j]; 5224 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5225 } 5226 } 5227 } 5228 else if (tbm == RendererSettings.TextBackgroundMethod_NONE) 5229 { 5230 synchronized (modifierFontMutex) { 5231 modifierFont.setColor(color.toInt()); 5232 modifierFont.setStyle(Style.FILL); 5233 for (int j = 0; j < size; j++) { 5234 TextInfo textInfo = tiArray[j]; 5235 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5236 } 5237 } 5238 } 5239 } 5240 5241 /** 5242 * 5243 * @param symbolID 5244 * @param modifiers 5245 * @return int[] where {xposition (-1 left, 0 centered, 1 right), yposition (0 centered, 1+ goes up, 1- goes down), 5246 * centered (0-no, 1-yes)} -999 means passed modifier is not supported by this symbol 5247 */ 5248 private static List<Modifier> getLabelPositionIndexes(String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 5249 { 5250 List<Modifier> mods = null; 5251 if(modifiers != null && !modifiers.isEmpty()) 5252 mods = new ArrayList<>(); 5253 else 5254 return null; 5255 5256 int ver = SymbolID.getVersion(symbolID); 5257 int ss = SymbolID.getSymbolSet(symbolID); 5258 int x = 0; 5259 int y = 0; 5260 boolean centered = true; 5261 int p = RendererSettings.getInstance().getSPModifierPlacement(); 5262 boolean strict = (RendererSettings.getInstance().getSPModifierPlacement() == RendererSettings.ModifierPlacement_STRICT); 5263 if(attributes != null && attributes.containsKey(MilStdAttributes.ModifierPlacement)) 5264 { 5265 String mp = attributes.get(MilStdAttributes.ModifierPlacement); 5266 if(mp.equals("0") || mp.equals("1") || mp.equals("2")) 5267 { 5268 p = Integer.parseInt(mp); 5269 if(p == 0) 5270 strict = true; 5271 else 5272 strict = false; 5273 } 5274 } 5275 String temp = null; 5276 String sep = " "; 5277 5278 5279 if(ver == SymbolID.Version_2525Dch1) 5280 { 5281 if(ss == SymbolID.SymbolSet_LandUnit || 5282 ss == SymbolID.SymbolSet_LandCivilianUnit_Organization) 5283 { 5284 5285 //Only Command & Control has AA; ec.equals("110000"). Always in the middle of the unit. 5286 if(modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ)) 5287 { 5288 temp = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ); 5289 if(temp != null && !temp.isEmpty()) 5290 mods.add(new Modifier("AA", temp, 0, 0, true)); 5291 } 5292 5293 //Do top center label 5294 x = 0;//centered 5295 y = 9;//on top of symbol 5296 if(modifiers.containsKey(Modifiers.B_ECHELON)) 5297 { 5298 temp = modifiers.get(Modifiers.B_ECHELON); 5299 if(temp != null && !temp.isEmpty()) 5300 mods.add(new Modifier("B", temp, x, y, centered)); 5301 } 5302 5303 //Do right side labels 5304 x = 1;//on right 5305 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5306 { 5307 y = 0;//center 5308 centered = true;//vertically centered, only matters for labels on left and right side 5309 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5310 if(temp != null && !temp.isEmpty()) 5311 mods.add(new Modifier("H", temp, x, y, centered)); 5312 } 5313 else if(!strict) 5314 { 5315 //if no "H', bring G and M closer to the center 5316 centered = false; 5317 } 5318 5319 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5320 { 5321 y = 1;//above center 5322 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5323 if(temp != null && !temp.isEmpty()) 5324 mods.add(new Modifier("G", temp, x, y, centered)); 5325 } 5326 5327 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 5328 { 5329 y = 2; 5330 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5331 y--; 5332 temp = ""; 5333 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 5334 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 5335 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5336 temp += modifiers.get(Modifiers.AS_COUNTRY); 5337 temp = temp.trim(); 5338 if(temp != null && !temp.isEmpty()) 5339 mods.add(new Modifier("F AS", temp, x, y, centered)); 5340 } 5341 5342 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 5343 { 5344 y = -1;//below center 5345 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 5346 if(temp != null && !temp.isEmpty()) 5347 mods.add(new Modifier("M", temp, x, y, centered)); 5348 } 5349 5350 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5351 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 5352 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5353 { 5354 y = -2; 5355 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 5356 y++; 5357 temp = ""; 5358 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5359 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5360 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 5361 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 5362 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5363 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5364 temp = temp.trim(); 5365 if(temp != null && !temp.isEmpty()) 5366 mods.add(new Modifier("J K P", temp, x, y, centered)); 5367 } 5368 5369 //Do left side labels 5370 x = -1;//on left 5371 centered = false; 5372 5373 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5374 { 5375 y = 1; 5376 temp = ""; 5377 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5378 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5379 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5380 temp += modifiers.get(Modifiers.Y_LOCATION); 5381 5382 temp = temp.trim(); 5383 if(temp != null && !temp.isEmpty()) 5384 mods.add(new Modifier("X Y", temp, x, y, centered)); 5385 } 5386 5387 if(modifiers.containsKey(Modifiers.W_DTG_1)) 5388 { 5389 y = 2;//above center 5390 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 5391 y--; 5392 temp = modifiers.get(Modifiers.W_DTG_1); 5393 if(temp != null && !temp.isEmpty()) 5394 mods.add(new Modifier("W", temp, x, y, centered)); 5395 } 5396 5397 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5398 { 5399 y = -1;//below center 5400 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5401 if(temp != null && !temp.isEmpty()) 5402 mods.add(new Modifier("T", temp, x, y, centered)); 5403 } 5404 5405 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5406 { 5407 y = -2; 5408 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5409 y++; 5410 temp = modifiers.get(Modifiers.Z_SPEED); 5411 if(temp != null && !temp.isEmpty()) 5412 mods.add(new Modifier(Modifiers.J_EVALUATION_RATING, temp, x, y, centered)); 5413 } 5414 } 5415 else if(ss == SymbolID.SymbolSet_LandEquipment || 5416 ss == SymbolID.SymbolSet_SignalsIntelligence_Land) 5417 { 5418 //Do top center label 5419 x = 0;//centered 5420 y = 9;//on top of symbol 5421 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 5422 { 5423 temp = modifiers.get(Modifiers.C_QUANTITY); 5424 if(temp != null && !temp.isEmpty()) 5425 mods.add(new Modifier("C", temp, x, y, centered)); 5426 } 5427 5428 //Do right side labels 5429 x = 1;//on right 5430 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 5431 { 5432 y = 0;//center 5433 centered = true;//vertically centered, only matters for labels on left and right side 5434 temp = ""; 5435 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5436 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 5437 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 5438 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 5439 temp = temp.trim(); 5440 if(temp != null && !temp.isEmpty()) 5441 mods.add(new Modifier("H AF", temp, x, y, centered)); 5442 } 5443 else if(!strict) 5444 { 5445 //if no "H', bring G and M closer to the center 5446 centered = false; 5447 } 5448 5449 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5450 { 5451 y = 1;//above center 5452 temp = ""; 5453 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5454 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5455 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5456 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 5457 temp = temp.trim(); 5458 if(temp != null && !temp.isEmpty()) 5459 mods.add(new Modifier("G AQ", temp, x, y, centered)); 5460 } 5461 5462 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5463 { 5464 y = 2; 5465 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 5466 y--; 5467 5468 temp = modifiers.get(Modifiers.AS_COUNTRY); 5469 if(temp != null && !temp.isEmpty()) 5470 mods.add(new Modifier("AS", temp, x, y, centered)); 5471 } 5472 5473 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5474 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 5475 modifiers.containsKey(Modifiers.N_HOSTILE) || 5476 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5477 { 5478 y = -1; 5479 5480 temp = ""; 5481 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5482 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5483 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 5484 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 5485 if(modifiers.containsKey(Modifiers.N_HOSTILE)) 5486 temp += modifiers.get(Modifiers.N_HOSTILE) + sep; 5487 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5488 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5489 temp = temp.trim(); 5490 if(temp != null && !temp.isEmpty()) 5491 mods.add(new Modifier("J L N P", temp, x, y, centered)); 5492 } 5493 5494 //Do left side labels 5495 x = -1;//on left 5496 5497 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 5498 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 5499 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 5500 { 5501 y = 0;//center 5502 centered = true;//vertically centered, only matters for labels on left and right side 5503 5504 temp = ""; 5505 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5506 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 5507 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 5508 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 5509 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 5510 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 5511 temp = temp.trim(); 5512 if(temp != null && !temp.isEmpty()) 5513 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 5514 } 5515 else if(!strict) 5516 { 5517 centered = false; 5518 } 5519 5520 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5521 { 5522 y = 1; 5523 temp = ""; 5524 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5525 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5526 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5527 temp += modifiers.get(Modifiers.Y_LOCATION); 5528 5529 temp = temp.trim(); 5530 mods.add(new Modifier("X Y", temp, x, y, centered)); 5531 } 5532 5533 if(modifiers.containsKey(Modifiers.W_DTG_1) || modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5534 { 5535 y = 2;//above center 5536 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 5537 y--; 5538 5539 temp = modifiers.get(Modifiers.W_DTG_1); 5540 5541 if(temp != null && !temp.isEmpty()) 5542 mods.add(new Modifier("W", temp, x, y, centered)); 5543 } 5544 5545 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5546 { 5547 y = -1;//below center 5548 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5549 if(temp != null && !temp.isEmpty()) 5550 mods.add(new Modifier("T", temp, x, y, centered)); 5551 } 5552 5553 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5554 { 5555 y = -2; 5556 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5557 y++; 5558 temp = modifiers.get(Modifiers.Z_SPEED); 5559 if(temp != null && !temp.isEmpty()) 5560 mods.add(new Modifier("Z", temp, x, y, centered)); 5561 } 5562 } 5563 else if(ss == SymbolID.SymbolSet_LandInstallation) 5564 { 5565 //No top center label 5566 5567 //Do right side labels 5568 x = 1;//on right 5569 5570 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5571 { 5572 y = 0;//center 5573 centered = true;//vertically centered, only matters for labels on left and right side 5574 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5575 5576 if(temp != null && !temp.isEmpty()) 5577 mods.add(new Modifier("H", temp, x, y, centered)); 5578 } 5579 else if(!strict) 5580 { 5581 centered = false; 5582 } 5583 5584 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5585 { 5586 y = 1;//above center 5587 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5588 5589 if(temp != null && !temp.isEmpty()) 5590 mods.add(new Modifier("G", temp, x, y, centered)); 5591 } 5592 5593 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5594 { 5595 y = 2; 5596 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5597 y--; 5598 5599 temp = modifiers.get(Modifiers.AS_COUNTRY); 5600 if(temp != null && !temp.isEmpty()) 5601 mods.add(new Modifier("AS", temp, x, y, centered)); 5602 } 5603 5604 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5605 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 5606 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5607 { 5608 y = -1; 5609 5610 temp = ""; 5611 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5612 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5613 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 5614 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 5615 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5616 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5617 temp = temp.trim(); 5618 mods.add(new Modifier("J K P", temp, x, y, centered)); 5619 } 5620 5621 //Do left side labels 5622 x = -1;//on left 5623 5624 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5625 { 5626 y = 0;//center 5627 centered = true;//vertically centered, only matters for labels on left and right side 5628 5629 temp = ""; 5630 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5631 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5632 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5633 temp += modifiers.get(Modifiers.Y_LOCATION); 5634 temp = temp.trim(); 5635 if(temp != null && !temp.isEmpty()) 5636 mods.add(new Modifier("X Y", temp, x, y, centered)); 5637 } 5638 else if(!strict) 5639 { 5640 centered = false; 5641 } 5642 5643 if(modifiers.containsKey(Modifiers.W_DTG_1)) 5644 { 5645 y = 1;//above center 5646 5647 temp = modifiers.get(Modifiers.W_DTG_1); 5648 5649 if(temp != null && !temp.isEmpty()) 5650 mods.add(new Modifier("W AR", temp, x, y, centered)); 5651 } 5652 5653 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5654 { 5655 y = -1;//below center 5656 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5657 if(temp != null && !temp.isEmpty()) 5658 mods.add(new Modifier("T", temp, x, y, centered)); 5659 } 5660 } 5661 else if(ss == SymbolID.SymbolSet_Air || 5662 ss == SymbolID.SymbolSet_AirMissile || 5663 ss == SymbolID.SymbolSet_SignalsIntelligence_Air) 5664 { 5665 //No top center label 5666 5667 5668 //Do right side labels 5669 x = 1;//on right 5670 centered = false;centered = true; 5671 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5672 { 5673 y = 0;//center 5674 centered = true;//vertically centered, only matters for labels on left and right side 5675 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5676 if(temp != null && !temp.isEmpty()) 5677 mods.add(new Modifier("V", temp, x, y, centered)); 5678 } 5679 else if(!strict) 5680 { 5681 //if no "H', bring G and M closer to the center 5682 centered = false; 5683 } 5684 5685 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5686 { 5687 y = 1;//above center 5688 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 5689 5690 if(temp != null && !temp.isEmpty()) 5691 mods.add(new Modifier("P", temp, x, y, centered)); 5692 } 5693 5694 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 5695 { 5696 y = 2; 5697 if(!strict && !modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5698 y--; 5699 temp = ""; 5700 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5701 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 5702 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5703 temp += modifiers.get(Modifiers.AS_COUNTRY); 5704 temp = temp.trim(); 5705 5706 if(temp != null && !temp.isEmpty()) 5707 mods.add(new Modifier("T AS", temp, x, y, centered)); 5708 } 5709 5710 if(modifiers.containsKey(Modifiers.Z_SPEED) || 5711 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5712 { 5713 y = -1;//below center 5714 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5715 y++; 5716 5717 temp = ""; 5718 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5719 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 5720 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5721 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5722 temp = temp.trim(); 5723 5724 if(temp != null && !temp.isEmpty()) 5725 mods.add(new Modifier("Z X", temp, x, y, centered)); 5726 } 5727 5728 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5729 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5730 { 5731 y = -2 ; 5732 if(!strict) 5733 { 5734 if(!(modifiers.containsKey(Modifiers.Z_SPEED) || 5735 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5736 y++; 5737 } 5738 temp = ""; 5739 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5740 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5741 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5742 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5743 temp = temp.trim(); 5744 if(temp != null && !temp.isEmpty()) 5745 mods.add(new Modifier("G H", temp, x, y, centered)); 5746 } 5747 5748 //No left side labels 5749 5750 } 5751 else if(ss == SymbolID.SymbolSet_Space || 5752 ss == SymbolID.SymbolSet_SpaceMissile || 5753 ss == SymbolID.SymbolSet_SignalsIntelligence_Space) 5754 { 5755 //No top center label 5756 5757 5758 //Do right side labels 5759 x = 1;//on right 5760 centered = false; 5761 5762 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5763 { 5764 y = 1;//above center 5765 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5766 if(temp != null && !temp.isEmpty()) 5767 mods.add(new Modifier("V", temp, x, y, centered)); 5768 } 5769 5770 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 5771 { 5772 y = 2; 5773 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5774 y--; 5775 temp = ""; 5776 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5777 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 5778 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5779 temp += modifiers.get(Modifiers.AS_COUNTRY); 5780 temp = temp.trim(); 5781 5782 if(temp != null && !temp.isEmpty()) 5783 mods.add(new Modifier("T AS", temp, x, y, centered)); 5784 } 5785 5786 if(modifiers.containsKey(Modifiers.Z_SPEED) || 5787 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5788 { 5789 y = -1;//below center 5790 temp = ""; 5791 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5792 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 5793 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5794 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5795 temp = temp.trim(); 5796 5797 if(temp != null && !temp.isEmpty()) 5798 mods.add(new Modifier("Z X", temp, x, y, centered)); 5799 } 5800 5801 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5802 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5803 { 5804 y = -2; 5805 if(!strict && 5806 !(modifiers.containsKey(Modifiers.Z_SPEED) || modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5807 y++; 5808 temp = ""; 5809 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5810 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5811 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5812 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5813 temp = temp.trim(); 5814 if(temp != null && !temp.isEmpty()) 5815 mods.add(new Modifier("G H", temp, x, y, centered)); 5816 } 5817 5818 //No left side labels 5819 } 5820 else if(ss == SymbolID.SymbolSet_SeaSurface || 5821 ss == SymbolID.SymbolSet_SignalsIntelligence_SeaSurface) 5822 { 5823 //No top center label 5824 5825 5826 //Do right side labels 5827 x = 1;//on right 5828 centered = true; 5829 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5830 { 5831 y = 0;//center 5832 centered = true;//vertically centered, only matters for labels on left and right side 5833 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 5834 if(temp != null && !temp.isEmpty()) 5835 mods.add(new Modifier("P", temp, x, y, centered)); 5836 } 5837 else if(!strict) 5838 { 5839 //if no "H', bring G and M closer to the center 5840 centered = false; 5841 } 5842 5843 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5844 { 5845 y = 1;//above center 5846 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5847 if(temp != null && !temp.isEmpty()) 5848 mods.add(new Modifier("V", temp, x, y, centered)); 5849 } 5850 5851 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 5852 { 5853 y = 2; 5854 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5855 y--; 5856 temp = ""; 5857 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5858 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 5859 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5860 temp += modifiers.get(Modifiers.AS_COUNTRY); 5861 temp = temp.trim(); 5862 5863 if(temp != null && !temp.isEmpty()) 5864 mods.add(new Modifier("T AS", temp, x, y, centered)); 5865 } 5866 5867 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5868 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5869 { 5870 y = -1;//below center 5871 temp = ""; 5872 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5873 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5874 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5875 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5876 temp = temp.trim(); 5877 5878 if(temp != null && !temp.isEmpty()) 5879 mods.add(new Modifier("G H", temp, x, y, centered)); 5880 } 5881 5882 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 5883 modifiers.containsKey(Modifiers.Z_SPEED)) 5884 { 5885 y = -2; 5886 if(!strict && 5887 !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 5888 y++; 5889 temp = ""; 5890 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5891 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 5892 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5893 temp += modifiers.get(Modifiers.Z_SPEED); 5894 temp = temp.trim(); 5895 if(temp != null && !temp.isEmpty()) 5896 mods.add(new Modifier("Y Z", temp, x, y, centered)); 5897 } 5898 5899 //Do left side labels 5900 x = -1; 5901 centered = false; 5902 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) || modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5903 { 5904 y = 2;//above center 5905 if(!strict) 5906 y--; 5907 5908 temp = ""; 5909 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5910 temp = modifiers.get(Modifiers.AQ_GUARDED_UNIT) + sep; 5911 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5912 temp += modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 5913 temp = temp.trim(); 5914 5915 if(temp != null && !temp.isEmpty()) 5916 mods.add(new Modifier("AQ AR", temp, x, y, centered)); 5917 } 5918 } 5919 else if(ss == SymbolID.SymbolSet_SeaSubsurface || 5920 ss == SymbolID.SymbolSet_SignalsIntelligence_SeaSubsurface) 5921 { 5922 //No top center label 5923 5924 5925 //Do right side labels 5926 x = 1;//on right 5927 centered = true; 5928 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5929 { 5930 y = 0;//center 5931 centered = true;//vertically centered, only matters for labels on left and right side 5932 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5933 if(temp != null && !temp.isEmpty()) 5934 mods.add(new Modifier("X", temp, x, y, centered)); 5935 } 5936 else if(!strict) 5937 { 5938 //if no "H', bring G and M closer to the center 5939 centered = false; 5940 } 5941 5942 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5943 { 5944 y = 1;//center 5945 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5946 if(temp != null && !temp.isEmpty()) 5947 mods.add(new Modifier("V", temp, x, y, centered)); 5948 } 5949 5950 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 5951 { 5952 y = 2; 5953 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5954 y--; 5955 temp = ""; 5956 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5957 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 5958 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5959 temp += modifiers.get(Modifiers.AS_COUNTRY); 5960 temp = temp.trim(); 5961 5962 if(temp != null && !temp.isEmpty()) 5963 mods.add(new Modifier("T AS", temp, x, y, centered)); 5964 } 5965 5966 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5967 { 5968 y = -1; 5969 5970 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5971 5972 if(temp != null && !temp.isEmpty()) 5973 mods.add(new Modifier("G", temp, x, y, centered)); 5974 } 5975 5976 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5977 { 5978 y = -2;//below center 5979 if(!strict) 5980 { 5981 if(!modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5982 y++; 5983 } 5984 5985 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5986 5987 if(temp != null && !temp.isEmpty()) 5988 mods.add(new Modifier("H", temp, x, y, centered)); 5989 } 5990 5991 //Do left side labels 5992 x = -1; 5993 centered = false; 5994 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5995 { 5996 y = 3;//above center 5997 if(!strict) 5998 { 5999 y--; 6000 } 6001 6002 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 6003 6004 if(temp != null && !temp.isEmpty()) 6005 mods.add(new Modifier("AR", temp, x, y, centered)); 6006 } 6007 6008 } 6009 else if(ss == SymbolID.SymbolSet_Activities) 6010 { 6011 //No top center label 6012 6013 //Do right side labels 6014 x = 1;//on right 6015 centered = false; 6016 6017 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6018 { 6019 y = 1; 6020 6021 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 6022 if(temp != null && !temp.isEmpty()) 6023 mods.add(new Modifier("G", temp, x, y, centered)); 6024 } 6025 6026 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6027 { 6028 y = 2; 6029 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6030 y--; 6031 temp = modifiers.get(Modifiers.AS_COUNTRY); 6032 6033 if(temp != null && !temp.isEmpty()) 6034 mods.add(new Modifier("AS", temp, x, y, centered)); 6035 } 6036 6037 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6038 { 6039 y = -1;//below center 6040 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6041 if(temp != null && !temp.isEmpty()) 6042 mods.add(new Modifier("H", temp, x, y, centered)); 6043 } 6044 6045 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6046 { 6047 y = -2; 6048 if(!strict && !modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6049 y++; 6050 temp = temp = modifiers.get(Modifiers.J_EVALUATION_RATING); 6051 6052 if(temp != null && !temp.isEmpty()) 6053 mods.add(new Modifier("J", temp, x, y, centered)); 6054 } 6055 6056 //Do left side labels 6057 x = -1;//on left 6058 centered = false; 6059 6060 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6061 { 6062 y = 1; 6063 temp = modifiers.get(Modifiers.Y_LOCATION); 6064 6065 if(temp != null && !temp.isEmpty()) 6066 mods.add(new Modifier("Y", temp, x, y, centered)); 6067 } 6068 6069 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6070 { 6071 y = 2;//above center 6072 if(!strict && !modifiers.containsKey(Modifiers.Y_LOCATION)) 6073 y--; 6074 temp = modifiers.get(Modifiers.W_DTG_1); 6075 if(temp != null && !temp.isEmpty()) 6076 mods.add(new Modifier("W", temp, x, y, centered)); 6077 } 6078 6079 } 6080 else if(ss == SymbolID.SymbolSet_CyberSpace) 6081 { 6082 //Do top center label 6083 x = 0;//centered 6084 y = 9;//on top of symbol 6085 if(modifiers.containsKey(Modifiers.B_ECHELON)) 6086 { 6087 temp = modifiers.get(Modifiers.B_ECHELON); 6088 if(temp != null && !temp.isEmpty()) 6089 mods.add(new Modifier("B", temp, x, y, centered)); 6090 } 6091 6092 //Do right side labels 6093 x = 1;//on right 6094 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6095 { 6096 y = 0;//center 6097 centered = true;//vertically centered, only matters for labels on left and right side 6098 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6099 if(temp != null && !temp.isEmpty()) 6100 mods.add(new Modifier("H", temp, x, y, centered)); 6101 } 6102 else if(!strict) 6103 { 6104 //if no "H', bring G and M closer to the center 6105 centered = false; 6106 } 6107 6108 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6109 { 6110 y = 1;//above center 6111 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 6112 if(temp != null && !temp.isEmpty()) 6113 mods.add(new Modifier("G", temp, x, y, centered)); 6114 } 6115 6116 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 6117 { 6118 y = 2; 6119 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6120 y--; 6121 temp = ""; 6122 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 6123 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 6124 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6125 temp += modifiers.get(Modifiers.AS_COUNTRY); 6126 temp = temp.trim(); 6127 if(temp != null && !temp.isEmpty()) 6128 mods.add(new Modifier("F AS", temp, x, y, centered)); 6129 } 6130 6131 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6132 { 6133 y = -1;//below center 6134 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6135 if(temp != null && !temp.isEmpty()) 6136 mods.add(new Modifier("M", temp, x, y, centered)); 6137 } 6138 6139 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6140 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6141 { 6142 y = -2; 6143 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6144 y++; 6145 temp = ""; 6146 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6147 temp = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6148 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6149 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 6150 6151 temp = temp.trim(); 6152 if(temp != null && !temp.isEmpty()) 6153 mods.add(new Modifier("K L", temp, x, y, centered)); 6154 } 6155 6156 //Do left side labels 6157 x = -1;//on left 6158 centered = true; 6159 6160 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6161 { 6162 y = 0; 6163 temp = modifiers.get(Modifiers.Y_LOCATION); 6164 6165 if(temp != null && !temp.isEmpty()) 6166 mods.add(new Modifier("Y", temp, x, y, centered)); 6167 } 6168 else if (!strict) 6169 { 6170 centered = false; 6171 } 6172 6173 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6174 { 6175 y = 1;//above center 6176 temp = modifiers.get(Modifiers.W_DTG_1); 6177 if(temp != null && !temp.isEmpty()) 6178 mods.add(new Modifier("W", temp, x, y, centered)); 6179 } 6180 6181 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6182 { 6183 y = -1;//below center 6184 temp = ""; 6185 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6186 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 6187 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6188 temp += modifiers.get(Modifiers.V_EQUIP_TYPE); 6189 6190 temp = temp.trim(); 6191 if(temp != null && !temp.isEmpty()) 6192 mods.add(new Modifier("T V", temp, x, y, centered)); 6193 } 6194 6195 } 6196 /*else if(ver == SymbolID.SymbolSet_MineWarfare) 6197 { 6198 //no modifiers 6199 }//*/ 6200 //else//SymbolSet Unknown 6201 //processUnknownTextModifiers 6202 } 6203 else if(ver >= SymbolID.Version_2525E) 6204 { 6205 int fs = SymbolID.getFrameShape(symbolID); 6206 if(ss == SymbolID.SymbolSet_LandUnit || 6207 ss == SymbolID.SymbolSet_LandCivilianUnit_Organization || 6208 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_LandUnit)) 6209 { 6210 6211 //Only Command & Control has AA; ec.equals("110000"). Always in the middle of the unit. 6212 if(modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ)) 6213 { 6214 temp = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ); 6215 if(temp != null && !temp.isEmpty()) 6216 mods.add(new Modifier("AA", temp, 0, 0, true)); 6217 } 6218 6219 //Do top center label 6220 x = 0;//centered 6221 y = 9;//on top of symbol 6222 if(modifiers.containsKey(Modifiers.B_ECHELON)) 6223 { 6224 temp = modifiers.get(Modifiers.B_ECHELON); 6225 if(temp != null && !temp.isEmpty()) 6226 mods.add(new Modifier("B", temp, x, y, centered)); 6227 } 6228 6229 //Do right side labels 6230 x = 1;//on right 6231 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6232 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6233 { 6234 y = 0;//center 6235 centered = true;//vertically centered, only matters for labels on left and right side 6236 temp = ""; 6237 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6238 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6239 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6240 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6241 temp = temp.trim(); 6242 if(temp != null && !temp.isEmpty()) 6243 mods.add(new Modifier("H AF", temp, x, y, centered)); 6244 } 6245 else if(!strict) 6246 { 6247 //if no "H', bring G and M closer to the center 6248 centered = false; 6249 } 6250 6251 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6252 { 6253 y = 1;//above center 6254 temp = ""; 6255 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6256 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6257 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6258 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6259 temp = temp.trim(); 6260 if(temp != null && !temp.isEmpty()) 6261 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6262 } 6263 6264 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 6265 { 6266 y = 2; 6267 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6268 y--; 6269 temp = ""; 6270 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 6271 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 6272 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6273 temp += modifiers.get(Modifiers.AS_COUNTRY); 6274 temp = temp.trim(); 6275 if(temp != null && !temp.isEmpty()) 6276 mods.add(new Modifier("F AS", temp, x, y, centered)); 6277 } 6278 6279 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6280 { 6281 y = -1;//below center 6282 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6283 if(temp != null && !temp.isEmpty()) 6284 mods.add(new Modifier("M", temp, x, y, centered)); 6285 } 6286 6287 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6288 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6289 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 6290 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6291 { 6292 y = -2; 6293 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6294 y++; 6295 temp = ""; 6296 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6297 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6298 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6299 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6300 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6301 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 6302 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6303 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6304 temp = temp.trim(); 6305 if(temp != null && !temp.isEmpty()) 6306 mods.add(new Modifier("J K L P", temp, x, y, centered)); 6307 } 6308 6309 //Do left side labels 6310 x = -1;//on left 6311 6312 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 6313 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 6314 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6315 { 6316 y = 0;//center 6317 centered = true;//vertically centered, only matters for labels on left and right side 6318 6319 temp = ""; 6320 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6321 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6322 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6323 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 6324 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6325 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6326 temp = temp.trim(); 6327 if(temp != null && !temp.isEmpty()) 6328 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 6329 } 6330 else if(!strict) 6331 { 6332 centered = false; 6333 } 6334 6335 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6336 { 6337 y = 1; 6338 temp = ""; 6339 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6340 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6341 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6342 temp += modifiers.get(Modifiers.Y_LOCATION); 6343 6344 temp = temp.trim(); 6345 mods.add(new Modifier("X Y", temp, x, y, centered)); 6346 } 6347 6348 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6349 { 6350 y = 2;//above center 6351 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6352 y--; 6353 6354 temp = modifiers.get(Modifiers.W_DTG_1); 6355 6356 if(temp != null && !temp.isEmpty()) 6357 mods.add(new Modifier("W", temp, x, y, centered)); 6358 } 6359 6360 if(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6361 { 6362 y = -1;//below center 6363 temp = ""; 6364 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6365 temp = modifiers.get(Modifiers.C_QUANTITY) + sep; 6366 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6367 temp += modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6368 6369 temp = temp.trim(); 6370 if(temp != null && !temp.isEmpty()) 6371 mods.add(new Modifier("C T", temp, x, y, centered)); 6372 } 6373 6374 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6375 { 6376 y = -2; 6377 if(!strict && !(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 6378 y++; 6379 temp = modifiers.get(Modifiers.Z_SPEED); 6380 if(temp != null && !temp.isEmpty()) 6381 mods.add(new Modifier("Z", temp, x, y, centered)); 6382 } 6383 } 6384 else if(ss == SymbolID.SymbolSet_LandEquipment || 6385 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_LandEquipment)) 6386 { 6387 //Do top center label 6388 x = 0;//centered 6389 y = 9;//on top of symbol 6390 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6391 { 6392 temp = modifiers.get(Modifiers.C_QUANTITY); 6393 if(temp != null && !temp.isEmpty()) 6394 mods.add(new Modifier("C", temp, x, y, centered)); 6395 } 6396 6397 //Do right side labels 6398 x = 1;//on right 6399 centered = false; 6400 6401 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6402 { 6403 y = 1;//above center 6404 temp = ""; 6405 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6406 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6407 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6408 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6409 temp = temp.trim(); 6410 if(temp != null && !temp.isEmpty()) 6411 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6412 } 6413 6414 if( modifiers.containsKey(Modifiers.AS_COUNTRY)) 6415 { 6416 y = 2; 6417 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6418 y--; 6419 temp = modifiers.get(Modifiers.AS_COUNTRY); 6420 6421 if(temp != null && !temp.isEmpty()) 6422 mods.add(new Modifier("AS", temp, x, y, centered)); 6423 } 6424 6425 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6426 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6427 { 6428 y = -1; 6429 temp = ""; 6430 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6431 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6432 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6433 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6434 temp = temp.trim(); 6435 if(temp != null && !temp.isEmpty()) 6436 mods.add(new Modifier("H AF", temp, x, y, centered)); 6437 } 6438 6439 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6440 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6441 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 6442 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6443 { 6444 y = -2; 6445 if(!strict && !(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6446 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))) 6447 y++; 6448 temp = ""; 6449 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6450 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6451 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6452 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6453 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6454 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 6455 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6456 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6457 temp = temp.trim(); 6458 if(temp != null && !temp.isEmpty()) 6459 mods.add(new Modifier("J K L P", temp, x, y, centered)); 6460 } 6461 6462 //Do left side labels 6463 x = -1;//on left 6464 6465 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 6466 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 6467 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6468 { 6469 y = 0;//center 6470 centered = true;//vertically centered, only matters for labels on left and right side 6471 6472 temp = ""; 6473 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6474 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6475 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6476 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 6477 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6478 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6479 temp = temp.trim(); 6480 if(temp != null && !temp.isEmpty()) 6481 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 6482 } 6483 else if(!strict) 6484 { 6485 centered = false; 6486 } 6487 6488 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6489 { 6490 y = 1; 6491 temp = ""; 6492 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6493 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6494 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6495 temp += modifiers.get(Modifiers.Y_LOCATION); 6496 6497 temp = temp.trim(); 6498 mods.add(new Modifier("X Y", temp, x, y, centered)); 6499 } 6500 6501 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6502 { 6503 y = 2;//above center 6504 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6505 y--; 6506 6507 temp = modifiers.get(Modifiers.W_DTG_1); 6508 6509 if(temp != null && !temp.isEmpty()) 6510 mods.add(new Modifier("W", temp, x, y, centered)); 6511 } 6512 6513 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6514 { 6515 y = -1;//below center 6516 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6517 6518 temp = temp.trim(); 6519 if(temp != null && !temp.isEmpty()) 6520 mods.add(new Modifier("T", temp, x, y, centered)); 6521 } 6522 6523 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6524 { 6525 y = -2; 6526 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6527 y++; 6528 temp = modifiers.get(Modifiers.Z_SPEED); 6529 if(temp != null && !temp.isEmpty()) 6530 mods.add(new Modifier("Z", temp, x, y, centered)); 6531 } 6532 } 6533 else if(ss == SymbolID.SymbolSet_LandInstallation) 6534 { 6535 //No top center label 6536 6537 //Do right side labels 6538 x = 1;//on right 6539 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6540 { 6541 y = 0;//center 6542 centered = true;//vertically centered, only matters for labels on left and right side 6543 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6544 6545 if(temp != null && !temp.isEmpty()) 6546 mods.add(new Modifier("H", temp, x, y, centered)); 6547 } 6548 else if(!strict) 6549 { 6550 //if no "H', bring G and M closer to the center 6551 centered = false; 6552 } 6553 6554 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6555 { 6556 y = 1;//above center 6557 temp = ""; 6558 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6559 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6560 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6561 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6562 temp = temp.trim(); 6563 if(temp != null && !temp.isEmpty()) 6564 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6565 } 6566 6567 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6568 { 6569 y = 2; 6570 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6571 y--; 6572 temp = modifiers.get(Modifiers.AS_COUNTRY); 6573 6574 if(temp != null && !temp.isEmpty()) 6575 mods.add(new Modifier("AS", temp, x, y, centered)); 6576 } 6577 6578 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6579 { 6580 y = -1;//below center 6581 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6582 if(temp != null && !temp.isEmpty()) 6583 mods.add(new Modifier("M", temp, x, y, centered)); 6584 } 6585 6586 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6587 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6588 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6589 { 6590 y = -2; 6591 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6592 y++; 6593 temp = ""; 6594 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6595 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6596 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6597 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6598 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6599 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6600 temp = temp.trim(); 6601 if(temp != null && !temp.isEmpty()) 6602 mods.add(new Modifier("J K P", temp, x, y, centered)); 6603 } 6604 6605 //Do left side labels 6606 x = -1;//on left 6607 centered = false; 6608 6609 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6610 { 6611 y = 1; 6612 temp = ""; 6613 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6614 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6615 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6616 temp += modifiers.get(Modifiers.Y_LOCATION); 6617 6618 temp = temp.trim(); 6619 mods.add(new Modifier("X Y", temp, x, y, centered)); 6620 } 6621 6622 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6623 { 6624 y = 2;//above center 6625 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6626 y--; 6627 6628 temp = modifiers.get(Modifiers.W_DTG_1); 6629 6630 if(temp != null && !temp.isEmpty()) 6631 mods.add(new Modifier("W", temp, x, y, centered)); 6632 } 6633 6634 if(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6635 { 6636 y = -1;//below center 6637 temp = ""; 6638 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6639 temp = modifiers.get(Modifiers.C_QUANTITY) + sep; 6640 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6641 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6642 6643 temp = temp.trim(); 6644 if(temp != null && !temp.isEmpty()) 6645 mods.add(new Modifier("C AE", temp, x, y, centered)); 6646 } 6647 6648 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6649 { 6650 y = -2; 6651 if(!strict && !(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))) 6652 y++; 6653 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6654 if(temp != null && !temp.isEmpty()) 6655 mods.add(new Modifier("T", temp, x, y, centered)); 6656 } 6657 } 6658 else if(ss == SymbolID.SymbolSet_Space || 6659 ss == SymbolID.SymbolSet_SpaceMissile || 6660 ss == SymbolID.SymbolSet_Air || 6661 ss == SymbolID.SymbolSet_AirMissile || 6662 (ss == SymbolID.SymbolSet_SignalsIntelligence && 6663 (fs == SymbolID.FrameShape_Space || fs == SymbolID.FrameShape_Air))) 6664 { 6665 //No top center label 6666 x = 0;//centered 6667 y = 9;//on top of symbol 6668 6669 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6670 { 6671 temp = modifiers.get(Modifiers.C_QUANTITY); 6672 if(temp != null && !temp.isEmpty()) 6673 mods.add(new Modifier("C", temp, x, y, centered)); 6674 } 6675 else if(modifiers.containsKey(Modifiers.B_ECHELON)) 6676 { 6677 temp = modifiers.get(Modifiers.B_ECHELON); 6678 if(temp != null && !temp.isEmpty()) 6679 mods.add(new Modifier("B", temp, x, y, centered)); 6680 } 6681 6682 6683 //Do right side labels 6684 x = 1;//on right 6685 centered = true; 6686 6687 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6688 { 6689 y = 0;// 6690 temp = ""; 6691 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6692 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6693 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6694 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6695 temp = temp.trim(); 6696 6697 if(temp != null && !temp.isEmpty()) 6698 mods.add(new Modifier("V AF", temp, x, y, centered)); 6699 } 6700 else 6701 { 6702 centered = false; 6703 } 6704 6705 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6706 { 6707 y = 1;//above center 6708 temp = ""; 6709 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6710 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 6711 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6712 temp += modifiers.get(Modifiers.Y_LOCATION); 6713 temp = temp.trim(); 6714 6715 if(temp != null && !temp.isEmpty()) 6716 mods.add(new Modifier("T Y", temp, x, y, centered)); 6717 } 6718 6719 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6720 { 6721 y = 2; 6722 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6723 y--; 6724 temp = modifiers.get(Modifiers.AS_COUNTRY); 6725 6726 if(temp != null && !temp.isEmpty()) 6727 mods.add(new Modifier("AS", temp, x, y, centered)); 6728 } 6729 6730 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) || 6731 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || 6732 modifiers.containsKey(Modifiers.Z_SPEED)) 6733 { 6734 y = -1;//below center 6735 temp = ""; 6736 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6737 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS) + sep; 6738 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6739 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6740 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6741 temp += modifiers.get(Modifiers.Z_SPEED); 6742 6743 temp = temp.trim(); 6744 6745 if(temp != null && !temp.isEmpty()) 6746 mods.add(new Modifier("P X Z", temp, x, y, centered)); 6747 } 6748 6749 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6750 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6751 modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6752 { 6753 y = -2;//below center 6754 if(!(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) || 6755 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || 6756 modifiers.containsKey(Modifiers.Z_SPEED))) 6757 y++; 6758 6759 temp = ""; 6760 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6761 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6762 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6763 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6764 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6765 temp += modifiers.get(Modifiers.J_EVALUATION_RATING); 6766 temp = temp.trim(); 6767 6768 if(temp != null && !temp.isEmpty()) 6769 mods.add(new Modifier("G H J", temp, x, y, centered)); 6770 } 6771 6772 //No left side labels 6773 x = -1;//on right 6774 centered = true; 6775 6776 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6777 { 6778 y = 0;// 6779 temp = modifiers.get(Modifiers.AD_PLATFORM_TYPE); 6780 6781 if(temp != null && !temp.isEmpty()) 6782 mods.add(new Modifier("AD", temp, x, y, centered)); 6783 } 6784 else 6785 { 6786 centered = false; 6787 } 6788 6789 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6790 { 6791 y = 1;//above center 6792 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 6793 6794 if(temp != null && !temp.isEmpty()) 6795 mods.add(new Modifier("AR", temp, x, y, centered)); 6796 } 6797 6798 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6799 { 6800 y = 2; 6801 if(!strict && !modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6802 y--; 6803 temp = modifiers.get(Modifiers.W_DTG_1); 6804 6805 if(temp != null && !temp.isEmpty()) 6806 mods.add(new Modifier("W", temp, x, y, centered)); 6807 } 6808 } 6809 else if(ss == SymbolID.SymbolSet_SeaSurface || 6810 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_SeaSurface)) 6811 { 6812 //No top center label 6813 6814 6815 //Do right side labels 6816 x = 1;//on right 6817 centered = false; 6818 6819 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6820 { 6821 y = 1;//above center 6822 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 6823 6824 if(temp != null && !temp.isEmpty()) 6825 mods.add(new Modifier("V", temp, x, y, centered)); 6826 } 6827 6828 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6829 { 6830 y = 2; 6831 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6832 y--; 6833 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6834 6835 if(temp != null && !temp.isEmpty()) 6836 mods.add(new Modifier("T", temp, x, y, centered)); 6837 } 6838 6839 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6840 { 6841 y = 3; 6842 if(!strict) 6843 { 6844 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6845 y--; 6846 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6847 y--; 6848 } 6849 6850 temp = modifiers.get(Modifiers.AS_COUNTRY ); 6851 6852 if(temp != null && !temp.isEmpty()) 6853 mods.add(new Modifier("AS", temp, x, y, centered)); 6854 } 6855 6856 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6857 { 6858 y = -1;//below center 6859 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 6860 6861 if(temp != null && !temp.isEmpty()) 6862 mods.add(new Modifier("P", temp, x, y, centered)); 6863 } 6864 6865 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6866 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6867 { 6868 y = -2;//below center 6869 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6870 y++; 6871 6872 temp = ""; 6873 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6874 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6875 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6876 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6877 temp = temp.trim(); 6878 6879 if(temp != null && !temp.isEmpty()) 6880 mods.add(new Modifier("G H", temp, x, y, centered)); 6881 } 6882 6883 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 6884 modifiers.containsKey(Modifiers.Z_SPEED)) 6885 { 6886 y = -3; 6887 if(!strict) 6888 { 6889 if(!(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6890 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 6891 y++; 6892 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6893 y++; 6894 } 6895 temp = ""; 6896 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6897 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 6898 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6899 temp += modifiers.get(Modifiers.Z_SPEED); 6900 temp = temp.trim(); 6901 if(temp != null && !temp.isEmpty()) 6902 mods.add(new Modifier("Y Z", temp, x, y, centered)); 6903 } 6904 6905 //No left side labels 6906 x = -1; 6907 centered = false; 6908 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) || 6909 modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6910 { 6911 y = 2; 6912 if(!strict) 6913 { 6914 y--; 6915 } 6916 temp = ""; 6917 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6918 temp = modifiers.get(Modifiers.AQ_GUARDED_UNIT) + sep; 6919 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6920 temp += modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 6921 temp = temp.trim(); 6922 if(temp != null && !temp.isEmpty()) 6923 mods.add(new Modifier("AQ AR", temp, x, y, centered)); 6924 } 6925 } 6926 else if(ss == SymbolID.SymbolSet_SeaSubsurface || 6927 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_SeaSubsurface)) 6928 { 6929 //No top center label 6930 6931 6932 //Do right side labels 6933 x = 1;//on right 6934 centered = false; 6935 6936 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6937 { 6938 y = 1;//above center 6939 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 6940 6941 if(temp != null && !temp.isEmpty()) 6942 mods.add(new Modifier("V", temp, x, y, centered)); 6943 } 6944 6945 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6946 { 6947 y = 2; 6948 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6949 y--; 6950 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6951 6952 if(temp != null && !temp.isEmpty()) 6953 mods.add(new Modifier("T", temp, x, y, centered)); 6954 } 6955 6956 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6957 { 6958 y = 3; 6959 if(!strict) 6960 { 6961 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6962 y--; 6963 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6964 y--; 6965 } 6966 6967 temp = modifiers.get(Modifiers.AS_COUNTRY ); 6968 6969 if(temp != null && !temp.isEmpty()) 6970 mods.add(new Modifier("AS", temp, x, y, centered)); 6971 } 6972 6973 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6974 { 6975 y = -1;//below center 6976 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 6977 6978 if(temp != null && !temp.isEmpty()) 6979 mods.add(new Modifier("P", temp, x, y, centered)); 6980 } 6981 6982 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6983 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6984 { 6985 y = -2;//below center 6986 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6987 y++; 6988 6989 temp = ""; 6990 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6991 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6992 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6993 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6994 temp = temp.trim(); 6995 6996 if(temp != null && !temp.isEmpty()) 6997 mods.add(new Modifier("G H", temp, x, y, centered)); 6998 } 6999 7000 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 7001 modifiers.containsKey(Modifiers.Z_SPEED)) 7002 { 7003 y = -3; 7004 if(!strict) 7005 { 7006 if(!(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 7007 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 7008 y++; 7009 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7010 y++; 7011 } 7012 temp = ""; 7013 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7014 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 7015 if(modifiers.containsKey(Modifiers.Z_SPEED)) 7016 temp += modifiers.get(Modifiers.Z_SPEED); 7017 temp = temp.trim(); 7018 if(temp != null && !temp.isEmpty()) 7019 mods.add(new Modifier("Y Z", temp, x, y, centered)); 7020 } 7021 7022 //No left side labels 7023 x = -1; 7024 centered = false; 7025 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7026 { 7027 y = 1; 7028 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 7029 7030 if(temp != null && !temp.isEmpty()) 7031 mods.add(new Modifier("X", temp, x, y, centered)); 7032 } 7033 7034 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 7035 { 7036 y = 2; 7037 if(!strict && !modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7038 { 7039 y--; 7040 } 7041 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 7042 temp = temp.trim(); 7043 if(temp != null && !temp.isEmpty()) 7044 mods.add(new Modifier("AR", temp, x, y, centered)); 7045 } 7046 } 7047 else if(ss == SymbolID.SymbolSet_DismountedIndividuals) 7048 { 7049 //No top center label 7050 7051 7052 //Do right side labels 7053 x = 1;//on right 7054 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7055 { 7056 y = 0;//center 7057 centered = true;//vertically centered, only matters for labels on left and right side 7058 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7059 7060 if(temp != null && !temp.isEmpty()) 7061 mods.add(new Modifier("H", temp, x, y, centered)); 7062 } 7063 else if(!strict) 7064 { 7065 centered = false; 7066 } 7067 7068 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7069 { 7070 y = 1;//above center 7071 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 7072 7073 if(temp != null && !temp.isEmpty()) 7074 mods.add(new Modifier("G", temp, x, y, centered)); 7075 } 7076 7077 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7078 { 7079 y = 2; 7080 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))) 7081 y--; 7082 temp = modifiers.get(Modifiers.AS_COUNTRY); 7083 7084 if(temp != null && !temp.isEmpty()) 7085 mods.add(new Modifier("AS", temp, x, y, centered)); 7086 } 7087 7088 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7089 { 7090 y = -1;//below center 7091 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 7092 if(temp != null && !temp.isEmpty()) 7093 mods.add(new Modifier("M", temp, x, y, centered)); 7094 } 7095 7096 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 7097 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 7098 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7099 { 7100 y = -2; 7101 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7102 y++; 7103 temp = ""; 7104 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7105 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 7106 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7107 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 7108 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7109 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 7110 temp = temp.trim(); 7111 if(temp != null && !temp.isEmpty()) 7112 mods.add(new Modifier("J K P", temp, x, y, centered)); 7113 } 7114 7115 //Do left side labels 7116 x = -1;//on left 7117 7118 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 7119 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7120 { 7121 y = 0;//center 7122 centered = true;//vertically centered, only matters for labels on left and right side 7123 7124 temp = ""; 7125 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7126 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 7127 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7128 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 7129 temp = temp.trim(); 7130 if(temp != null && !temp.isEmpty()) 7131 mods.add(new Modifier("V AF", temp, x, y, centered)); 7132 } 7133 else if(!strict) 7134 { 7135 centered = false; 7136 } 7137 7138 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 7139 { 7140 y = 1; 7141 temp = ""; 7142 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7143 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 7144 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7145 temp += modifiers.get(Modifiers.Y_LOCATION); 7146 7147 temp = temp.trim(); 7148 mods.add(new Modifier("X Y", temp, x, y, centered)); 7149 } 7150 7151 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7152 { 7153 y = 2;//above center 7154 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 7155 y--; 7156 7157 temp = modifiers.get(Modifiers.W_DTG_1); 7158 7159 if(temp != null && !temp.isEmpty()) 7160 mods.add(new Modifier("W", temp, x, y, centered)); 7161 } 7162 7163 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7164 { 7165 y = -1;//below center 7166 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7167 7168 if(temp != null && !temp.isEmpty()) 7169 mods.add(new Modifier("T", temp, x, y, centered)); 7170 } 7171 7172 if(modifiers.containsKey(Modifiers.Z_SPEED)) 7173 { 7174 y = -2; 7175 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 7176 y++; 7177 temp = modifiers.get(Modifiers.Z_SPEED); 7178 if(temp != null && !temp.isEmpty()) 7179 mods.add(new Modifier("Z", temp, x, y, centered)); 7180 } 7181 } 7182 else if(ss == SymbolID.SymbolSet_Activities) 7183 { 7184 //No top center label 7185 7186 7187 //Do right side labels 7188 x = 1;//on right 7189 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7190 { 7191 y = 0;//center 7192 centered = true;//vertically centered, only matters for labels on left and right side 7193 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 7194 7195 if(temp != null && !temp.isEmpty()) 7196 mods.add(new Modifier("G", temp, x, y, centered)); 7197 } 7198 else if(!strict) 7199 { 7200 centered = false; 7201 } 7202 7203 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7204 { 7205 y = 1;//above center 7206 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7207 7208 if(temp != null && !temp.isEmpty()) 7209 mods.add(new Modifier("T", temp, x, y, centered)); 7210 } 7211 7212 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7213 { 7214 y = 2; 7215 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 7216 y--; 7217 temp = modifiers.get(Modifiers.AS_COUNTRY); 7218 7219 if(temp != null && !temp.isEmpty()) 7220 mods.add(new Modifier("AS", temp, x, y, centered)); 7221 } 7222 7223 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7224 { 7225 y = -1;//below center 7226 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7227 if(temp != null && !temp.isEmpty()) 7228 mods.add(new Modifier("H", temp, x, y, centered)); 7229 } 7230 7231 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7232 { 7233 y = -2; 7234 if(!strict && !modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7235 y++; 7236 temp = modifiers.get(Modifiers.J_EVALUATION_RATING); 7237 7238 if(temp != null && !temp.isEmpty()) 7239 mods.add(new Modifier("J", temp, x, y, centered)); 7240 } 7241 7242 //Do left side labels 7243 x = -1;//on left 7244 7245 if(!strict) 7246 { 7247 centered = false; 7248 } 7249 7250 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7251 { 7252 y = 1; 7253 temp = modifiers.get(Modifiers.Y_LOCATION); 7254 7255 if(temp != null && !temp.isEmpty()) 7256 mods.add(new Modifier("Y", temp, x, y, centered)); 7257 } 7258 7259 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7260 { 7261 y = 2;//above center 7262 if(!strict && !(modifiers.containsKey(Modifiers.Y_LOCATION))) 7263 y--; 7264 7265 temp = modifiers.get(Modifiers.W_DTG_1); 7266 7267 if(temp != null && !temp.isEmpty()) 7268 mods.add(new Modifier("W", temp, x, y, centered)); 7269 } 7270 7271 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 7272 { 7273 y = -1;//below center 7274 temp = modifiers.get(Modifiers.C_QUANTITY); 7275 7276 if(temp != null && !temp.isEmpty()) 7277 mods.add(new Modifier("C", temp, x, y, centered)); 7278 } 7279 7280 } 7281 else if(ss == SymbolID.SymbolSet_CyberSpace || 7282 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_Cyberspace)) 7283 { 7284 //Do top center label 7285 x = 0;//centered 7286 y = 9;//on top of symbol 7287 if(modifiers.containsKey(Modifiers.B_ECHELON)) 7288 { 7289 temp = modifiers.get(Modifiers.B_ECHELON); 7290 if(temp != null && !temp.isEmpty()) 7291 mods.add(new Modifier("B", temp, x, y, centered)); 7292 } 7293 7294 //Do right side labels 7295 x = 1;//on right 7296 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7297 { 7298 y = 0;//center 7299 centered = true;//vertically centered, only matters for labels on left and right side 7300 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7301 7302 if(temp != null && !temp.isEmpty()) 7303 mods.add(new Modifier("H", temp, x, y, centered)); 7304 } 7305 else if(!strict) 7306 { 7307 centered = false; 7308 } 7309 7310 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7311 { 7312 y = 1;//above center 7313 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 7314 7315 if(temp != null && !temp.isEmpty()) 7316 mods.add(new Modifier("G", temp, x, y, centered)); 7317 } 7318 7319 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 7320 { 7321 y = 2; 7322 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))) 7323 y--; 7324 temp = ""; 7325 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 7326 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 7327 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7328 temp += modifiers.get(Modifiers.AS_COUNTRY); 7329 temp = temp.trim(); 7330 if(temp != null && !temp.isEmpty()) 7331 mods.add(new Modifier("F AS", temp, x, y, centered)); 7332 } 7333 7334 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7335 { 7336 y = -1;//below center 7337 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 7338 if(temp != null && !temp.isEmpty()) 7339 mods.add(new Modifier("M", temp, x, y, centered)); 7340 } 7341 7342 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 7343 { 7344 y = -2; 7345 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7346 y++; 7347 temp = ""; 7348 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7349 temp = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 7350 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 7351 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 7352 temp = temp.trim(); 7353 if(temp != null && !temp.isEmpty()) 7354 mods.add(new Modifier("K L", temp, x, y, centered)); 7355 } 7356 7357 //Do left side labels 7358 x=-1; 7359 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7360 { 7361 y = 0;//center 7362 centered = true;//vertically centered, only matters for labels on left and right side 7363 7364 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 7365 7366 if(temp != null && !temp.isEmpty()) 7367 mods.add(new Modifier("V", temp, x, y, centered)); 7368 } 7369 else if(!strict) 7370 { 7371 centered = false; 7372 } 7373 7374 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7375 { 7376 y = 1; 7377 temp = modifiers.get(Modifiers.Y_LOCATION); 7378 7379 if(temp != null && !temp.isEmpty()) 7380 mods.add(new Modifier("Y", temp, x, y, centered)); 7381 } 7382 7383 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7384 { 7385 y = 2;//above center 7386 if(!strict && !(modifiers.containsKey(Modifiers.Y_LOCATION))) 7387 y--; 7388 7389 temp = modifiers.get(Modifiers.W_DTG_1); 7390 7391 if(temp != null && !temp.isEmpty()) 7392 mods.add(new Modifier("W", temp, x, y, centered)); 7393 } 7394 7395 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7396 { 7397 y = -1;//below center 7398 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7399 7400 if(temp != null && !temp.isEmpty()) 7401 mods.add(new Modifier("T", temp, x, y, centered)); 7402 } 7403 } 7404 /*else if(ver == SymbolID.SymbolSet_MineWarfare) 7405 { 7406 //no modifiers 7407 }//*/ 7408 //else//SymbolSet Unknown 7409 //processUnknownTextModifiers 7410 } 7411 else if(ver >= SymbolID.Version_APP6D) 7412 { 7413 int fs = SymbolID.getFrameShape(symbolID); 7414 if(ss == SymbolID.SymbolSet_LandUnit || 7415 ss == SymbolID.SymbolSet_LandCivilianUnit_Organization) 7416 { 7417 7418 //Only Command & Control has AA; ec.equals("110000"). Always in the middle of the unit. 7419 if(modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ)) 7420 { 7421 temp = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ); 7422 if(temp != null && !temp.isEmpty()) 7423 mods.add(new Modifier("AA", temp, 0, 0, true)); 7424 } 7425 7426 //Do top center label 7427 x = 0;//centered 7428 y = 9;//on top of symbol 7429 if(modifiers.containsKey(Modifiers.B_ECHELON)) 7430 { 7431 temp = modifiers.get(Modifiers.B_ECHELON); 7432 if(temp != null && !temp.isEmpty()) 7433 mods.add(new Modifier("B", temp, x, y, centered)); 7434 } 7435 7436 //Do right side labels 7437 x = 1;//on right 7438 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 7439 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7440 { 7441 y = 0;//center 7442 centered = true;//vertically centered, only matters for labels on left and right side 7443 temp = ""; 7444 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7445 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 7446 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7447 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 7448 temp = temp.trim(); 7449 if(temp != null && !temp.isEmpty()) 7450 mods.add(new Modifier("H AF", temp, x, y, centered)); 7451 } 7452 else if(!strict) 7453 { 7454 //if no "H', bring G and M closer to the center 7455 centered = false; 7456 } 7457 7458 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 7459 { 7460 y = 1;//above center 7461 temp = ""; 7462 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7463 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 7464 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 7465 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 7466 temp = temp.trim(); 7467 if(temp != null && !temp.isEmpty()) 7468 mods.add(new Modifier("G AQ", temp, x, y, centered)); 7469 } 7470 7471 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 7472 { 7473 y = 2; 7474 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 7475 y--; 7476 temp = ""; 7477 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 7478 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 7479 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7480 temp += modifiers.get(Modifiers.AS_COUNTRY); 7481 temp = temp.trim(); 7482 if(temp != null && !temp.isEmpty()) 7483 mods.add(new Modifier("F AS", temp, x, y, centered)); 7484 } 7485 7486 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7487 { 7488 y = -1;//below center 7489 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 7490 if(temp != null && !temp.isEmpty()) 7491 mods.add(new Modifier("M", temp, x, y, centered)); 7492 } 7493 7494 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 7495 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 7496 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 7497 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7498 { 7499 y = -2; 7500 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7501 y++; 7502 temp = ""; 7503 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7504 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 7505 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7506 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 7507 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 7508 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 7509 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7510 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 7511 temp = temp.trim(); 7512 if(temp != null && !temp.isEmpty()) 7513 mods.add(new Modifier("J K L P", temp, x, y, centered)); 7514 } 7515 7516 //Do left side labels 7517 x = -1;//on left 7518 7519 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 7520 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 7521 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 7522 { 7523 y = 0;//center 7524 centered = true;//vertically centered, only matters for labels on left and right side 7525 7526 temp = ""; 7527 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7528 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 7529 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 7530 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 7531 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 7532 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 7533 temp = temp.trim(); 7534 if(temp != null && !temp.isEmpty()) 7535 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 7536 } 7537 else if(!strict) 7538 { 7539 centered = false; 7540 } 7541 7542 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 7543 { 7544 y = 1; 7545 temp = ""; 7546 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7547 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 7548 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7549 temp += modifiers.get(Modifiers.Y_LOCATION); 7550 7551 temp = temp.trim(); 7552 mods.add(new Modifier("X Y", temp, x, y, centered)); 7553 } 7554 7555 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7556 { 7557 y = 2;//above center 7558 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 7559 y--; 7560 7561 temp = modifiers.get(Modifiers.W_DTG_1); 7562 7563 if(temp != null && !temp.isEmpty()) 7564 mods.add(new Modifier("W", temp, x, y, centered)); 7565 } 7566 7567 if(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7568 { 7569 y = -1;//below center 7570 temp = ""; 7571 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 7572 temp = modifiers.get(Modifiers.C_QUANTITY) + sep; 7573 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7574 temp += modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7575 7576 temp = temp.trim(); 7577 if(temp != null && !temp.isEmpty()) 7578 mods.add(new Modifier("C T", temp, x, y, centered)); 7579 } 7580 7581 if(modifiers.containsKey(Modifiers.Z_SPEED)) 7582 { 7583 y = -2; 7584 if(!strict && !(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 7585 y++; 7586 temp = modifiers.get(Modifiers.Z_SPEED); 7587 if(temp != null && !temp.isEmpty()) 7588 mods.add(new Modifier("Z", temp, x, y, centered)); 7589 } 7590 } 7591 else if(ss == SymbolID.SymbolSet_LandEquipment) 7592 { 7593 //Do top center label 7594 x = 0;//centered 7595 y = 9;//on top of symbol 7596 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 7597 { 7598 temp = modifiers.get(Modifiers.C_QUANTITY); 7599 if(temp != null && !temp.isEmpty()) 7600 mods.add(new Modifier("C", temp, x, y, centered)); 7601 } 7602 7603 //Do right side labels 7604 x = 1;//on right 7605 centered = false; 7606 7607 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 7608 { 7609 y = 1;//above center 7610 temp = ""; 7611 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7612 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 7613 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 7614 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 7615 temp = temp.trim(); 7616 if(temp != null && !temp.isEmpty()) 7617 mods.add(new Modifier("G AQ", temp, x, y, centered)); 7618 } 7619 7620 if( modifiers.containsKey(Modifiers.AS_COUNTRY)) 7621 { 7622 y = 2; 7623 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 7624 y--; 7625 temp = modifiers.get(Modifiers.AS_COUNTRY); 7626 7627 if(temp != null && !temp.isEmpty()) 7628 mods.add(new Modifier("AS", temp, x, y, centered)); 7629 } 7630 7631 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 7632 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 7633 { 7634 y = 0; 7635 temp = ""; 7636 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7637 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 7638 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 7639 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 7640 temp = temp.trim(); 7641 if(temp != null && !temp.isEmpty()) 7642 mods.add(new Modifier("H AE", temp, x, y, centered)); 7643 } 7644 7645 if( modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7646 { 7647 y = -1; 7648 if(!strict && !(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))) 7649 y++; 7650 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 7651 7652 if(temp != null && !temp.isEmpty()) 7653 mods.add(new Modifier("M", temp, x, y, centered)); 7654 } 7655 7656 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 7657 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 7658 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 7659 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7660 { 7661 y = -2; 7662 if(!strict && !(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))) 7663 y++; 7664 temp = ""; 7665 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7666 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 7667 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7668 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 7669 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 7670 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 7671 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7672 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 7673 temp = temp.trim(); 7674 if(temp != null && !temp.isEmpty()) 7675 mods.add(new Modifier("J K L P", temp, x, y, centered)); 7676 } 7677 7678 //Do left side labels 7679 x = -1;//on left 7680 7681 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 7682 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 7683 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 7684 { 7685 y = 0;//center 7686 centered = true;//vertically centered, only matters for labels on left and right side 7687 7688 temp = ""; 7689 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7690 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 7691 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 7692 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 7693 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7694 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 7695 temp = temp.trim(); 7696 if(temp != null && !temp.isEmpty()) 7697 mods.add(new Modifier("V AD AF", temp, x, y, centered)); 7698 } 7699 else if(!strict) 7700 { 7701 centered = false; 7702 } 7703 7704 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 7705 { 7706 y = 1; 7707 temp = ""; 7708 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7709 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 7710 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7711 temp += modifiers.get(Modifiers.Y_LOCATION); 7712 7713 temp = temp.trim(); 7714 mods.add(new Modifier("X Y", temp, x, y, centered)); 7715 } 7716 7717 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7718 { 7719 y = 2;//above center 7720 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 7721 y--; 7722 7723 temp = modifiers.get(Modifiers.W_DTG_1); 7724 7725 if(temp != null && !temp.isEmpty()) 7726 mods.add(new Modifier("W", temp, x, y, centered)); 7727 } 7728 7729 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7730 { 7731 y = -1;//below center 7732 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7733 7734 temp = temp.trim(); 7735 if(temp != null && !temp.isEmpty()) 7736 mods.add(new Modifier("T", temp, x, y, centered)); 7737 } 7738 7739 if(modifiers.containsKey(Modifiers.Z_SPEED)) 7740 { 7741 y = -2; 7742 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7743 y++; 7744 temp = modifiers.get(Modifiers.Z_SPEED); 7745 if(temp != null && !temp.isEmpty()) 7746 mods.add(new Modifier("Z", temp, x, y, centered)); 7747 } 7748 } 7749 else if(ss == SymbolID.SymbolSet_LandInstallation) 7750 { 7751 //No top center label 7752 7753 //Do right side labels 7754 x = 1;//on right 7755 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 7756 { 7757 y = 0;//center 7758 centered = true;//vertically centered, only matters for labels on left and right side 7759 temp = ""; 7760 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7761 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 7762 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 7763 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 7764 temp = temp.trim(); 7765 7766 if(temp != null && !temp.isEmpty()) 7767 mods.add(new Modifier("H AE", temp, x, y, centered)); 7768 } 7769 else if(!strict) 7770 { 7771 //if no "H', bring G and M closer to the center 7772 centered = false; 7773 } 7774 7775 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 7776 { 7777 y = 1;//above center 7778 temp = ""; 7779 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7780 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 7781 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 7782 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 7783 temp = temp.trim(); 7784 if(temp != null && !temp.isEmpty()) 7785 mods.add(new Modifier("G AQ", temp, x, y, centered)); 7786 } 7787 7788 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7789 { 7790 y = 2; 7791 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 7792 y--; 7793 temp = modifiers.get(Modifiers.AS_COUNTRY); 7794 7795 if(temp != null && !temp.isEmpty()) 7796 mods.add(new Modifier("AS", temp, x, y, centered)); 7797 } 7798 7799 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7800 { 7801 y = -1;//below center 7802 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 7803 if(temp != null && !temp.isEmpty()) 7804 mods.add(new Modifier("M", temp, x, y, centered)); 7805 } 7806 7807 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 7808 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 7809 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7810 { 7811 y = -2; 7812 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7813 y++; 7814 temp = ""; 7815 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7816 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 7817 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7818 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS); 7819 temp = temp.trim(); 7820 if(temp != null && !temp.isEmpty()) 7821 mods.add(new Modifier("J K P", temp, x, y, centered)); 7822 } 7823 7824 //Do left side labels 7825 x = -1;//on left 7826 centered = false; 7827 7828 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 7829 { 7830 y = 0;//center 7831 centered = true;//vertically centered, only matters for labels on left and right side 7832 7833 temp = ""; 7834 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7835 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 7836 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7837 temp += modifiers.get(Modifiers.Y_LOCATION); 7838 temp = temp.trim(); 7839 if(temp != null && !temp.isEmpty()) 7840 mods.add(new Modifier("X Y", temp, x, y, centered)); 7841 } 7842 else if(!strict) 7843 { 7844 centered = false; 7845 } 7846 7847 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7848 { 7849 y = 1;//above center 7850 7851 temp = modifiers.get(Modifiers.W_DTG_1); 7852 7853 if(temp != null && !temp.isEmpty()) 7854 mods.add(new Modifier("W AR", temp, x, y, centered)); 7855 } 7856 7857 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7858 { 7859 y = -1;//below center 7860 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7861 if(temp != null && !temp.isEmpty()) 7862 mods.add(new Modifier("T", temp, x, y, centered)); 7863 } 7864 } 7865 else if(ss == SymbolID.SymbolSet_Air || 7866 ss == SymbolID.SymbolSet_AirMissile) 7867 { 7868 //No top center label 7869 7870 7871 //Do right side labels 7872 x = 1;//on right 7873 centered = false; 7874 7875 centered = true; 7876 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7877 { 7878 y = 0;//center 7879 centered = true;//vertically centered, only matters for labels on left and right side 7880 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 7881 if(temp != null && !temp.isEmpty()) 7882 mods.add(new Modifier("V", temp, x, y, centered)); 7883 } 7884 else if(!strict) 7885 { 7886 //if no "H', bring G and M closer to the center 7887 centered = false; 7888 } 7889 7890 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7891 { 7892 y = 1;//above center 7893 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 7894 7895 if(temp != null && !temp.isEmpty()) 7896 mods.add(new Modifier("P", temp, x, y, centered)); 7897 } 7898 7899 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 7900 { 7901 y = 2; 7902 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7903 y--; 7904 temp = ""; 7905 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7906 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 7907 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7908 temp += modifiers.get(Modifiers.AS_COUNTRY); 7909 temp = temp.trim(); 7910 7911 if(temp != null && !temp.isEmpty()) 7912 mods.add(new Modifier("T AS", temp, x, y, centered)); 7913 } 7914 7915 if(modifiers.containsKey(Modifiers.Z_SPEED) || 7916 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7917 { 7918 y = -1;//below center 7919 7920 temp = ""; 7921 if(modifiers.containsKey(Modifiers.Z_SPEED)) 7922 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 7923 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7924 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 7925 temp = temp.trim(); 7926 7927 if(temp != null && !temp.isEmpty()) 7928 mods.add(new Modifier("Z X", temp, x, y, centered)); 7929 } 7930 7931 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 7932 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7933 { 7934 y = -2; 7935 if(!strict) 7936 { 7937 if(!(modifiers.containsKey(Modifiers.Z_SPEED) || 7938 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 7939 y++; 7940 } 7941 temp = ""; 7942 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7943 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 7944 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7945 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7946 temp = temp.trim(); 7947 if(temp != null && !temp.isEmpty()) 7948 mods.add(new Modifier("G H", temp, x, y, centered)); 7949 } 7950 7951 //No left side labels 7952 7953 } 7954 else if(ss == SymbolID.SymbolSet_Space || 7955 ss == SymbolID.SymbolSet_SpaceMissile) 7956 { 7957 //No top center label 7958 7959 7960 //Do right side labels 7961 x = 1;//on right 7962 centered = false; 7963 7964 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7965 { 7966 y = 1;//above center 7967 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 7968 if(temp != null && !temp.isEmpty()) 7969 mods.add(new Modifier("V", temp, x, y, centered)); 7970 } 7971 7972 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 7973 { 7974 y = 2; 7975 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7976 y--; 7977 temp = ""; 7978 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7979 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 7980 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7981 temp += modifiers.get(Modifiers.AS_COUNTRY); 7982 temp = temp.trim(); 7983 7984 if(temp != null && !temp.isEmpty()) 7985 mods.add(new Modifier("T AS", temp, x, y, centered)); 7986 } 7987 7988 if(modifiers.containsKey(Modifiers.Z_SPEED) || 7989 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7990 { 7991 y = -1;//below center 7992 temp = ""; 7993 if(modifiers.containsKey(Modifiers.Z_SPEED)) 7994 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 7995 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7996 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 7997 temp = temp.trim(); 7998 7999 if(temp != null && !temp.isEmpty()) 8000 mods.add(new Modifier("Z X", temp, x, y, centered)); 8001 } 8002 8003 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 8004 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8005 { 8006 y = -2; 8007 if(!strict && 8008 !(modifiers.containsKey(Modifiers.Z_SPEED) || modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 8009 y++; 8010 temp = ""; 8011 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 8012 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 8013 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8014 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 8015 temp = temp.trim(); 8016 if(temp != null && !temp.isEmpty()) 8017 mods.add(new Modifier("G H", temp, x, y, centered)); 8018 } 8019 8020 //No left side labels 8021 } 8022 else if(ss == SymbolID.SymbolSet_SeaSurface) 8023 { 8024 //No top center label 8025 8026 8027 //Do right side labels 8028 x = 1;//on right 8029 centered = true; 8030 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 8031 { 8032 y = 0;//center 8033 centered = true;//vertically centered, only matters for labels on left and right side 8034 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 8035 if(temp != null && !temp.isEmpty()) 8036 mods.add(new Modifier("P", temp, x, y, centered)); 8037 } 8038 else if(!strict) 8039 { 8040 //if no "X', bring V and G closer to the center 8041 centered = false; 8042 } 8043 8044 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 8045 { 8046 y = 1;//above center 8047 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 8048 if(temp != null && !temp.isEmpty()) 8049 mods.add(new Modifier("V", temp, x, y, centered)); 8050 } 8051 8052 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 8053 { 8054 y = 2; 8055 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 8056 y--; 8057 temp = ""; 8058 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 8059 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 8060 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 8061 temp += modifiers.get(Modifiers.AS_COUNTRY); 8062 temp = temp.trim(); 8063 8064 if(temp != null && !temp.isEmpty()) 8065 mods.add(new Modifier("T AS", temp, x, y, centered)); 8066 } 8067 8068 8069 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 8070 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8071 { 8072 y = -1;//below center 8073 temp = ""; 8074 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 8075 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 8076 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8077 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 8078 temp = temp.trim(); 8079 8080 if(temp != null && !temp.isEmpty()) 8081 mods.add(new Modifier("G H", temp, x, y, centered)); 8082 } 8083 8084 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 8085 modifiers.containsKey(Modifiers.Z_SPEED)) 8086 { 8087 y = -2; 8088 if(!strict && 8089 !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 8090 y++; 8091 temp = ""; 8092 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 8093 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 8094 if(modifiers.containsKey(Modifiers.Z_SPEED)) 8095 temp += modifiers.get(Modifiers.Z_SPEED); 8096 temp = temp.trim(); 8097 if(temp != null && !temp.isEmpty()) 8098 mods.add(new Modifier("Y Z", temp, x, y, centered)); 8099 } 8100 8101 //No left side labels 8102 x = -1; 8103 centered = false; 8104 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) || 8105 modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 8106 { 8107 y = 2; 8108 if(!strict) 8109 { 8110 y--; 8111 } 8112 temp = ""; 8113 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 8114 temp = modifiers.get(Modifiers.AQ_GUARDED_UNIT) + sep; 8115 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 8116 temp += modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 8117 temp = temp.trim(); 8118 if(temp != null && !temp.isEmpty()) 8119 mods.add(new Modifier("AQ AR", temp, x, y, centered)); 8120 } 8121 } 8122 else if(ss == SymbolID.SymbolSet_SeaSubsurface) 8123 { 8124 //No top center label 8125 8126 8127 //Do right side labels 8128 x = 1;//on right 8129 centered = true; 8130 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 8131 { 8132 y = 0;//center 8133 centered = true;//vertically centered, only matters for labels on left and right side 8134 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 8135 if(temp != null && !temp.isEmpty()) 8136 mods.add(new Modifier("X", temp, x, y, centered)); 8137 } 8138 else if(!strict) 8139 { 8140 //if no "H', bring G and M closer to the center 8141 centered = false; 8142 } 8143 8144 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 8145 { 8146 y = 1;//center 8147 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 8148 if(temp != null && !temp.isEmpty()) 8149 mods.add(new Modifier("V", temp, x, y, centered)); 8150 } 8151 8152 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 8153 { 8154 y = 2; 8155 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 8156 y--; 8157 temp = ""; 8158 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 8159 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 8160 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 8161 temp += modifiers.get(Modifiers.AS_COUNTRY); 8162 temp = temp.trim(); 8163 8164 if(temp != null && !temp.isEmpty()) 8165 mods.add(new Modifier("T AS", temp, x, y, centered)); 8166 } 8167 8168 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 8169 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8170 { 8171 y = -1;//below center 8172 8173 temp = ""; 8174 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 8175 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 8176 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8177 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 8178 temp = temp.trim(); 8179 8180 if(temp != null && !temp.isEmpty()) 8181 mods.add(new Modifier("G H", temp, x, y, centered)); 8182 } 8183 8184 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 8185 modifiers.containsKey(Modifiers.Z_SPEED)) 8186 { 8187 y = -2; 8188 if(!strict) 8189 { 8190 if(!(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 8191 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 8192 y++; 8193 } 8194 temp = ""; 8195 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 8196 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 8197 if(modifiers.containsKey(Modifiers.Z_SPEED)) 8198 temp += modifiers.get(Modifiers.Z_SPEED); 8199 temp = temp.trim(); 8200 if(temp != null && !temp.isEmpty()) 8201 mods.add(new Modifier("Y Z", temp, x, y, centered)); 8202 } 8203 8204 //No left side labels 8205 x = -1; 8206 centered = false; 8207 8208 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 8209 { 8210 y = 2; 8211 if(!strict && !modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 8212 { 8213 y--; 8214 } 8215 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 8216 temp = temp.trim(); 8217 if(temp != null && !temp.isEmpty()) 8218 mods.add(new Modifier("AR", temp, x, y, centered)); 8219 } 8220 } 8221 else if(ss == SymbolID.SymbolSet_DismountedIndividuals) 8222 { 8223 //Do bottom center label 8224 x = 0;//centered 8225 y = -9;//on bottom of symbol 8226 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 8227 { 8228 temp = modifiers.get(Modifiers.C_QUANTITY); 8229 if(temp != null && !temp.isEmpty()) 8230 mods.add(new Modifier("C", temp, x, y, centered)); 8231 } 8232 8233 //Do right side labels 8234 x = 1;//on right 8235 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8236 { 8237 y = 0;//center 8238 centered = true;//vertically centered, only matters for labels on left and right side 8239 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 8240 8241 if(temp != null && !temp.isEmpty()) 8242 mods.add(new Modifier("H", temp, x, y, centered)); 8243 } 8244 else if(!strict) 8245 { 8246 centered = false; 8247 } 8248 8249 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 8250 { 8251 y = 1;//above center 8252 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 8253 8254 if(temp != null && !temp.isEmpty()) 8255 mods.add(new Modifier("G", temp, x, y, centered)); 8256 } 8257 8258 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 8259 { 8260 y = 2; 8261 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))) 8262 y--; 8263 temp = modifiers.get(Modifiers.AS_COUNTRY); 8264 8265 if(temp != null && !temp.isEmpty()) 8266 mods.add(new Modifier("AS", temp, x, y, centered)); 8267 } 8268 8269 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 8270 { 8271 y = -1;//below center 8272 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 8273 if(temp != null && !temp.isEmpty()) 8274 mods.add(new Modifier("M", temp, x, y, centered)); 8275 } 8276 8277 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 8278 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 8279 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 8280 { 8281 y = -2; 8282 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 8283 y++; 8284 temp = ""; 8285 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 8286 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 8287 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 8288 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 8289 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 8290 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 8291 temp = temp.trim(); 8292 if(temp != null && !temp.isEmpty()) 8293 mods.add(new Modifier("J K P", temp, x, y, centered)); 8294 } 8295 8296 //Do left side labels 8297 x = -1;//on left 8298 8299 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 8300 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 8301 { 8302 y = 0;//center 8303 centered = true;//vertically centered, only matters for labels on left and right side 8304 8305 temp = ""; 8306 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 8307 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 8308 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 8309 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 8310 temp = temp.trim(); 8311 if(temp != null && !temp.isEmpty()) 8312 mods.add(new Modifier("V AF", temp, x, y, centered)); 8313 } 8314 else if(!strict) 8315 { 8316 centered = false; 8317 } 8318 8319 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 8320 { 8321 y = 1; 8322 temp = ""; 8323 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 8324 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 8325 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 8326 temp += modifiers.get(Modifiers.Y_LOCATION); 8327 8328 temp = temp.trim(); 8329 mods.add(new Modifier("X Y", temp, x, y, centered)); 8330 } 8331 8332 if(modifiers.containsKey(Modifiers.W_DTG_1)) 8333 { 8334 y = 2;//above center 8335 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 8336 y--; 8337 8338 temp = modifiers.get(Modifiers.W_DTG_1); 8339 8340 if(temp != null && !temp.isEmpty()) 8341 mods.add(new Modifier("W", temp, x, y, centered)); 8342 } 8343 8344 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 8345 { 8346 y = -1;//below center 8347 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 8348 8349 if(temp != null && !temp.isEmpty()) 8350 mods.add(new Modifier("T", temp, x, y, centered)); 8351 } 8352 8353 if(modifiers.containsKey(Modifiers.Z_SPEED)) 8354 { 8355 y = -2; 8356 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 8357 y++; 8358 temp = modifiers.get(Modifiers.Z_SPEED); 8359 if(temp != null && !temp.isEmpty()) 8360 mods.add(new Modifier("Z", temp, x, y, centered)); 8361 } 8362 } 8363 else if(ss == SymbolID.SymbolSet_Activities) 8364 { 8365 //No top center label 8366 8367 //Do right side labels 8368 x = 1;//on right 8369 centered = false; 8370 8371 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 8372 { 8373 y = 1; 8374 8375 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 8376 if(temp != null && !temp.isEmpty()) 8377 mods.add(new Modifier("G", temp, x, y, centered)); 8378 } 8379 8380 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 8381 { 8382 y = 2; 8383 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 8384 y--; 8385 temp = modifiers.get(Modifiers.AS_COUNTRY); 8386 8387 if(temp != null && !temp.isEmpty()) 8388 mods.add(new Modifier("AS", temp, x, y, centered)); 8389 } 8390 8391 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8392 { 8393 y = -1;//below center 8394 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 8395 if(temp != null && !temp.isEmpty()) 8396 mods.add(new Modifier("H", temp, x, y, centered)); 8397 } 8398 8399 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 8400 { 8401 y = -2; 8402 if(!strict && !modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8403 y++; 8404 temp = temp = modifiers.get(Modifiers.J_EVALUATION_RATING); 8405 8406 if(temp != null && !temp.isEmpty()) 8407 mods.add(new Modifier("J", temp, x, y, centered)); 8408 } 8409 8410 //Do left side labels 8411 x = -1;//on left 8412 centered = false; 8413 8414 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 8415 { 8416 y = 1; 8417 temp = modifiers.get(Modifiers.Y_LOCATION); 8418 8419 if(temp != null && !temp.isEmpty()) 8420 mods.add(new Modifier("Y", temp, x, y, centered)); 8421 } 8422 8423 if(modifiers.containsKey(Modifiers.W_DTG_1)) 8424 { 8425 y = 2;//above center 8426 if(!strict && !modifiers.containsKey(Modifiers.Y_LOCATION)) 8427 y--; 8428 temp = modifiers.get(Modifiers.W_DTG_1); 8429 if(temp != null && !temp.isEmpty()) 8430 mods.add(new Modifier("W", temp, x, y, centered)); 8431 } 8432 8433 } 8434 else if(ss == SymbolID.SymbolSet_CyberSpace) 8435 { 8436 //Do top center label 8437 x = 0;//centered 8438 y = 9;//on top of symbol 8439 if(modifiers.containsKey(Modifiers.B_ECHELON)) 8440 { 8441 temp = modifiers.get(Modifiers.B_ECHELON); 8442 if(temp != null && !temp.isEmpty()) 8443 mods.add(new Modifier("B", temp, x, y, centered)); 8444 } 8445 8446 //Do right side labels 8447 x = 1;//on right 8448 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 8449 { 8450 y = 0;//center 8451 centered = true;//vertically centered, only matters for labels on left and right side 8452 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 8453 8454 if(temp != null && !temp.isEmpty()) 8455 mods.add(new Modifier("H", temp, x, y, centered)); 8456 } 8457 else if(!strict) 8458 { 8459 centered = false; 8460 } 8461 8462 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 8463 { 8464 y = 1;//above center 8465 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 8466 8467 if(temp != null && !temp.isEmpty()) 8468 mods.add(new Modifier("G", temp, x, y, centered)); 8469 } 8470 8471 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 8472 { 8473 y = 2; 8474 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))) 8475 y--; 8476 temp = ""; 8477 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 8478 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 8479 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 8480 temp += modifiers.get(Modifiers.AS_COUNTRY); 8481 temp = temp.trim(); 8482 if(temp != null && !temp.isEmpty()) 8483 mods.add(new Modifier("F AS", temp, x, y, centered)); 8484 } 8485 8486 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 8487 { 8488 y = -1;//below center 8489 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 8490 if(temp != null && !temp.isEmpty()) 8491 mods.add(new Modifier("M", temp, x, y, centered)); 8492 } 8493 8494 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 8495 { 8496 y = -2; 8497 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 8498 y++; 8499 temp = ""; 8500 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 8501 temp = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 8502 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 8503 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 8504 temp = temp.trim(); 8505 if(temp != null && !temp.isEmpty()) 8506 mods.add(new Modifier("K L", temp, x, y, centered)); 8507 } 8508 8509 //Do left side labels 8510 x=-1; 8511 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 8512 { 8513 y = 0;//center 8514 centered = true;//vertically centered, only matters for labels on left and right side 8515 8516 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 8517 8518 if(temp != null && !temp.isEmpty()) 8519 mods.add(new Modifier("V", temp, x, y, centered)); 8520 } 8521 else if(!strict) 8522 { 8523 centered = false; 8524 } 8525 8526 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 8527 { 8528 y = 1; 8529 temp = modifiers.get(Modifiers.Y_LOCATION); 8530 8531 if(temp != null && !temp.isEmpty()) 8532 mods.add(new Modifier("Y", temp, x, y, centered)); 8533 } 8534 8535 if(modifiers.containsKey(Modifiers.W_DTG_1)) 8536 { 8537 y = 2;//above center 8538 if(!strict && !(modifiers.containsKey(Modifiers.Y_LOCATION))) 8539 y--; 8540 8541 temp = modifiers.get(Modifiers.W_DTG_1); 8542 8543 if(temp != null && !temp.isEmpty()) 8544 mods.add(new Modifier("W", temp, x, y, centered)); 8545 } 8546 8547 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 8548 { 8549 y = -1;//below center 8550 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 8551 8552 if(temp != null && !temp.isEmpty()) 8553 mods.add(new Modifier("T", temp, x, y, centered)); 8554 } 8555 } 8556 /*else if(ver == SymbolID.SymbolSet_MineWarfare) 8557 { 8558 //no modifiers 8559 }//*/ 8560 //else//SymbolSet Unknown 8561 //processUnknownTextModifiers 8562 } 8563 8564 return mods; 8565 } 8566 8567 8568 /** 8569 * @param bounds bounds of the core icon 8570 * @param labelWidth height of the label to be placed 8571 * @param location -1 left, 0 center, 1 right 8572 * @returns 8573 */ 8574 private static double getLabelXPosition(Rect bounds, int labelWidth, int location, float modifierFontHeight) 8575 { 8576 int buffer = (int)modifierFontHeight/2; 8577 8578 double x = 0; 8579 if(location == 1)//on right 8580 { 8581 x = bounds.left + bounds.width() + buffer; 8582 } 8583 else if(location == -1)//left 8584 { 8585 x = bounds.left - labelWidth - buffer; 8586 } 8587 else if(location == 0) 8588 { 8589 x = Math.round((bounds.left + (bounds.width() * 0.5f)) - (labelWidth * 0.5f)); 8590 } 8591 return x; 8592 } 8593 8594 /** 8595 * 8596 * @param bounds bounds of the core icon 8597 * @param labelHeight height of the label to be placed 8598 * @param descent descent of the label to be placed 8599 * @param bufferText spacing buffer if desired 8600 * @param centered if true, there will be a center label location identified by 0 8601 * @param location positive 1, 2, 3 to be above symbol mid-point or negative values to be below 8602 * @returns y position 8603 */ 8604 private static double getLabelYPosition(Rect bounds, int labelHeight, int descent, int bufferText, boolean centered, int location) { 8605 double y = 0; 8606 if (bounds != null && !bounds.isEmpty()) 8607 { 8608 if(centered) 8609 { 8610 switch (location) 8611 { 8612 case 3://3 above center 8613 y = (bounds.height()); 8614 y = ((y * 0.5) + (labelHeight * 0.5)); 8615 y = y - ((labelHeight + bufferText) * 3); 8616 y = bounds.top + y; 8617 break; 8618 case 2://2 above center 8619 y = (bounds.height()); 8620 y = ((y * 0.5) + (labelHeight * 0.5)); 8621 y = y - ((labelHeight + bufferText) * 2); 8622 y = bounds.top + y; 8623 break; 8624 case 1://1 above center 8625 y = (bounds.height()); 8626 y = ((y * 0.5) + (labelHeight * 0.5)); 8627 y = y - ((labelHeight + bufferText)); 8628 y = bounds.top + y; 8629 break; 8630 case 0: //centered 8631 y = (bounds.height()); 8632 y = ((y * 0.5) + ((labelHeight - descent) * 0.5)); 8633 y = bounds.top + y; 8634 break; 8635 case -1://1 below center 8636 y = (bounds.height()); 8637 y = ((y * 0.5) + (labelHeight * 0.5)); 8638 y = y + ((labelHeight + bufferText - descent)); 8639 y = bounds.top + y; 8640 break; 8641 case -2://2 below center 8642 y = (bounds.height()); 8643 y = ((y * 0.5) + (labelHeight * 0.5)); 8644 y = y + ((labelHeight + bufferText) * 2) - (descent); 8645 y = bounds.top + y; 8646 break; 8647 case -3://3 below center 8648 y = (bounds.height()); 8649 y = ((y * 0.5) + (labelHeight * 0.5)); 8650 y = y + ((labelHeight + bufferText) * 3) - (descent); 8651 y = bounds.top + y; 8652 break; 8653 } 8654 } 8655 else//split between top and bottom 8656 { 8657 switch (location) 8658 { 8659 case 3: 8660 y = (bounds.top + ((bounds.height() / 2) - descent - labelHeight*2 - bufferText)); 8661 break; 8662 case 2: 8663 y = (bounds.top + ((bounds.height() / 2) - descent - labelHeight - bufferText)); 8664 break; 8665 case 1: 8666 y = (bounds.top + ((bounds.height() / 2) - descent)); 8667 break; 8668 case -1: 8669 y = (bounds.top + (bounds.height() / 2) + (labelHeight - descent + bufferText)); 8670 break; 8671 case -2: 8672 y = (bounds.top + (bounds.height() / 2) + ((labelHeight*2 - descent + bufferText))); 8673 break; 8674 case -3: 8675 y = (bounds.top + (bounds.height() / 2) + ((labelHeight*3 - descent + bufferText))); 8676 break; 8677 } 8678 } 8679 if(location == 9)//on top of symbol 8680 { 8681 y = Math.round(bounds.top - bufferText - descent); 8682 } 8683 if(location == -9)//on bottom of symbol 8684 { 8685 y = (int)Math.round(bounds.top + bounds.height() + bufferText + labelHeight - descent); 8686 } 8687 } 8688 return y; 8689 } 8690 8691 /** 8692 * Currently, modifiers are based on Symbol Set. 8693 * The exception is SIGINT which required a frame shape value in 2525E+ 8694 * The SSMC couldn't come to an agreement on if frame shape should dictate modifiers. 8695 * Currently, I'm keeping it tied to Symbol Set. 8696 * @param symbolID 8697 * @return 8698 */ 8699 private static boolean isCOnTop(String symbolID) 8700 { 8701 boolean onTop = false; 8702 8703 int version = SymbolID.getVersion(symbolID); 8704 int ss = SymbolID.getSymbolSet(symbolID); 8705 char frame = SymbolID.getFrameShape(symbolID); 8706 8707 if(SymbolUtilities.hasModifier(symbolID,Modifiers.C_QUANTITY)) { 8708 8709 if(version >= SymbolID.Version_2525E) 8710 { 8711 8712 if (ss == SymbolID.SymbolSet_Air || 8713 ss == SymbolID.SymbolSet_AirMissile || 8714 ss == SymbolID.SymbolSet_Space || 8715 ss == SymbolID.SymbolSet_SpaceMissile || 8716 ss == SymbolID.SymbolSet_LandEquipment) 8717 { 8718 onTop = true; 8719 } 8720 else if(ss == SymbolID.SymbolSet_SignalsIntelligence && 8721 (frame == SymbolID.FrameShape_Air || 8722 frame == SymbolID.FrameShape_Space || 8723 frame == SymbolID.FrameShape_LandEquipment || frame == SymbolID.FrameShape_LandUnit || frame == '0')) 8724 { 8725 onTop = true; 8726 } 8727 8728 }// else if <= SymbolID.Version_2525Dch1 8729 else if (ss == SymbolID.SymbolSet_LandEquipment || 8730 ss == SymbolID.SymbolSet_SignalsIntelligence_Land) 8731 { 8732 onTop = true; 8733 } 8734 } 8735 return onTop; 8736 } 8737 public static boolean hasDisplayModifiers(String symbolID, Map<String,String> modifiers) 8738 { 8739 boolean hasModifiers = false; 8740 int ss = SymbolID.getSymbolSet(symbolID); 8741 int status = SymbolID.getStatus(symbolID); 8742 int context = SymbolID.getContext(symbolID); 8743 8744 if(ss == SymbolID.SymbolSet_ControlMeasure)//check control measure 8745 { 8746 if (SymbolUtilities.isCBRNEvent(symbolID) == true && modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT)) 8747 { 8748 hasModifiers = true; 8749 } 8750 else if(SymbolUtilities.hasFDI(symbolID)) 8751 hasModifiers = true; 8752 } 8753 else if(ss != SymbolID.SymbolSet_Atmospheric && 8754 ss != SymbolID.SymbolSet_Oceanographic && 8755 ss != SymbolID.SymbolSet_MeteorologicalSpace) 8756 {//checking units 8757 8758 if(context > 0) //Exercise or Simulation 8759 hasModifiers = true; 8760 8761 //echelon or mobility, 8762 if (SymbolID.getAmplifierDescriptor(symbolID) > 0 || modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT)) 8763 hasModifiers = true; 8764 8765 if(modifiers.containsKey(Modifiers.AJ_SPEED_LEADER)) 8766 hasModifiers = true; 8767 8768 if(modifiers.containsKey(Modifiers.AO_ENGAGEMENT_BAR)) 8769 hasModifiers = true; 8770 8771 //HQ/Taskforce 8772 if(SymbolID.getHQTFD(symbolID) > 0) 8773 hasModifiers = true; 8774 8775 if(status > 1)//Fully capable, damaged, destroyed 8776 hasModifiers = true; 8777 }//no display modifiers for single point weather 8778 8779 8780 8781 return hasModifiers; 8782 } 8783 8784 public static boolean hasTextModifiers(String symbolID, Map<String,String> modifiers) 8785 { 8786 8787 int ss = SymbolID.getSymbolSet(symbolID); 8788 int ec = SymbolID.getEntityCode(symbolID); 8789 if(ss == SymbolID.SymbolSet_Atmospheric) 8790 { 8791 switch(ec) 8792 { 8793 case 110102: //tropopause low 8794 case 110202: //tropopause high 8795 case 162200: //tropopause level ? 8796 case 162300: //freezing level ? 8797 return true; 8798 default: 8799 return false; 8800 } 8801 } 8802 else if(ss == SymbolID.SymbolSet_Oceanographic || ss == SymbolID.SymbolSet_MeteorologicalSpace) 8803 { 8804 return false; 8805 } 8806 else if (ss == SymbolID.SymbolSet_ControlMeasure) 8807 { 8808 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 8809 8810 if( msi.getModifiers().size() > 0 && modifiers != null && modifiers.size() > 0) 8811 return true; 8812 else 8813 return false; 8814 } 8815 else 8816 { 8817 8818 if (SymbolUtilities.getStandardIdentityModifier(symbolID) != null) 8819 { 8820 return true; 8821 } 8822 8823 int cc = SymbolID.getCountryCode(symbolID); 8824 if (cc > 0 && !GENCLookup.getInstance().get3CharCode(cc).isEmpty()) 8825 { 8826 return true; 8827 }//*/ 8828 8829 else if (modifiers.size() > 0) 8830 { 8831 return true; 8832 } 8833 } 8834 return false; 8835 } 8836 8837 /** 8838 * Rerturns either the default font from RendererSettings or font based on properties 8839 * set in MilStdAttributes. 8840 * @param attributes 8841 * @return 8842 */ 8843 private static Paint getFont(Map<String,String> attributes) 8844 { 8845 Paint p = null; 8846 Typeface tf = null; 8847 8848 p = RendererSettings.getInstance().getModiferFont(); 8849 8850 String[] props = RendererSettings.getInstance().getModiferFontProps(); 8851 8852 String ff = props[0]; 8853 int fstyle = Integer.parseInt(props[1]);// modifierFont.getTypeface().getStyle(); 8854 float fsize = Float.parseFloat(props[2]);// modifierFont.getTextSize(); 8855 String temp = null; 8856 8857 8858 if(attributes.containsKey(MilStdAttributes.FontFamily) || 8859 attributes.containsKey(MilStdAttributes.FontStyle) || 8860 attributes.containsKey(MilStdAttributes.FontSize)) 8861 { 8862 if(attributes.containsKey(MilStdAttributes.FontStyle)) 8863 { 8864 temp = attributes.get(MilStdAttributes.FontStyle); 8865 if (temp != null && !temp.isEmpty()) { 8866 fstyle = Integer.parseInt(temp); 8867 } 8868 } 8869 if(attributes.containsKey(MilStdAttributes.FontSize)) 8870 { 8871 temp = attributes.get(MilStdAttributes.FontSize); 8872 if (temp != null && !temp.isEmpty()) { 8873 fsize = Float.parseFloat(temp); 8874 } 8875 } 8876 if(attributes.containsKey(MilStdAttributes.FontFamily)) 8877 { 8878 temp = attributes.get(MilStdAttributes.FontFamily); 8879 if (temp != null && !temp.isEmpty()) { 8880 ff = temp;//Typeface.create(temp,fstyle); 8881 } 8882 } 8883 tf = Typeface.create(ff,fstyle); 8884 if(tf == null) 8885 tf = Typeface.create(props[0],fstyle); 8886 if(tf == null) 8887 return null; 8888 8889 p = new Paint(); 8890 p.setTextSize(fsize); 8891 p.setAntiAlias(true); 8892 p.setTypeface(tf); 8893 p.setStrokeCap(Cap.BUTT); 8894 p.setStrokeJoin(Join.MITER); 8895 p.setStrokeMiter(3f); 8896 8897 return p; 8898 } 8899 else 8900 return _modifierFont; 8901 8902 } 8903 8904 private static float[] getFontHeightandDescent(Paint font) 8905 { 8906 float[] hd = {0f,0f}; 8907 8908 if(font != null) { 8909 Paint.FontMetrics fm = font.getFontMetrics(); 8910 //_modifierFontHeight = fm.top + fm.bottom; 8911 hd[0] = fm.bottom - fm.top; 8912 hd[1] = fm.descent; 8913 } 8914 return hd; 8915 } 8916 8917}