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.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.containsKey(Modifiers.AJ_SPEED_LEADER))) { 2305 String aj = modifiers.get(Modifiers.AJ_SPEED_LEADER); 2306 String[] values = aj.split(" "); 2307 if (values.length >= 3) { 2308 int speed = Integer.parseInt(values[0]); 2309 String speedUnit = values[1]; 2310 int angle = 0; 2311 if (values[2].length() == 3) 2312 angle = Integer.parseInt(values[2]) - 90; 2313 else 2314 angle = (int) (Integer.parseInt(values[2]) * 0.05625) - 90; 2315 2316 slPath = new Path(); 2317 slPath.moveTo(symbolCenter.x, symbolCenter.y); 2318 slsvgPath = new SVGPath(); 2319 slsvgPath.moveTo(symbolCenter.x, symbolCenter.y); 2320 2321 //convert to Knots 2322 switch (speedUnit)//KPH, KPS, MPH, NMH, KTS//https://www.aviationhunt.com/speed-converter/ 2323 { 2324 case "KPH": 2325 speed = (int) (speed * 0.539957); 2326 break; 2327 case "KPS"://https://www.metric-conversions.org/speed/kilometers-per-second-to-knots.htm 2328 speed = (int) (speed * 1943.84); 2329 break; 2330 case "MPH": 2331 speed = (int) (speed * 0.86897); 2332 break; 2333 } 2334 2335 int distance = 0; 2336 char frame = SymbolID.getFrameShape(symbolID); 2337 boolean fast = false; 2338 if (frame == '0' && ss == SymbolID.SymbolSet_Air || 2339 ss == SymbolID.SymbolSet_AirMissile || 2340 ss == SymbolID.SymbolSet_SignalsIntelligence_Air || 2341 ss == SymbolID.SymbolSet_SpaceMissile || 2342 ss == SymbolID.SymbolSet_Space || 2343 (SymbolID.getVersion(symbolID) <= SymbolID.Version_2525Dch1 && ss == SymbolID.SymbolSet_SignalsIntelligence_Space)) 2344 { 2345 fast = true; 2346 } 2347 else if(frame == SymbolID.FrameShape_Air || frame == SymbolID.FrameShape_Space) 2348 { 2349 fast = true; 2350 } 2351 2352 float distanceScaler = dpi;//spec does scale by inch, but if the symbol is too big, scale by pixel size 2353 if(dpi < pixelSize) 2354 distanceScaler = pixelSize; 2355 2356 if(fast) 2357 {//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. 2358 if (speed < 300) 2359 distance = (int) (distanceScaler * 0.25)/300 * speed; 2360 else if (speed < 600) 2361 distance = (int) (distanceScaler * 0.5)/600 * speed; 2362 else 2363 distance = (int) (distanceScaler * 0.75); 2364 } 2365 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 2366 { 2367 if (speed < 15) 2368 distance = (int) (distanceScaler * 0.25)/15 * speed; 2369 else if (speed < 30) 2370 distance = (int) (distanceScaler * 0.5)/30 * speed; 2371 else 2372 distance = (int) (distanceScaler * 0.75); 2373 } 2374 double radians = (angle * (Math.PI / 180));//convert degrees to radians 2375 int x2 = (int) (symbolCenter.x + distance * Math.cos(radians)); 2376 int y2 = (int) (symbolCenter.y + distance * Math.sin(radians)); 2377 2378 slPath.lineTo(x2, y2); 2379 slsvgPath.lineTo(x2, y2); 2380 slBounds = slsvgPath.getBounds(); 2381 imageBounds.union(slBounds); 2382 } 2383 2384 if (sdi instanceof ImageInfo) { 2385 Bitmap bmp = Bitmap.createBitmap((int) Math.ceil(imageBounds.width()), (int) Math.ceil(imageBounds.height()), Config.ARGB_8888); 2386 Canvas ctx = new Canvas(bmp); 2387 2388 int alpha = 1; 2389 if (attributes.containsKey(MilStdAttributes.Alpha)) 2390 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 2391 2392 2393 Paint slPaint = new Paint(); 2394 slPaint.setColor(Color.BLACK.toInt()); 2395 slPaint.setAlpha(alpha * 255); 2396 slPaint.setStyle(Style.STROKE); 2397 slPaint.setStrokeWidth(strokeWidth); 2398 2399 2400 float offsetX = 0; 2401 float offsetY = 0; 2402 if (imageBounds.left < 0) 2403 offsetX = imageBounds.left * -1; 2404 if (imageBounds.top < 0) 2405 offsetY = imageBounds.top * -1; 2406 2407 slPath.offset(offsetX,offsetY); 2408 2409 ctx.drawBitmap(((ImageInfo) sdi).getImage(), offsetX, offsetY, null); 2410 ctx.drawPath(slPath,slPaint); 2411 2412 imageBounds.offset((int)offsetX,(int)offsetY); 2413 symbolBounds.offset((int)offsetX,(int)offsetY); 2414 symbolCenter.offset((int)offsetX,(int)offsetY); 2415 2416 rsdi = new ImageInfo(bmp, symbolCenter, symbolBounds); 2417 } 2418 else if (sdi instanceof SVGSymbolInfo) 2419 {//public static String Convert(Shape shape,String stroke, String fill, String strokeWidth, String strokeOpacity, String fillOpacity, String dashArray, String lineCap) 2420 String svg = ((SVGSymbolInfo) sdi).getSVG(); 2421 svg += slsvgPath.toSVGElement("#000000",strokeWidth,"none",1,1,null); 2422 //svg += (Shape2SVG.Convert(slPath, "#000000", "none", String.valueOf(strokeWidth),null,null,null, null)); 2423 rsdi = new SVGSymbolInfo(svg,symbolCenter,symbolBounds,imageBounds); 2424 } 2425 } 2426 } 2427 catch(Exception exc) 2428 { 2429 ErrorLogger.LogException("ModifierRenderer","processSpeedLineIndicator",exc); 2430 } 2431 2432 return rsdi; 2433 } 2434 2435 /** 2436 * uses 2525C layout which shows most modifiers 2437 * @param sdi 2438 * @param symbolID 2439 * @param modifiers 2440 * @param attributes 2441 * @return 2442 */ 2443 public static SymbolDimensionInfo processUnknownTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 2444 { 2445 Paint modifierFont = getFont(attributes); 2446 float[] hd = getFontHeightandDescent(modifierFont); 2447 float modifierFontHeight = hd[0]; 2448 float modifierFontDescent = hd[1]; 2449 2450 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 2451 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 2452 { 2453 String temp = attributes.get(MilStdAttributes.FontFamily); 2454 if(temp != null && !temp.isEmpty()) 2455 modifierFontName = temp; 2456 } 2457 2458 int bufferHorizontal = (int)modifierFontHeight/2; 2459 int bufferXL = bufferHorizontal; 2460 int bufferXR = bufferHorizontal; 2461 int bufferY = 2; 2462 int bufferText = 2; 2463 int x = 0; 2464 int y = 0;//best y 2465 2466 SymbolDimensionInfo newsdi = null; 2467 2468 ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size()); 2469 2470 int descent = (int) (modifierFontDescent + 0.5); 2471 2472 Rect labelBounds = null; 2473 int labelWidth, labelHeight; 2474 2475 Rect bounds = new Rect(sdi.getSymbolBounds()); 2476 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 2477 Point centerPoint = new Point(sdi.getCenterPoint()); 2478 Rect imageBounds = new Rect(sdi.getImageBounds()); 2479 2480 int echelon = SymbolID.getAmplifierDescriptor(symbolID); 2481 String echelonText = SymbolUtilities.getEchelonText(echelon); 2482 String amText = SymbolUtilities.getStandardIdentityModifier(symbolID); 2483 int mobility = SymbolID.getAmplifierDescriptor(symbolID); 2484 2485 //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol 2486 bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height()); 2487 2488 2489 //check if text is too tall: 2490 boolean byLabelHeight = false; 2491 labelHeight = (int) (modifierFontHeight + 0.5);/* RendererUtilities.measureTextHeight(RendererSettings.getModifierFontName(), 2492 RendererSettings.getModifierFontSize(), 2493 RendererSettings.getModifierFontStyle()).fullHeight;*/ 2494 2495 int maxHeight = (bounds.height()); 2496 if ((labelHeight * 3) > maxHeight) 2497 { 2498 byLabelHeight = true; 2499 } 2500 2501 //Affiliation Modifier being drawn as a display modifier 2502 String affiliationModifier = null; 2503 if (RS.getDrawAffiliationModifierAsLabel() == true) 2504 { 2505 affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID); 2506 } 2507 if (affiliationModifier != null) 2508 { //Set affiliation modifier 2509 modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier); 2510 //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier; 2511 }//*/ 2512 2513 2514 // int y0 = 0;//W E/F 2515 // int y1 = 0;//X/Y G 2516 // int y2 = 0;//V/AD/AE H/AF 2517 // int y3 = 0;//T M CC 2518 // int y4 = 0;//Z J/K/L/N/P 2519 // 2520 2521 // <editor-fold defaultstate="collapsed" desc="Build Modifiers"> 2522 String modifierValue = null; 2523 TextInfo tiTemp = null; 2524 //if(Modifiers.C_QUANTITY in modifiers 2525 if (modifiers.containsKey(Modifiers.C_QUANTITY) 2526 && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.C_QUANTITY)) 2527 { 2528 String text = modifiers.get(Modifiers.C_QUANTITY); 2529 if(text != null) 2530 { 2531 //bounds = armyc2.c5isr.renderer.utilities.RendererUtilities.getTextOutlineBounds(modifierFont, text, new SO.Point(0,0)); 2532 tiTemp = new TextInfo(text, 0, 0, modifierFont, modifierFontName); 2533 labelBounds = tiTemp.getTextBounds(); 2534 labelWidth = labelBounds.width(); 2535 x = Math.round((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f)); 2536 y = Math.round(symbolBounds.top - bufferY - descent); 2537 tiTemp.setLocation(x, y); 2538 tiArray.add(tiTemp); 2539 } 2540 } 2541 2542 //if(Modifiers.X_ALTITUDE_DEPTH in modifiers || Modifiers.Y_LOCATION in modifiers) 2543 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 2544 { 2545 modifierValue = null; 2546 2547 String xm = null, 2548 ym = null; 2549 2550 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.X_ALTITUDE_DEPTH)) 2551 { 2552 xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);// xm = modifiers.X; 2553 } 2554 if (modifiers.containsKey(Modifiers.Y_LOCATION)) 2555 { 2556 ym = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y; 2557 } 2558 if (xm == null && ym != null) 2559 { 2560 modifierValue = ym; 2561 } 2562 else if (xm != null && ym == null) 2563 { 2564 modifierValue = xm; 2565 } 2566 else if (xm != null && ym != null) 2567 { 2568 modifierValue = xm + " " + ym; 2569 } 2570 2571 if(modifierValue != null) 2572 { 2573 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2574 labelBounds = tiTemp.getTextBounds(); 2575 labelWidth = labelBounds.width(); 2576 2577 if (!byLabelHeight) 2578 { 2579 x = bounds.left - labelBounds.width() - bufferXL; 2580 y = bounds.top + labelHeight - descent; 2581 } 2582 else 2583 { 2584 x = bounds.left - labelBounds.width() - bufferXL; 2585 2586 y = (bounds.height()); 2587 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2588 2589 y = y - ((labelHeight + bufferText)); 2590 y = bounds.top + y; 2591 } 2592 2593 tiTemp.setLocation(x, y); 2594 tiArray.add(tiTemp); 2595 } 2596 } 2597 2598 if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) ) 2599 { 2600 modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS); 2601 2602 if(modifierValue != null) 2603 { 2604 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2605 labelBounds = tiTemp.getTextBounds(); 2606 labelWidth = labelBounds.width(); 2607 2608 x = bounds.left + bounds.width() + bufferXR; 2609 if (!byLabelHeight) 2610 { 2611 y = bounds.top + labelHeight - descent; 2612 } 2613 else 2614 { 2615 y = (bounds.height()); 2616 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2617 2618 y = y - ((labelHeight + bufferText)); 2619 y = bounds.top + y; 2620 } 2621 2622 tiTemp.setLocation(x, y); 2623 tiArray.add(tiTemp); 2624 2625 } 2626 } 2627 2628 if ((modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) || 2629 (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) || 2630 (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))) 2631 { 2632 String vm = null, 2633 adm = null, 2634 aem = null; 2635 2636 if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.V_EQUIP_TYPE)) 2637 { 2638 vm = modifiers.get(Modifiers.V_EQUIP_TYPE); 2639 } 2640 if (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AD_PLATFORM_TYPE)) 2641 { 2642 adm = modifiers.get(Modifiers.AD_PLATFORM_TYPE); 2643 } 2644 if (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 2645 { 2646 aem = modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 2647 } 2648 2649 modifierValue = ""; 2650 if(vm != null && vm.equals("") == false) 2651 modifierValue = vm; 2652 if(adm != null && adm.equals("") == false) 2653 modifierValue += " " + adm; 2654 if(aem != null && aem.equals("") == false) 2655 modifierValue += " " + aem; 2656 2657 if(modifierValue != null) 2658 modifierValue = modifierValue.trim(); 2659 if(modifierValue != null && modifierValue.equals("") == false) 2660 { 2661 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2662 labelBounds = tiTemp.getTextBounds(); 2663 labelWidth = labelBounds.width(); 2664 2665 x = bounds.left - labelBounds.width() - bufferXL; 2666 2667 y = (bounds.height()); 2668 y = (int) ((y * 0.5f) + ((labelHeight - descent) * 0.5f)); 2669 y = bounds.top + y; 2670 2671 tiTemp.setLocation(x, y); 2672 tiArray.add(tiTemp); 2673 } 2674 } 2675 2676 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 2677 { 2678 modifierValue = ""; 2679 String hm = "", 2680 afm = ""; 2681 2682 hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 2683 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 2684 { 2685 hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 2686 } 2687 if (modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AF_COMMON_IDENTIFIER)) 2688 { 2689 afm = modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 2690 } 2691 2692 modifierValue = hm + " " + afm; 2693 modifierValue = modifierValue.trim(); 2694 2695 if(modifierValue != null && modifierValue.equals("") == false) 2696 { 2697 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2698 labelBounds = tiTemp.getTextBounds(); 2699 labelWidth = labelBounds.width(); 2700 2701 x = bounds.left + bounds.width() + bufferXR; 2702 2703 y = (bounds.height()); 2704 y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5)); 2705 y = bounds.top + y; 2706 2707 tiTemp.setLocation(x, y); 2708 tiArray.add(tiTemp); 2709 2710 } 2711 } 2712 2713 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 2714 { 2715 modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 2716 2717 if(modifierValue != null) 2718 { 2719 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2720 labelBounds = tiTemp.getTextBounds(); 2721 labelWidth = labelBounds.width(); 2722 2723 if (!byLabelHeight) 2724 { 2725 x = bounds.left - labelWidth - bufferXL; 2726 y = bounds.top + bounds.height(); 2727 } 2728 else 2729 { 2730 x = bounds.left - labelWidth - bufferXL; 2731 2732 y = (bounds.height()); 2733 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2734 2735 y = y + ((labelHeight + bufferText) - descent); 2736 y = bounds.top + y; 2737 } 2738 2739 tiTemp.setLocation(x, y); 2740 tiArray.add(tiTemp); 2741 } 2742 } 2743 2744 if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 2745 { 2746 modifierValue = ""; 2747 2748 if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.M_HIGHER_FORMATION)) 2749 { 2750 modifierValue += modifiers.get(Modifiers.M_HIGHER_FORMATION); 2751 } 2752 if (modifiers.containsKey(Modifiers.AS_COUNTRY)) 2753 { 2754 if (modifierValue.length() > 0) 2755 { 2756 modifierValue += " "; 2757 } 2758 modifierValue += modifiers.get(Modifiers.AS_COUNTRY); 2759 } 2760 2761 if(modifierValue.equals("")==false) 2762 { 2763 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2764 labelBounds = tiTemp.getTextBounds(); 2765 labelWidth = labelBounds.width(); 2766 2767 x = bounds.left + bounds.width() + bufferXR; 2768 if (!byLabelHeight) 2769 { 2770 y = bounds.top + bounds.height(); 2771 } 2772 else 2773 { 2774 y = (bounds.height()); 2775 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2776 2777 y = y + ((labelHeight + bufferText - descent)); 2778 y = bounds.top + y; 2779 } 2780 2781 tiTemp.setLocation(x, y); 2782 tiArray.add(tiTemp); 2783 2784 } 2785 } 2786 2787 if (modifiers.containsKey(Modifiers.Z_SPEED) ) 2788 { 2789 modifierValue = modifiers.get(Modifiers.Z_SPEED); 2790 2791 if(modifierValue != null) 2792 { 2793 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2794 labelBounds = tiTemp.getTextBounds(); 2795 labelWidth = labelBounds.width(); 2796 2797 x = bounds.left - labelWidth - bufferXL; 2798 if (!byLabelHeight) 2799 { 2800 y = Math.round(bounds.top + bounds.height() + labelHeight + bufferText); 2801 } 2802 else 2803 { 2804 y = (bounds.height()); 2805 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2806 2807 y = y + ((labelHeight + bufferText) * 2) - (descent * 2); 2808 y = Math.round(bounds.top + y); 2809 } 2810 2811 tiTemp.setLocation(x, y); 2812 tiArray.add(tiTemp); 2813 } 2814 } 2815 2816 if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING) 2817 || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)// 2818 || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)// 2819 || modifiers.containsKey(Modifiers.N_HOSTILE)// 2820 || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))// 2821 { 2822 modifierValue = null; 2823 2824 String jm = null, 2825 km = null, 2826 lm = null, 2827 nm = null, 2828 pm = null; 2829 2830 if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 2831 { 2832 jm = modifiers.get(Modifiers.J_EVALUATION_RATING); 2833 } 2834 if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.K_COMBAT_EFFECTIVENESS)) 2835 { 2836 km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS); 2837 } 2838 if (modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.L_SIGNATURE_EQUIP)) 2839 { 2840 lm = modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 2841 } 2842 if (modifiers.containsKey(Modifiers.N_HOSTILE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.N_HOSTILE)) 2843 { 2844 nm = modifiers.get(Modifiers.N_HOSTILE); 2845 } 2846 if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.P_IFF_SIF_AIS)) 2847 { 2848 pm = modifiers.get(Modifiers.P_IFF_SIF_AIS); 2849 } 2850 2851 modifierValue = ""; 2852 if (jm != null && jm.equals("") == false) 2853 { 2854 modifierValue = modifierValue + jm; 2855 } 2856 if (km != null && km.equals("") == false) 2857 { 2858 modifierValue = modifierValue + " " + km; 2859 } 2860 if (lm != null && lm.equals("") == false) 2861 { 2862 modifierValue = modifierValue + " " + lm; 2863 } 2864 if (nm != null && nm.equals("") == false) 2865 { 2866 modifierValue = modifierValue + " " + nm; 2867 } 2868 if (pm != null && pm.equals("") == false) 2869 { 2870 modifierValue = modifierValue + " " + pm; 2871 } 2872 2873 if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ') 2874 { 2875 modifierValue = modifierValue.substring(1); 2876 } 2877 2878 modifierValue = modifierValue.trim(); 2879 2880 if(modifierValue.equals("")==false) 2881 { 2882 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2883 labelBounds = tiTemp.getTextBounds(); 2884 labelWidth = labelBounds.width(); 2885 2886 x = bounds.left + bounds.width() + bufferXR; 2887 if (!byLabelHeight) 2888 { 2889 y = Math.round(bounds.top + bounds.height() + labelHeight + bufferText); 2890 } 2891 else 2892 { 2893 y = (bounds.height()); 2894 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2895 2896 y = y + ((labelHeight + bufferText) * 2) - (descent * 2); 2897 y = Math.round(bounds.top + y); 2898 } 2899 2900 tiTemp.setLocation(x, y); 2901 tiArray.add(tiTemp); 2902 2903 } 2904 2905 } 2906 2907 if (modifiers.containsKey(Modifiers.W_DTG_1)) 2908 { 2909 modifierValue = modifiers.get(Modifiers.W_DTG_1); 2910 2911 if(modifierValue != null) 2912 { 2913 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2914 labelBounds = tiTemp.getTextBounds(); 2915 labelWidth = labelBounds.width(); 2916 2917 if (!byLabelHeight) 2918 { 2919 x = bounds.left - labelWidth - bufferXL; 2920 y = bounds.top - bufferY - descent; 2921 } 2922 else 2923 { 2924 x = bounds.left - labelWidth - bufferXL; 2925 2926 y = (bounds.height()); 2927 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2928 2929 y = y - ((labelHeight + bufferText) * 2); 2930 y = bounds.top + y; 2931 } 2932 2933 tiTemp.setLocation(x, y); 2934 tiArray.add(tiTemp); 2935 } 2936 } 2937 2938 if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER)) 2939 { 2940 modifierValue = null; 2941 String E = null, 2942 F = null; 2943 2944 if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER)) 2945 { 2946 E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER); 2947 modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER); 2948 } 2949 if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.F_REINFORCED_REDUCED)) 2950 { 2951 F = modifiers.get(Modifiers.F_REINFORCED_REDUCED); 2952 } 2953 2954 if (E != null && E.equals("") == false) 2955 { 2956 modifierValue = E; 2957 } 2958 2959 if (F != null && F.equals("") == false) 2960 { 2961 if (F.toUpperCase(Locale.US) == ("R")) 2962 { 2963 F = "(+)"; 2964 } 2965 else if (F.toUpperCase(Locale.US) == ("D")) 2966 { 2967 F = "(-)"; 2968 } 2969 else if (F.toUpperCase(Locale.US) == ("RD")) 2970 { 2971 F = "(" + (char) (177) + ")"; 2972 } 2973 } 2974 2975 if (F != null && F.equals("") == false) 2976 { 2977 if (modifierValue != null && modifierValue.equals("") == false) 2978 { 2979 modifierValue = modifierValue + " " + F; 2980 } 2981 else 2982 { 2983 modifierValue = F; 2984 } 2985 } 2986 2987 if(modifierValue != null) 2988 { 2989 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 2990 labelBounds = tiTemp.getTextBounds(); 2991 labelWidth = labelBounds.width(); 2992 2993 if (!byLabelHeight) 2994 { 2995 x = bounds.left + bounds.width() + bufferXR; 2996 y = bounds.top - bufferY - descent; 2997 } 2998 else 2999 { 3000 x = bounds.left + bounds.width() + bufferXR; 3001 3002 y = (bounds.height()); 3003 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 3004 3005 y = y - ((labelHeight + bufferText) * 2); 3006 y = bounds.top + y; 3007 } 3008 3009 tiTemp.setLocation(x, y); 3010 tiArray.add(tiTemp); 3011 3012 } 3013 } 3014 3015 if (modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AA_SPECIAL_C2_HQ)) 3016 { 3017 modifierValue = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ); 3018 3019 if(modifierValue != null) 3020 { 3021 tiTemp = new TextInfo(modifierValue, 0, 0, modifierFont, modifierFontName); 3022 labelBounds = tiTemp.getTextBounds(); 3023 labelWidth = labelBounds.width(); 3024 3025 x = (int) ((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f)); 3026 3027 y = (symbolBounds.height());//checkpoint, get box above the point 3028 y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5)); 3029 y = symbolBounds.top + y; 3030 3031 tiTemp.setLocation(x, y); 3032 tiArray.add(tiTemp); 3033 } 3034 } 3035 3036 3037 // </editor-fold> 3038 3039 //Shift Points and Draw 3040 newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes, modifierFont); 3041 3042 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 3043 tiArray = null; 3044 tiTemp = null; 3045 //tempShape = null; 3046 //ctx = null; 3047 //buffer = null; 3048 // </editor-fold> 3049 3050 return newsdi; 3051 } 3052 3053 3054 public static SymbolDimensionInfo processSPTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 3055 { 3056 Paint modifierFont = getFont(attributes); 3057 float[] hd = getFontHeightandDescent(modifierFont); 3058 float modifierFontHeight = hd[0]; 3059 float modifierFontDescent = hd[1]; 3060 3061 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 3062 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 3063 { 3064 String temp = attributes.get(MilStdAttributes.FontFamily); 3065 if(temp != null && !temp.isEmpty()) 3066 modifierFontName = temp; 3067 } 3068 3069 int bufferXL = 7; 3070 int bufferXR = 7; 3071 int bufferY = 2; 3072 int bufferText = 2; 3073 int x = 0; 3074 int y = 0;//best y 3075 SymbolDimensionInfo newsdi = null; 3076 3077 ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size()); 3078 3079 int descent = (int) (modifierFontDescent + 0.5); 3080 3081 3082 Rect labelBounds = null; 3083 int labelWidth, labelHeight; 3084 3085 Rect bounds = new Rect(sdi.getSymbolBounds()); 3086 Rect imageBounds = new Rect(sdi.getImageBounds()); 3087 3088 //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol 3089 bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height()); 3090 3091 labelHeight = (int) (modifierFontHeight + 0.5); 3092 3093 //Affiliation Modifier being drawn as a display modifier 3094 String affiliationModifier = null; 3095 if (RS.getDrawAffiliationModifierAsLabel() == true) 3096 { 3097 affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID); 3098 } 3099 if (affiliationModifier != null) 3100 { //Set affiliation modifier 3101 modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier); 3102 //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier; 3103 }//*/ 3104 3105 //Check for Valid Country Code 3106 int cc = SymbolID.getCountryCode(symbolID); 3107 String scc = ""; 3108 if(cc > 0) 3109 { 3110 scc = GENCLookup.getInstance().get3CharCode(cc); 3111 } 3112 if(!scc.isEmpty()) 3113 modifiers.put(Modifiers.AS_COUNTRY, scc); 3114 3115 // <editor-fold defaultstate="collapsed" desc="Build Modifiers"> 3116 String modifierValue = null; 3117 TextInfo tiTemp = null; 3118 3119 3120 List<Modifier> mods = getLabelPositionIndexes(symbolID, modifiers, attributes); 3121 3122 Modifier mod = null; 3123 if(mods != null) { 3124 for (int i = 0; i < mods.size(); i++) { 3125 mod = mods.get(i); 3126 3127 tiTemp = new TextInfo(mod.getText(), 0, 0, modifierFont, modifierFontName); 3128 labelBounds = tiTemp.getTextBounds(); 3129 labelWidth = (int) labelBounds.width(); 3130 3131 //on left 3132 x = (int) getLabelXPosition(bounds, labelWidth, mod.getIndexX(), modifierFontHeight); 3133 //above center V 3134 y = (int) getLabelYPosition(bounds, labelHeight, descent, bufferText, mod.getCentered(), mod.getIndexY()); 3135 3136 tiTemp.setLocation(x, y); 3137 tiArray.add(tiTemp); 3138 } 3139 } 3140 3141 3142 // </editor-fold> 3143 3144 //Shift Points and Draw 3145 newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes, modifierFont); 3146 3147 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 3148 tiArray = null; 3149 tiTemp = null; 3150 //tempShape = null; 3151 //ctx = null; 3152 //buffer = null; 3153 // </editor-fold> 3154 3155 return newsdi; 3156 } 3157 3158 public static SymbolDimensionInfo ProcessTGSPWithSpecialModifierLayout(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes, Color lineColor) 3159 { 3160 Paint modifierFont = getFont(attributes); 3161 float[] hd = getFontHeightandDescent(modifierFont); 3162 float modifierFontHeight = hd[0]; 3163 float modifierFontDescent = hd[1]; 3164 3165 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 3166 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 3167 { 3168 String temp = attributes.get(MilStdAttributes.FontFamily); 3169 if(temp != null && !temp.isEmpty()) 3170 modifierFontName = temp; 3171 } 3172 3173 ImageInfo ii = null; 3174 SVGSymbolInfo ssi = null; 3175 3176 int bufferXL = 6; 3177 int bufferXR = 4; 3178 int bufferY = 2; 3179 int bufferText = 2; 3180 int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel 3181 int x = 0; 3182 int y = 0; 3183 int x2 = 0; 3184 int y2 = 0; 3185 3186 int outlineOffset = RS.getTextOutlineWidth(); 3187 int labelHeight = 0; 3188 int labelWidth = 0; 3189 int alpha = -1; 3190 SymbolDimensionInfo newsdi = null; 3191 Color textColor = lineColor; 3192 Color textBackgroundColor = null; 3193 int ss = SymbolID.getSymbolSet(symbolID); 3194 int ec = SymbolID.getEntityCode(symbolID); 3195 int e = SymbolID.getEntity(symbolID); 3196 int et = SymbolID.getEntityType(symbolID); 3197 int est = SymbolID.getEntitySubtype(symbolID); 3198 3199 //Feint Dummy Indicator variables 3200 Rect fdiBounds = null; 3201 Point fdiTop = null; 3202 Point fdiLeft = null; 3203 Point fdiRight = null; 3204 3205 ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>(); 3206 boolean duplicate = false; 3207 3208 Rect bounds = new Rect(sdi.getSymbolBounds()); 3209 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 3210 Point centerPoint = new Point(sdi.getCenterPoint()); 3211 Rect imageBounds = new Rect(sdi.getImageBounds()); 3212 3213 if (attributes.containsKey(MilStdAttributes.Alpha)) 3214 { 3215 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 3216 textColor.setAlpha(alpha); 3217 } 3218 3219 centerPoint = new Point(Math.round(sdi.getCenterPoint().x), Math.round(sdi.getCenterPoint().y)); 3220 3221 boolean byLabelHeight = false; 3222 labelHeight = (int) (modifierFontHeight + 0.5f); 3223 3224 int maxHeight = (symbolBounds.height()); 3225 if ((labelHeight * 3) > maxHeight) 3226 { 3227 byLabelHeight = true; 3228 } 3229 3230 int descent = (int) (modifierFontDescent + 0.5f); 3231 int yForY = -1; 3232 3233 Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0); 3234 Rect labelBounds2 = null; 3235 String strText = ""; 3236 String strText1 = ""; 3237 String strText2 = ""; 3238 TextInfo text1 = null; 3239 TextInfo text2 = null; 3240 3241 3242 if (outlineOffset > 2) 3243 { 3244 outlineOffset = ((outlineOffset - 1) / 2); 3245 } 3246 else 3247 { 3248 outlineOffset = 0; 3249 } 3250 3251 3252 // <editor-fold defaultstate="collapsed" desc="Process Special Modifiers"> 3253 TextInfo ti = null; 3254 if (SymbolUtilities.isCBRNEvent(symbolID))//chemical 3255 { 3256 if ((labelHeight * 3) > bounds.height()) 3257 { 3258 byLabelHeight = true; 3259 } 3260 } 3261 3262 if(ss == SymbolID.SymbolSet_ControlMeasure) { 3263 if (ec == 130500) //contact point 3264 { 3265 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3266 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3267 if (strText != null) { 3268 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3269 labelWidth = Math.round(ti.getTextBounds().width()); 3270 //One modifier symbols and modifier goes in center 3271 x = bounds.left + (int) (bounds.width() * 0.5f); 3272 x = x - (int) (labelWidth * 0.5f); 3273 y = bounds.top + (int) (bounds.height() * 0.4f); 3274 y = y + (int) (labelHeight * 0.5f); 3275 3276 ti.setLocation(Math.round(x), Math.round(y)); 3277 arrMods.add(ti); 3278 } 3279 } 3280 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3281 strText = modifiers.get(Modifiers.W_DTG_1); 3282 if (strText != null) { 3283 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3284 labelWidth = ti.getTextBounds().width(); 3285 3286 x = (bounds.left - labelWidth - bufferXL); 3287 y = (bounds.top + labelHeight - descent); 3288 3289 ti.setLocation(x, y); 3290 arrMods.add(ti); 3291 } 3292 } 3293 } 3294 if (ec == 130700) //decision point 3295 { 3296 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3297 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3298 if (strText != null) { 3299 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3300 labelWidth = Math.round(ti.getTextBounds().width()); 3301 //One modifier symbols and modifier goes in center 3302 x = bounds.left + (int) (bounds.width() * 0.5f); 3303 x = x - (int) (labelWidth * 0.5f); 3304 y = bounds.top + (int) (bounds.height() * 0.5f); 3305 y = y + (int) (labelHeight * 0.5f); 3306 3307 ti.setLocation(Math.round(x), Math.round(y)); 3308 arrMods.add(ti); 3309 } 3310 } 3311 } 3312 else if (ec == 212800)//harbor 3313 { 3314 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3315 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3316 if (strText != null) { 3317 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3318 labelWidth = Math.round(ti.getTextBounds().width()); 3319 //One modifier symbols and modifier goes in center 3320 x = bounds.left + (int) (bounds.width() * 0.5f); 3321 x = x - (int) (labelWidth * 0.5f); 3322 y = bounds.top + (int) (bounds.height() * 0.5f); 3323 y = y + (int) (labelHeight * 0.5f); 3324 3325 ti.setLocation(Math.round(x), Math.round(y)); 3326 arrMods.add(ti); 3327 } 3328 } 3329 } else if (ec == 131300)//point of interest 3330 { 3331 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3332 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3333 if (strText != null) { 3334 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3335 labelWidth = Math.round(ti.getTextBounds().width()); 3336 //One modifier symbols, top third & center 3337 x = bounds.left + (int) (bounds.width() * 0.5f); 3338 x = x - (int) (labelWidth * 0.5f); 3339 y = bounds.top + (int) (bounds.height() * 0.25f); 3340 y = y + (int) (labelHeight * 0.5f); 3341 3342 ti.setLocation(Math.round(x), Math.round(y)); 3343 arrMods.add(ti); 3344 } 3345 } 3346 } else if (ec == 131800//waypoint 3347 || ec == 240900)//fire support station 3348 { 3349 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3350 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3351 if (strText != null) { 3352 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3353 3354 //One modifier symbols and modifier goes right of center 3355 if (ec == 131800) 3356 x = bounds.left + (int) (bounds.width() * 0.75f); 3357 else 3358 x = bounds.left + (bounds.width()); 3359 y = bounds.top + (int) (bounds.height() * 0.5f); 3360 y = y + (int) ((labelHeight - descent) * 0.5f); 3361 3362 ti.setLocation(Math.round(x), Math.round(y)); 3363 arrMods.add(ti); 3364 } 3365 } 3366 } 3367 else if (ec == 131900)//Airfield (AEGIS Only) 3368 { 3369 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3370 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3371 if (strText != null) { 3372 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3373 3374 //One modifier symbols and modifier goes right of symbol 3375 3376 x = bounds.left + (bounds.width() + bufferXR); 3377 3378 y = bounds.top + (int) (bounds.height() * 0.5f); 3379 y = y + (int) ((labelHeight - descent) * 0.5f); 3380 3381 ti.setLocation(Math.round(x), Math.round(y)); 3382 arrMods.add(ti); 3383 } 3384 } 3385 } 3386 else if (ec == 180100 //Air Control point 3387 || ec == 180200) //Communications Check point 3388 { 3389 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3390 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3391 if (strText != null) { 3392 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3393 labelWidth = ti.getTextBounds().width(); 3394 //One modifier symbols and modifier goes just below of center 3395 x = bounds.left + (int) (bounds.width() * 0.5); 3396 x = x - (int) (labelWidth * 0.5); 3397 y = bounds.top + (int) (bounds.height() * 0.5f); 3398 y = y + (int) (((bounds.height() * 0.5f) - labelHeight) / 2) + labelHeight - descent; 3399 3400 ti.setLocation(Math.round(x), Math.round(y)); 3401 arrMods.add(ti); 3402 } 3403 } 3404 } else if (ec == 160300 || //T (target reference point) 3405 ec == 132000 || //T (Target Handover) 3406 ec == 240601 || //ap,ap1,x,h (Point/Single Target) 3407 ec == 240602) //ap (nuclear target) 3408 { //Targets with special modifier positions 3409 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) 3410 && ec == 240601)//H //point single target 3411 { 3412 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3413 if (strText != null) { 3414 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3415 3416 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3417 y = bounds.top + (int) (bounds.height() * 0.75f); 3418 y = y + (int) (labelHeight * 0.5f); 3419 3420 ti.setLocation(Math.round(x), Math.round(y)); 3421 arrMods.add(ti); 3422 } 3423 } 3424 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) 3425 && ec == 240601)//X point or single target 3426 { 3427 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3428 if (strText != null) { 3429 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3430 labelWidth = Math.round(ti.getTextBounds().width()); 3431 x = RectUtilities.getCenterX(bounds) - (int) (bounds.width() * 0.15f); 3432 x = x - (labelWidth); 3433 y = bounds.top + (int) (bounds.height() * 0.75f); 3434 y = y + (int) (labelHeight * 0.5f); 3435 3436 ti.setLocation(Math.round(x), Math.round(y)); 3437 arrMods.add(ti); 3438 } 3439 } 3440 strText = null; 3441 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) && (ec == 160300 || ec == 132000)) { 3442 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3443 if (strText != null) { 3444 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3445 3446 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3447 y = bounds.top + (int) (bounds.height() * 0.25f); 3448 y = y + (int) (labelHeight * 0.5f); 3449 3450 ti.setLocation(Math.round(x), Math.round(y)); 3451 arrMods.add(ti); 3452 } 3453 } 3454 if (ec == 240601 || ec == 240602) 3455 { 3456 if (modifiers.containsKey(Modifiers.AP_TARGET_NUMBER)) { 3457 strText = modifiers.get(Modifiers.AP_TARGET_NUMBER); 3458 } 3459 if (ec == 240601 && modifiers.containsKey(Modifiers.AP1_TARGET_NUMBER_EXTENSION)) { 3460 if (strText != null) 3461 strText = strText + " " + modifiers.get(Modifiers.AP1_TARGET_NUMBER_EXTENSION); 3462 else 3463 strText = modifiers.get(Modifiers.AP1_TARGET_NUMBER_EXTENSION); 3464 } 3465 if (strText != null) { 3466 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3467 3468 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3469 y = bounds.top + (int) (bounds.height() * 0.25f); 3470 y = y + (int) (labelHeight * 0.5f); 3471 3472 ti.setLocation(Math.round(x), Math.round(y)); 3473 arrMods.add(ti); 3474 } 3475 } 3476 } 3477 else if (ec == 132100)//Key Terrain 3478 { 3479 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3480 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3481 if (strText != null) { 3482 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3483 3484 //One modifier symbols and modifier goes right of symbol 3485 3486 x = bounds.left + (int)(bounds.width() * 0.5) + bufferXL; 3487 3488 y = bounds.top + (int) (bounds.height() * 0.5f); 3489 y = y + (int) ((labelHeight - descent) * 0.5f); 3490 3491 ti.setLocation(Math.round(x), Math.round(y)); 3492 arrMods.add(ti); 3493 } 3494 } 3495 } 3496 else if(ec == 182600)//Isolated Personnel Location 3497 { 3498 if (modifiers.containsKey(Modifiers.C_QUANTITY)) { 3499 strText = modifiers.get(Modifiers.C_QUANTITY); 3500 if (strText != null) { 3501 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3502 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3503 //subset of NBC, just nuclear 3504 x = (int)(bounds.left + (bounds.width() * 0.5)); 3505 x = x - (int) (labelWidth * 0.5); 3506 y = (int)bounds.top - descent; 3507 ti.setLocation(Math.round(x), Math.round(y)); 3508 arrMods.add(ti); 3509 } 3510 } 3511 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3512 strText = modifiers.get(Modifiers.W_DTG_1); 3513 if (strText != null) { 3514 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3515 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3516 3517 x = (int)bounds.left - labelWidth - bufferXL; 3518 if (!byLabelHeight) { 3519 y = (int)bounds.top + labelHeight - descent; 3520 } else { 3521 //y = bounds.y + ((bounds.getHeight * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3522 y = (int)(bounds.top + ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText))); 3523 } 3524 3525 ti.setLocation(Math.round(x), Math.round(y)); 3526 arrMods.add(ti); 3527 } 3528 } 3529 if (modifiers.containsKey(Modifiers.W1_DTG_2)) { 3530 strText = modifiers.get(Modifiers.W1_DTG_2); 3531 if (strText != null) { 3532 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3533 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3534 3535 x = (int)bounds.left - labelWidth - bufferXL; 3536 if (!byLabelHeight) { 3537 y = (int)bounds.top + labelHeight - descent; 3538 } else { 3539 //y = bounds.y + ((bounds.getHeight * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3540 y = (int)(bounds.top + ((bounds.height() * 0.5) - (((labelHeight * 2) - descent) * 0.5) + (-descent - bufferText))); 3541 } 3542 3543 ti.setLocation(Math.round(x), Math.round(y)); 3544 arrMods.add(ti); 3545 } 3546 } 3547 } 3548 else if (SymbolUtilities.isCBRNEvent(symbolID)) //CBRN 3549 { 3550 if (modifiers.containsKey(Modifiers.N_HOSTILE)) { 3551 strText = modifiers.get(Modifiers.N_HOSTILE); 3552 if (strText != null) { 3553 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3554 3555 x = bounds.left + bounds.width() + bufferXR; 3556 3557 if (!byLabelHeight) { 3558 y = bounds.top + bounds.height(); 3559 } else { 3560 y = bounds.top + (int) ((bounds.height() * 0.5f) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText)); 3561 } 3562 3563 ti.setLocation(Math.round(x), Math.round(y)); 3564 arrMods.add(ti); 3565 } 3566 3567 } 3568 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3569 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3570 if (strText != null) { 3571 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3572 3573 x = bounds.left + bounds.width() + bufferXR; 3574 if (!byLabelHeight) { 3575 y = bounds.top + labelHeight - descent; 3576 } else { 3577 //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3578 y = bounds.top + (int) ((bounds.height() * 0.5f) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)); 3579 } 3580 3581 ti.setLocation(Math.round(x), Math.round(y)); 3582 arrMods.add(ti); 3583 } 3584 } 3585 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3586 strText = modifiers.get(Modifiers.W_DTG_1); 3587 if (strText != null) { 3588 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3589 labelWidth = Math.round(ti.getTextBounds().width()); 3590 3591 x = bounds.left - labelWidth - bufferXL; 3592 if (!byLabelHeight) { 3593 y = bounds.top + labelHeight - descent; 3594 } else { 3595 //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3596 y = bounds.top + (int) ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)); 3597 } 3598 3599 ti.setLocation(Math.round(x), Math.round(y)); 3600 arrMods.add(ti); 3601 } 3602 } 3603 if ((ec == 281500 || ec == 281600) && modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) {//nuclear event or nuclear fallout producing event 3604 strText = modifiers.get(Modifiers.V_EQUIP_TYPE); 3605 if (strText != null) { 3606 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3607 3608 //subset of nbc, just nuclear 3609 labelWidth = Math.round(ti.getTextBounds().width()); 3610 x = bounds.left - labelWidth - bufferXL; 3611 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5));//((bounds.height / 2) - (labelHeight/2)); 3612 3613 ti.setLocation(Math.round(x), Math.round(y)); 3614 arrMods.add(ti); 3615 } 3616 } 3617 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3618 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3619 if (strText != null) { 3620 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3621 labelWidth = Math.round(ti.getTextBounds().width()); 3622 x = bounds.left - labelWidth - bufferXL; 3623 if (!byLabelHeight) { 3624 y = bounds.top + bounds.height(); 3625 } else { 3626 //y = bounds.y + ((bounds.height * 0.5) + ((labelHeight-descent) * 0.5) + (labelHeight + bufferText)); 3627 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText)); 3628 } 3629 ti.setLocation(Math.round(x), Math.round(y)); 3630 arrMods.add(ti); 3631 } 3632 } 3633 if (modifiers.containsKey(Modifiers.Y_LOCATION)) { 3634 strText = modifiers.get(Modifiers.Y_LOCATION); 3635 if (strText != null) { 3636 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3637 labelWidth = Math.round(ti.getTextBounds().width()); 3638 //just NBC 3639 //x = bounds.left + (bounds.width() * 0.5); 3640 //x = x - (labelWidth * 0.5); 3641 x = bounds.left + (int) (bounds.width() * 0.5f); 3642 x = x - (int) (labelWidth * 0.5f); 3643 3644 if (!byLabelHeight) { 3645 y = bounds.top + bounds.height() + labelHeight - descent + bufferY; 3646 } else { 3647 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + ((labelHeight + bufferText) * 2) - descent); 3648 3649 } 3650 yForY = y + descent; //so we know where to start the DOM arrow. 3651 ti.setLocation(Math.round(x), Math.round(y)); 3652 arrMods.add(ti); 3653 } 3654 3655 } 3656 if (modifiers.containsKey(Modifiers.C_QUANTITY)) { 3657 strText = modifiers.get(Modifiers.C_QUANTITY); 3658 if (strText != null) { 3659 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3660 labelWidth = Math.round(ti.getTextBounds().width()); 3661 //subset of NBC, just nuclear 3662 x = bounds.left + (int) (bounds.width() * 0.5); 3663 x = x - (int) (labelWidth * 0.5); 3664 y = bounds.top - descent; 3665 ti.setLocation(Math.round(x), Math.round(y)); 3666 arrMods.add(ti); 3667 } 3668 3669 } 3670 } 3671 else if (ec == 270701)//static depiction 3672 { 3673 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3674 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3675 if (strText != null) { 3676 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3677 labelWidth = Math.round(ti.getTextBounds().width()); 3678 x = bounds.left + (int) (bounds.width() * 0.5); 3679 x = x - (int) (labelWidth * 0.5); 3680 y = bounds.top - descent;// + (bounds.height * 0.5); 3681 //y = y + (labelHeight * 0.5); 3682 3683 ti.setLocation(Math.round(x), Math.round(y)); 3684 arrMods.add(ti); 3685 } 3686 3687 } 3688 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3689 strText = modifiers.get(Modifiers.W_DTG_1); 3690 if (strText != null) { 3691 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3692 labelWidth = Math.round(ti.getTextBounds().width()); 3693 x = bounds.left + (int) (bounds.width() * 0.5); 3694 x = x - (int) (labelWidth * 0.5); 3695 y = bounds.top + (bounds.height()); 3696 y = y + (labelHeight); 3697 3698 ti.setLocation(Math.round(x), Math.round(y)); 3699 arrMods.add(ti); 3700 } 3701 } 3702 if (modifiers.containsKey(Modifiers.N_HOSTILE)) { 3703 strText = modifiers.get(Modifiers.N_HOSTILE); 3704 if (strText != null) { 3705 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3706 TextInfo ti2 = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3707 labelWidth = Math.round(ti.getTextBounds().width()); 3708 x = bounds.left + (bounds.width()) + bufferXR;//right 3709 //x = x + labelWidth;//- (labelBounds.width * 0.75); 3710 3711 duplicate = true; 3712 3713 x2 = bounds.left;//left 3714 x2 = x2 - labelWidth - bufferXL;// - (labelBounds.width * 0.25); 3715 3716 y = bounds.top + (int) (bounds.height() * 0.5);//center 3717 y = y + (int) ((labelHeight - descent) * 0.5); 3718 3719 y2 = y; 3720 3721 ti.setLocation(Math.round(x), Math.round(y)); 3722 ti2.setLocation(Math.round(x2), Math.round(y2)); 3723 arrMods.add(ti); 3724 arrMods.add(ti2); 3725 } 3726 } 3727 3728 } 3729 else if(e == 21 && et == 35)//sonobuoys 3730 { 3731 boolean is2525E = (SymbolID.getVersion(symbolID) >= SymbolID.Version_2525E); 3732 //H sitting on center of circle to the right 3733 //T above H 3734 centerPoint = SymbolUtilities.getCMSymbolAnchorPoint(symbolID,RectUtilities.makeRectFFromRect(bounds)); 3735 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3736 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3737 if (strText != null) { 3738 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3739 TextInfo ti2 = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3740 labelWidth = Math.round(ti.getTextBounds().width()); 3741 x = bounds.left + (bounds.width()) + bufferXR;//right 3742 y = centerPoint.y; 3743 3744 if(is2525E) { 3745 x = x - (int)(bounds.width() * 0.2); 3746 y = (int) (bounds.top + (bounds.height() / 2)); 3747 } 3748 3749 ti.setLocation(Math.round(x), Math.round(y)); 3750 arrMods.add(ti); 3751 } 3752 } 3753 if (est == 0 || est == 1 || est == 4 || est == 7 || est == 8 || est == 15) { 3754 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3755 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3756 if (strText != null) { 3757 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3758 TextInfo ti2 = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3759 labelWidth = Math.round(ti.getTextBounds().width()); 3760 x = (bounds.left + (bounds.width()) + bufferXR - (int)(bounds.width() * 0.2) );//right 3761 y = centerPoint.y - labelHeight; 3762 3763 if(is2525E) { 3764 y = (bounds.top + (bounds.height() / 2)) - labelHeight; 3765 } 3766 3767 ti.setLocation(Math.round(x), Math.round(y)); 3768 arrMods.add(ti); 3769 } 3770 } 3771 } 3772 } 3773 else if(ec == 282001 || //tower, low 3774 ec == 282002) //tower, high 3775 { 3776 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) { 3777 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3778 if (strText != null) { 3779 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3780 labelWidth = Math.round(ti.getTextBounds().width()); 3781 x = bounds.left + (int) (bounds.width() * 0.7); 3782 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3783 //y = y + (labelHeight * 0.5); 3784 3785 ti.setLocation(Math.round(x), Math.round(y)); 3786 arrMods.add(ti); 3787 } 3788 3789 } 3790 } 3791 else if(ec == 180600)//TACAN 3792 { 3793 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3794 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3795 if (strText != null) { 3796 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3797 labelWidth = Math.round(ti.getTextBounds().width()); 3798 x = bounds.left + bounds.width() + bufferXR; 3799 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3800 //y = y + (labelHeight * 0.5); 3801 3802 ti.setLocation(Math.round(x), Math.round(y)); 3803 arrMods.add(ti); 3804 } 3805 3806 } 3807 } 3808 else if(ec == 210300)//Defended Asset 3809 { 3810 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3811 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3812 if (strText != null) { 3813 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3814 labelWidth = Math.round(ti.getTextBounds().width()); 3815 x = bounds.left - labelWidth - bufferXL; 3816 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3817 //y = y + (labelHeight * 0.5); 3818 3819 ti.setLocation(Math.round(x), Math.round(y)); 3820 arrMods.add(ti); 3821 } 3822 3823 } 3824 } 3825 else if(ec == 210600)//Air Detonation 3826 { 3827 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) { 3828 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3829 if (strText != null) { 3830 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3831 labelWidth = Math.round(ti.getTextBounds().width()); 3832 x = bounds.left + (bounds.width() + bufferXR); 3833 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3834 //y = y + (labelHeight * 0.5); 3835 3836 ti.setLocation(Math.round(x), Math.round(y)); 3837 arrMods.add(ti); 3838 } 3839 3840 } 3841 } 3842 else if(ec == 210800)//Impact Point 3843 { 3844 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3845 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3846 if (strText != null) { 3847 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3848 labelWidth = Math.round(ti.getTextBounds().width()); 3849 x = bounds.left + (int) (bounds.width() * 0.65f); 3850// x = x - (labelBounds.width * 0.5); 3851 y = bounds.top + (int) (bounds.height() * 0.25f); 3852 y = y + (int) (labelHeight * 0.5f); 3853 //y = y + (labelHeight * 0.5); 3854 3855 ti.setLocation(Math.round(x), Math.round(y)); 3856 arrMods.add(ti); 3857 } 3858 3859 } 3860 } 3861 else if(ec == 211000)//Launched Torpedo 3862 { 3863 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3864 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3865 if (strText != null) { 3866 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3867 labelWidth = Math.round(ti.getTextBounds().width()); 3868 x = (int)(bounds.left + (bounds.width() * 0.5) - (labelWidth/2)); 3869 y = bounds.top - bufferY; 3870 3871 ti.setLocation(Math.round(x), Math.round(y)); 3872 arrMods.add(ti); 3873 } 3874 3875 } 3876 } 3877 else if(ec == 214900 || ec == 215600)//General Sea SubSurface Station & General Sea Surface Station 3878 { 3879 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3880 strText = modifiers.get(Modifiers.W_DTG_1); 3881 if (strText != null) { 3882 ti = new TextInfo(strText + " - ", 0, 0, modifierFont, modifierFontName); 3883 x = bounds.left + (bounds.width() + bufferXR); 3884 y = bounds.top + labelHeight; 3885 3886 ti.setLocation(Math.round(x), Math.round(y)); 3887 arrMods.add(ti); 3888 } 3889 3890 } 3891 if (modifiers.containsKey(Modifiers.W1_DTG_2)) { 3892 strText = modifiers.get(Modifiers.W1_DTG_2); 3893 if (strText != null) { 3894 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3895 x = bounds.left + (bounds.width() + bufferXR); 3896 y = bounds.top + (labelHeight * 2); 3897 3898 ti.setLocation(Math.round(x), Math.round(y)); 3899 arrMods.add(ti); 3900 } 3901 3902 } 3903 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3904 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3905 if (strText != null) { 3906 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3907 x = bounds.left + (bounds.width() + bufferXR); 3908 y = bounds.top + (labelHeight * 3); 3909 3910 ti.setLocation(Math.round(x), Math.round(y)); 3911 arrMods.add(ti); 3912 } 3913 3914 } 3915 } 3916 else if(ec == 217000)//Shore Control Station 3917 { 3918 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3919 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3920 if (strText != null) { 3921 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3922 labelWidth = Math.round(ti.getTextBounds().width()); 3923 x = (int)(bounds.left + (bounds.width() * 0.5) - (labelWidth/2)); 3924 y = bounds.top + bounds.height() + labelHeight + bufferY; 3925 3926 ti.setLocation(Math.round(x), Math.round(y)); 3927 arrMods.add(ti); 3928 } 3929 3930 } 3931 } 3932 else if(ec == 250600)//Known Point 3933 { 3934 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3935 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3936 if (strText != null) { 3937 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3938 labelWidth = Math.round(ti.getTextBounds().width()); 3939 x = bounds.left + (bounds.width() + bufferXR); 3940// x = x - (labelBounds.width * 0.5); 3941 y = bounds.top + (int) (bounds.height() * 0.25f); 3942 y = y + (int) (labelHeight * 0.5f); 3943 //y = y + (labelHeight * 0.5); 3944 3945 ti.setLocation(Math.round(x), Math.round(y)); 3946 arrMods.add(ti); 3947 } 3948 3949 } 3950 } 3951 } 3952 else if(ss == SymbolID.SymbolSet_Atmospheric) 3953 { 3954 String modX = null; 3955 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 3956 modX = (modifiers.get(Modifiers.X_ALTITUDE_DEPTH)); 3957 3958 if(ec == 162300)//Freezing Level 3959 { 3960 strText = "0" + (char)(176) + ":"; 3961 if(modX != null) 3962 strText += modX; 3963 else 3964 strText += "?"; 3965 3966 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3967 labelWidth = Math.round(ti.getTextBounds().width()); 3968 //One modifier symbols and modifier goes in center 3969 x = bounds.left + (int) (bounds.width() * 0.5f); 3970 x = x - (int) (labelWidth * 0.5f); 3971 y = bounds.top + (int) (bounds.height() * 0.5f); 3972 y = y + (int) ((labelHeight - modifierFontDescent) * 0.5f); 3973 3974 ti.setLocation(Math.round(x), Math.round(y)); 3975 arrMods.add(ti); 3976 } 3977 else if(ec == 162200)//tropopause Level 3978 { 3979 strText = "X?"; 3980 if(modX != null) 3981 strText = modX; 3982 3983 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3984 labelWidth = Math.round(ti.getTextBounds().width()); 3985 //One modifier symbols and modifier goes in center 3986 x = bounds.left + (int) (bounds.width() * 0.5f); 3987 x = x - (int) (labelWidth * 0.5f); 3988 y = bounds.top + (int) (bounds.height() * 0.5f); 3989 y = y + (int) ((labelHeight - modifierFontDescent) * 0.5f); 3990 3991 ti.setLocation(Math.round(x), Math.round(y)); 3992 arrMods.add(ti); 3993 } 3994 else if(ec == 110102)//tropopause Low 3995 { 3996 strText = "X?"; 3997 if(modX != null) 3998 strText = modX; 3999 4000 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4001 labelWidth = Math.round(ti.getTextBounds().width()); 4002 //One modifier symbols and modifier goes in center 4003 x = bounds.left + (int) (bounds.width() * 0.5f); 4004 x = x - (int) (labelWidth * 0.5f); 4005 y = bounds.top + (int) (bounds.height() * 0.5f); 4006 y = y - descent; 4007 4008 ti.setLocation(Math.round(x), Math.round(y)); 4009 arrMods.add(ti); 4010 } 4011 else if(ec == 110202)//tropopause High 4012 { 4013 strText = "X?"; 4014 if(modX != null) 4015 strText = modX; 4016 4017 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4018 labelWidth = Math.round(ti.getTextBounds().width()); 4019 //One modifier symbols and modifier goes in center 4020 x = bounds.left + (int) (bounds.width() * 0.5f); 4021 x = x - (int) (labelWidth * 0.5f); 4022 y = bounds.top + (int) (bounds.height() * 0.5f); 4023 //y = y + (int) ((labelHeight * 0.5f) + (labelHeight/2)); 4024 y = y + (int) (((labelHeight * 0.5f) - (labelHeight/2)) + labelHeight - descent); 4025 4026 ti.setLocation(Math.round(x), Math.round(y)); 4027 arrMods.add(ti); 4028 } 4029 } 4030 // </editor-fold> 4031 4032 // <editor-fold defaultstate="collapsed" desc="DOM Arrow"> 4033 Point[] domPoints = null; 4034 Rect domBounds = null; 4035 4036 if (modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT) && 4037 SymbolUtilities.isCBRNEvent(symbolID))//CBRN events 4038 { 4039 strText = modifiers.get(Modifiers.Q_DIRECTION_OF_MOVEMENT); 4040 if(strText != null && SymbolUtilities.isNumber(strText)) 4041 { 4042 float q = Float.parseFloat(strText); 4043 Rect tempBounds = new Rect(bounds); 4044 tempBounds.union(RectUtilities.getCenterX(bounds), yForY); 4045 4046 domPoints = createDOMArrowPoints(symbolID, tempBounds, sdi.getCenterPoint(), q, false, modifierFontHeight); 4047 4048 domBounds = RectUtilities.makeRect(domPoints[0].x, domPoints[0].y, 1, 1); 4049 4050 Point temp = null; 4051 for (int i = 1; i < 6; i++) 4052 { 4053 temp = domPoints[i]; 4054 if (temp != null) 4055 { 4056 domBounds.union(temp.x, temp.y); 4057 } 4058 } 4059 imageBounds.union(domBounds); 4060 } 4061 } 4062 // </editor-fold> 4063 4064 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 4065 if (SymbolUtilities.hasFDI(symbolID)) 4066 { 4067 //create feint indicator /\ 4068 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 4069 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 4070 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f))); 4071 4072 4073 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 4074 fdiBounds.union(fdiTop.x, fdiTop.y); 4075 fdiBounds.union(fdiRight.x, fdiRight.y); 4076 4077 float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4078 RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2)); 4079 4080 ti = new TextInfo("TEST",0,0, modifierFont, modifierFontName); 4081 if (ti != null && SymbolUtilities.isCBRNEvent(symbolID)) 4082 { 4083 int shiftY = Math.round(symbolBounds.top - ti.getTextBounds().height() - 2); 4084 fdiLeft.offset(0, shiftY); 4085 fdiTop.offset(0, shiftY); 4086 fdiRight.offset(0, shiftY); 4087 fdiBounds.offset(0, shiftY); 4088 } 4089 4090 imageBounds.union(fdiBounds); 4091 4092 } 4093 // </editor-fold> 4094 4095 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 4096 Rect modifierBounds = null; 4097 if (arrMods != null && arrMods.size() > 0) 4098 { 4099 4100 //build modifier bounds///////////////////////////////////////// 4101 modifierBounds = arrMods.get(0).getTextOutlineBounds(); 4102 int size = arrMods.size(); 4103 TextInfo tempShape = null; 4104 for (int i = 1; i < size; i++) 4105 { 4106 tempShape = arrMods.get(i); 4107 modifierBounds.union(tempShape.getTextOutlineBounds()); 4108 } 4109 4110 } 4111 4112 if (modifierBounds != null || domBounds != null || fdiBounds != null) 4113 { 4114 4115 if (modifierBounds != null) 4116 { 4117 imageBounds.union(modifierBounds); 4118 } 4119 if (domBounds != null) 4120 { 4121 imageBounds.union(domBounds); 4122 } 4123 if (fdiBounds != null) 4124 { 4125 imageBounds.union(fdiBounds); 4126 } 4127 4128 //shift points if needed//////////////////////////////////////// 4129 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4130 { 4131 int shiftX = Math.abs(imageBounds.left); 4132 int shiftY = Math.abs(imageBounds.top); 4133 4134 //shift mobility points 4135 int size = arrMods.size(); 4136 TextInfo tempShape = null; 4137 for (int i = 0; i < size; i++) 4138 { 4139 tempShape = arrMods.get(i); 4140 tempShape.shift(shiftX, shiftY); 4141 } 4142 if(modifierBounds != null) 4143 modifierBounds.offset(shiftX, shiftY); 4144 4145 if (domBounds != null) 4146 { 4147 for (int i = 0; i < 6; i++) 4148 { 4149 Point temp = domPoints[i]; 4150 if (temp != null) 4151 { 4152 temp.offset(shiftX, shiftY); 4153 } 4154 } 4155 domBounds.offset(shiftX, shiftY); 4156 } 4157 4158 //If there's an FDI 4159 if (fdiBounds != null) 4160 { 4161 fdiBounds.offset(shiftX, shiftY); 4162 fdiLeft.offset(shiftX, shiftY); 4163 fdiTop.offset(shiftX, shiftY); 4164 fdiRight.offset(shiftX, shiftY); 4165 } 4166 4167 //shift image points 4168 centerPoint.offset(shiftX, shiftY); 4169 symbolBounds.offset(shiftX, shiftY); 4170 imageBounds.offset(shiftX, shiftY); 4171 } 4172 4173 4174 if (attributes.containsKey(MilStdAttributes.TextColor)) 4175 { 4176 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4177 if(alpha > -1) 4178 textColor.setAlpha(alpha); 4179 } 4180 if (attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4181 { 4182 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4183 if(alpha > -1) 4184 textBackgroundColor.setAlpha(alpha); 4185 } 4186 4187 if(sdi instanceof ImageInfo) { 4188 ii = (ImageInfo)sdi; 4189 //Render modifiers////////////////////////////////////////////////// 4190 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 4191 Canvas ctx = new Canvas(bmp); 4192 4193 //render//////////////////////////////////////////////////////// 4194 //draw original icon with potential modifiers. 4195 ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null); 4196 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 4197 4198 4199 renderText(ctx, arrMods, textColor, textBackgroundColor, modifierFont); 4200 4201 //draw DOM arrow 4202 if (domBounds != null) 4203 { 4204 drawDOMArrow(ctx, domPoints, alpha, lineColor); 4205 } 4206 4207 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4208 if (fdiBounds != null) { 4209 4210 Paint fdiPaint = new Paint(); 4211 fdiPaint.setAntiAlias(true); 4212 fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 4213 if (alpha > -1) 4214 fdiPaint.setAlpha(alpha); 4215 fdiPaint.setStyle(Style.STROKE); 4216 4217 int dpi = RendererSettings.getInstance().getDeviceDPI(); 4218 int lineLength = dpi / 96 * 6; 4219 int lineGap = dpi / 96 * 4; 4220 4221 /// /////////////////////////////////// 4222 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4223 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4224 //distance = distance / 14f; 4225 lineGap = (int)((distance / 14f) * 2); 4226 lineLength = (int)((distance / 14f) * 3); 4227 /// ////////////////////////////////// 4228 4229 fdiPaint.setPathEffect(new DashPathEffect(new float[] 4230 { 4231 lineLength, lineGap 4232 }, 0)); 4233 4234 float fdiStrokeWidth = Math.round(dpi / 96f); 4235 if (fdiStrokeWidth < 2) 4236 fdiStrokeWidth = 2; 4237 4238 fdiPaint.setStrokeCap(Cap.ROUND); 4239 fdiPaint.setStrokeJoin(Join.MITER); 4240 fdiPaint.setStrokeWidth(fdiStrokeWidth); 4241 4242 Path fdiPath = new Path(); 4243 4244 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4245 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4246 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4247 fdiPath.lineTo(fdiRight.x, fdiRight.y); 4248 ctx.drawPath(fdiPath, fdiPaint); 4249 4250 fdiBounds = null; 4251 4252 } 4253 //</editor-fold> 4254 4255 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 4256 ctx = null; 4257 } 4258 else if(sdi instanceof SVGSymbolInfo) 4259 { 4260 float strokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4261 if(strokeWidth < 1) 4262 strokeWidth=1; 4263 String svgStroke = RendererUtilities.colorToHexString(lineColor,false); 4264 String svgStrokeWidth = String.valueOf(strokeWidth);//"3"; 4265 4266 ssi = (SVGSymbolInfo)sdi; 4267 StringBuilder sbSVG = new StringBuilder(); 4268 sbSVG.append(ssi.getSVG()); 4269 sbSVG.append(renderTextElements(arrMods,textColor,textBackgroundColor)); 4270 4271 // <editor-fold defaultstate="collapsed" desc="DOM arrow"> 4272 if (domBounds != null && domPoints.length == 6) 4273 { 4274 SVGPath domPath = new SVGPath() ; 4275 4276 domPath.moveTo(domPoints[0].x, domPoints[0].y); 4277 if (domPoints[1] != null) 4278 { 4279 domPath.lineTo(domPoints[1].x, domPoints[1].y); 4280 } 4281 if (domPoints[2] != null) 4282 { 4283 domPath.lineTo(domPoints[2].x, domPoints[2].y); 4284 } 4285 sbSVG.append(domPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,null)); 4286 4287 domPath = new SVGPath(); 4288 4289 domPath.moveTo(domPoints[3].x, domPoints[3].y); 4290 domPath.lineTo(domPoints[4].x, domPoints[4].y); 4291 domPath.lineTo(domPoints[5].x, domPoints[5].y); 4292 sbSVG.append(domPath.toSVGElement(null,0f,svgStroke,1f,1f,null)); 4293 4294 domBounds = null; 4295 domPoints = null; 4296 } 4297 // </editor-fold> 4298 4299 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4300 if (fdiBounds != null) 4301 { 4302 4303 /*int dpi = RendererSettings.getInstance().getDeviceDPI(); 4304 int lineLength = dpi / 96 * 6; 4305 int lineGap = dpi / 96 * 4; 4306 String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/ 4307 4308 /// /////////////////////////////////// 4309 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4310 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4311 //distance = distance / 14f; 4312 int lineGap = (int)((distance / 14f) * 2); 4313 int lineLength = (int)((distance / 14f) * 3); 4314 String svgFDIDashArray = "" + lineLength + " " + lineGap; 4315 /// ////////////////////////////////// 4316 4317 SVGPath fdiPath = new SVGPath(); 4318 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4319 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4320 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4321 fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/ 4322 4323 fdiPath.setLineDash(svgFDIDashArray); 4324 4325 sbSVG.append(fdiPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,"round")); 4326 //sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray)); 4327 } 4328 //</editor-fold> 4329 4330 newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds); 4331 } 4332 4333 4334 4335 4336 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 4337 //ctx = null; 4338 // </editor-fold> 4339 4340 return newsdi; 4341 4342 } 4343 else 4344 { 4345 return null; 4346 } 4347 // </editor-fold> 4348 4349 } 4350 4351 /** 4352 * Process modifiers for action points 4353 */ 4354 public static SymbolDimensionInfo ProcessTGSPModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes, Color lineColor) 4355 { 4356 4357 Paint modifierFont = getFont(attributes); 4358 float[] hd = getFontHeightandDescent(modifierFont); 4359 float modifierFontHeight = hd[0]; 4360 float modifierFontDescent = hd[1]; 4361 4362 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 4363 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 4364 { 4365 String temp = attributes.get(MilStdAttributes.FontFamily); 4366 if(temp != null && !temp.isEmpty()) 4367 modifierFontName = temp; 4368 } 4369 4370 // <editor-fold defaultstate="collapsed" desc="Variables"> 4371 ImageInfo ii = null; 4372 SVGSymbolInfo ssi = null; 4373 4374 int bufferXL = 6; 4375 int bufferXR = 4; 4376 int bufferY = 2; 4377 int bufferText = 2; 4378 int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel 4379 int x = 0; 4380 int y = 0; 4381 int x2 = 0; 4382 int y2 = 0; 4383 4384 //Feint Dummy Indicator variables 4385 Rect fdiBounds = null; 4386 Point fdiTop = null; 4387 Point fdiLeft = null; 4388 Point fdiRight = null; 4389 4390 int outlineOffset = RS.getTextOutlineWidth(); 4391 int labelHeight = 0; 4392 int labelWidth = 0; 4393 int alpha = -1; 4394 SymbolDimensionInfo newsdi = null; 4395 4396 Color textColor = lineColor; 4397 Color textBackgroundColor = null; 4398 4399 ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>(); 4400 boolean duplicate = false; 4401 4402 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 4403 4404 4405 if (attributes.containsKey(MilStdAttributes.Alpha)) 4406 { 4407 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 4408 } 4409 4410 Rect bounds = new Rect(sdi.getSymbolBounds()); 4411 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 4412 Point centerPoint = new Point(sdi.getCenterPoint()); 4413 Rect imageBounds = new Rect(sdi.getImageBounds()); 4414 4415 centerPoint = new Point(Math.round(sdi.getCenterPoint().x), Math.round(sdi.getCenterPoint().y)); 4416 4417 boolean byLabelHeight = false; 4418 4419 labelHeight = Math.round(modifierFontHeight + 0.5f); 4420 int maxHeight = (symbolBounds.height()); 4421 if ((labelHeight * 3) > maxHeight) 4422 { 4423 byLabelHeight = true; 4424 } 4425 4426 int descent = (int) (modifierFontDescent + 0.5f); 4427 int yForY = -1; 4428 4429 Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0); 4430 Rect labelBounds2 = null; 4431 String strText = ""; 4432 String strText1 = ""; 4433 String strText2 = ""; 4434 TextInfo text1 = null; 4435 TextInfo text2 = null; 4436 4437 String basicID = SymbolUtilities.getBasicSymbolID(symbolID); 4438 4439 if (outlineOffset > 2) 4440 { 4441 outlineOffset = ((outlineOffset - 1) / 2); 4442 } 4443 else 4444 { 4445 outlineOffset = 0; 4446 } 4447 4448 /*bufferXL += outlineOffset; 4449 bufferXR += outlineOffset; 4450 bufferY += outlineOffset; 4451 bufferText += outlineOffset;*/ 4452 // </editor-fold> 4453 // <editor-fold defaultstate="collapsed" desc="Process Modifiers"> 4454 TextInfo ti = null; 4455 4456 { 4457 if (msi.getModifiers().contains(Modifiers.N_HOSTILE) && modifiers.containsKey(Modifiers.N_HOSTILE)) 4458 { 4459 strText = modifiers.get(Modifiers.N_HOSTILE); 4460 if(strText != null) 4461 { 4462 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4463 4464 x = bounds.left + bounds.width() + bufferXR; 4465 4466 if (!byLabelHeight) 4467 { 4468 y = ((bounds.height() / 3) * 2);//checkpoint, get box above the point 4469 y = bounds.top + y; 4470 } 4471 else 4472 { 4473 //y = ((labelHeight + bufferText) * 3); 4474 //y = bounds.y + y - descent; 4475 y = bounds.top + bounds.height(); 4476 } 4477 4478 ti.setLocation(x, y); 4479 arrMods.add(ti); 4480 } 4481 4482 } 4483 if (msi.getModifiers().contains(Modifiers.H_ADDITIONAL_INFO_1) && modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 4484 { 4485 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 4486 if(strText != null) 4487 { 4488 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4489 labelWidth = Math.round(ti.getTextBounds().width()); 4490 4491 x = bounds.left + (int) (bounds.width() * 0.5f); 4492 x = x - (int) (labelWidth * 0.5f); 4493 y = bounds.top - descent; 4494 4495 ti.setLocation(x, y); 4496 arrMods.add(ti); 4497 } 4498 } 4499 if (msi.getModifiers().contains(Modifiers.H1_ADDITIONAL_INFO_2) && modifiers.containsKey(Modifiers.H1_ADDITIONAL_INFO_2)) 4500 { 4501 strText = modifiers.get(Modifiers.H1_ADDITIONAL_INFO_2); 4502 if(strText != null) 4503 { 4504 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4505 labelWidth = Math.round(ti.getTextBounds().width()); 4506 4507 x = bounds.left + (int) (bounds.width() * 0.5); 4508 x = x - (int) (labelWidth * 0.5); 4509 y = bounds.top + labelHeight - descent + (int) (bounds.height() * 0.07); 4510 4511 ti.setLocation(x, y); 4512 arrMods.add(ti); 4513 } 4514 } 4515 if (msi.getModifiers().contains(Modifiers.A_SYMBOL_ICON)) 4516 { 4517 if(modifiers.containsKey(Modifiers.A_SYMBOL_ICON)) 4518 strText = modifiers.get(Modifiers.A_SYMBOL_ICON); 4519 else if(SymbolID.getEntityCode(symbolID)==321706)//NATO Multiple Supply Class Point 4520 strText = "ALL?";//make it clear the required 'A' value wasn't set for this symbol. 4521 4522 if(strText != null) 4523 { 4524 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4525 labelWidth = Math.round(ti.getTextBounds().width()); 4526 4527 x = bounds.left + (int) (bounds.width() * 0.5); 4528 x = x - (int) (labelWidth * 0.5); 4529 y = bounds.top + labelHeight - descent + (int) (bounds.height() * 0.07); 4530 4531 ti.setLocation(x, y); 4532 arrMods.add(ti); 4533 } 4534 } 4535 if (msi.getModifiers().contains(Modifiers.W_DTG_1) && modifiers.containsKey(Modifiers.W_DTG_1)) 4536 { 4537 strText = modifiers.get(Modifiers.W_DTG_1); 4538 if(strText != null) 4539 { 4540 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4541 labelWidth = Math.round(ti.getTextBounds().width()); 4542 4543 x = bounds.left - labelWidth - bufferXL; 4544 y = bounds.top + labelHeight - descent; 4545 4546 ti.setLocation(x, y); 4547 arrMods.add(ti); 4548 } 4549 } 4550 if (msi.getModifiers().contains(Modifiers.W1_DTG_2) && modifiers.containsKey(Modifiers.W1_DTG_2)) 4551 { 4552 strText = modifiers.get(Modifiers.W1_DTG_2); 4553 if(strText != null) 4554 { 4555 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4556 labelWidth = Math.round(ti.getTextBounds().width()); 4557 4558 x = bounds.left - labelWidth - bufferXL; 4559 4560 y = ((labelHeight - descent + bufferText) * 2); 4561 y = bounds.top + y; 4562 4563 ti.setLocation(x, y); 4564 arrMods.add(ti); 4565 } 4566 } 4567 if (msi.getModifiers().contains(Modifiers.T_UNIQUE_DESIGNATION_1) && modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 4568 { 4569 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 4570 if(strText != null) 4571 { 4572 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4573 4574 x = bounds.left + bounds.width() + bufferXR; 4575 y = bounds.top + labelHeight - descent; 4576 4577 ti.setLocation(x, y); 4578 arrMods.add(ti); 4579 } 4580 } 4581 if (msi.getModifiers().contains(Modifiers.T1_UNIQUE_DESIGNATION_2) && modifiers.containsKey(Modifiers.T1_UNIQUE_DESIGNATION_2)) 4582 { 4583 strText = modifiers.get(Modifiers.T1_UNIQUE_DESIGNATION_2); 4584 if(strText != null) 4585 { 4586 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4587 labelWidth = Math.round(ti.getTextBounds().width()); 4588 4589 //points 4590 x = bounds.left + (int) (bounds.width() * 0.5); 4591 x = x - (int) (labelWidth * 0.5); 4592 //y = bounds.y + (bounds.height * 0.5); 4593 4594 y = (int) ((bounds.height() * 0.55));//633333333 4595 y = bounds.top + y; 4596 4597 int ec = SymbolID.getEntityCode(symbolID); 4598 if((ec >= 281800 && ec <= 281809) || ec == 321100) 4599 { 4600 y = (int) ((bounds.height() * 0.63)); 4601 y = (int)bounds.top + y; 4602 } 4603 4604 ti.setLocation(x, y); 4605 arrMods.add(ti); 4606 } 4607 } 4608 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 4609 if (SymbolUtilities.hasFDI(symbolID)) 4610 { 4611 //create feint indicator /\ 4612 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 4613 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 4614 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f))); 4615 4616 4617 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 4618 fdiBounds.union(fdiTop.x, fdiTop.y); 4619 fdiBounds.union(fdiRight.x, fdiRight.y); 4620 4621 float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4622 RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2)); 4623 4624 ti = new TextInfo("TEST",0,0, modifierFont, modifierFontName); 4625 if (ti != null) 4626 { 4627 int shiftY = Math.round(symbolBounds.top - ti.getTextBounds().height() - 2); 4628 fdiLeft.offset(0, shiftY); 4629 fdiTop.offset(0, shiftY); 4630 fdiRight.offset(0, shiftY); 4631 fdiBounds.offset(0, shiftY); 4632 } 4633 4634 imageBounds.union(fdiBounds); 4635 4636 } 4637 // </editor-fold> 4638 } 4639 4640 // </editor-fold> 4641 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 4642 Rect modifierBounds = null; 4643 if (arrMods != null && arrMods.size() > 0) 4644 { 4645 4646 //build modifier bounds///////////////////////////////////////// 4647 modifierBounds = arrMods.get(0).getTextOutlineBounds(); 4648 int size = arrMods.size(); 4649 TextInfo tempShape = null; 4650 for (int i = 1; i < size; i++) 4651 { 4652 tempShape = arrMods.get(i); 4653 modifierBounds.union(tempShape.getTextOutlineBounds()); 4654 } 4655 4656 } 4657 4658 if(fdiBounds != null) 4659 { 4660 if(modifierBounds != null) 4661 modifierBounds.union(fdiBounds); 4662 else 4663 modifierBounds = fdiBounds; 4664 } 4665 4666 if (modifierBounds != null) 4667 { 4668 4669 imageBounds.union(modifierBounds); 4670 4671 //shift points if needed//////////////////////////////////////// 4672 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4673 { 4674 int shiftX = Math.abs(imageBounds.left); 4675 int shiftY = Math.abs(imageBounds.top); 4676 4677 //shift mobility points 4678 int size = arrMods.size(); 4679 TextInfo tempShape = null; 4680 for (int i = 0; i < size; i++) 4681 { 4682 tempShape = arrMods.get(i); 4683 tempShape.shift(shiftX, shiftY); 4684 } 4685 modifierBounds.offset(shiftX, shiftY); 4686 4687 //shift image points 4688 centerPoint.offset(shiftX, shiftY); 4689 symbolBounds.offset(shiftX, shiftY); 4690 imageBounds.offset(shiftX, shiftY); 4691 4692 //If there's an FDI 4693 if (fdiBounds != null) 4694 { 4695 fdiBounds.offset(shiftX, shiftY); 4696 fdiLeft.offset(shiftX, shiftY); 4697 fdiTop.offset(shiftX, shiftY); 4698 fdiRight.offset(shiftX, shiftY); 4699 } 4700 } 4701 4702 if (attributes.containsKey(MilStdAttributes.TextColor)) 4703 { 4704 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4705 if(alpha > -1) 4706 textColor.setAlpha(alpha); 4707 } 4708 if (attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4709 { 4710 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4711 if(alpha > -1) 4712 textBackgroundColor.setAlpha(alpha); 4713 } 4714 4715 if(sdi instanceof ImageInfo) 4716 { 4717 ii = (ImageInfo) sdi; 4718 //Render modifiers////////////////////////////////////////////////// 4719 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 4720 Canvas ctx = new Canvas(bmp); 4721 4722 //draw original icon with potential modifiers. 4723 ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null); 4724 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 4725 4726 4727 renderText(ctx, arrMods, textColor, textBackgroundColor, modifierFont); 4728 4729 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4730 if (fdiBounds != null) { 4731 4732 Paint fdiPaint = new Paint(); 4733 fdiPaint.setAntiAlias(true); 4734 fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 4735 if (alpha > -1) 4736 fdiPaint.setAlpha(alpha); 4737 fdiPaint.setStyle(Style.STROKE); 4738 4739 int dpi = RendererSettings.getInstance().getDeviceDPI(); 4740 int lineLength = dpi / 96 * 6; 4741 int lineGap = dpi / 96 * 4; 4742 4743 /// /////////////////////////////////// 4744 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4745 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4746 //distance = distance / 14f; 4747 lineGap = (int)((distance / 14f) * 2); 4748 lineLength = (int)((distance / 14f) * 3); 4749 /// ////////////////////////////////// 4750 4751 fdiPaint.setPathEffect(new DashPathEffect(new float[] 4752 { 4753 lineLength, lineGap 4754 }, 0)); 4755 4756 float fdiStrokeWidth = Math.round(dpi / 96f); 4757 if (fdiStrokeWidth < 2) 4758 fdiStrokeWidth = 2; 4759 4760 fdiPaint.setStrokeCap(Cap.ROUND); 4761 fdiPaint.setStrokeJoin(Join.MITER); 4762 fdiPaint.setStrokeWidth(fdiStrokeWidth); 4763 4764 Path fdiPath = new Path(); 4765 4766 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4767 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4768 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4769 fdiPath.lineTo(fdiRight.x, fdiRight.y); 4770 ctx.drawPath(fdiPath, fdiPaint); 4771 4772 fdiBounds = null; 4773 4774 } 4775 //</editor-fold> 4776 4777 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 4778 } 4779 else if(sdi instanceof SVGSymbolInfo) 4780 { 4781 String svgStroke = RendererUtilities.colorToHexString(lineColor,false); 4782 String svgStrokeWidth = "3"; 4783 String svgAlpha = null; 4784 if(alpha > -1) 4785 svgAlpha = String.valueOf(alpha); 4786 ssi = (SVGSymbolInfo)sdi; 4787 StringBuilder sbSVG = new StringBuilder(); 4788 sbSVG.append(ssi.getSVG()); 4789 sbSVG.append(renderTextElements(arrMods,textColor,textBackgroundColor)); 4790 4791 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4792 if (fdiBounds != null) 4793 { 4794 /*int dpi = RendererSettings.getInstance().getDeviceDPI(); 4795 int lineLength = dpi / 96 * 6; 4796 int lineGap = dpi / 96 * 4; 4797 String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/ 4798 4799 /// /////////////////////////////////// 4800 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4801 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4802 //distance = distance / 14f; 4803 int lineGap = (int)((distance / 14f) * 2); 4804 int lineLength = (int)((distance / 14f) * 3); 4805 String svgFDIDashArray = "" + lineLength + " " + lineGap; 4806 /// ////////////////////////////////// 4807 4808 SVGPath fdiPath = new SVGPath(); 4809 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4810 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4811 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4812 fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/ 4813 4814 fdiPath.setLineDash(svgFDIDashArray); 4815 sbSVG.append(fdiPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,"round")); 4816 //sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray)); 4817 } 4818 //</editor-fold> 4819 4820 newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds); 4821 } 4822 4823 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 4824 //ctx = null; 4825 4826 // </editor-fold> 4827 } 4828 // </editor-fold> 4829 return newsdi; 4830 4831 } 4832 4833 private static SymbolDimensionInfo shiftUnitPointsAndDraw(ArrayList<TextInfo> tiArray, SymbolDimensionInfo sdi, Map<String,String> attributes, Paint modifierFont) 4834 { 4835 4836 ImageInfo ii = null; 4837 SVGSymbolInfo ssi = null; 4838 SymbolDimensionInfo newsdi = null; 4839 4840 int alpha = -1; 4841 4842 4843 if (attributes != null && attributes.containsKey(MilStdAttributes.Alpha)) 4844 { 4845 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 4846 } 4847 4848 Color textColor = Color.BLACK; 4849 Color textBackgroundColor = null; 4850 4851 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 4852 Point centerPoint = new Point(sdi.getCenterPoint()); 4853 Rect imageBounds = new Rect(sdi.getImageBounds()); 4854 Rect imageBoundsOld = new Rect(sdi.getImageBounds()); 4855 4856 Rect modifierBounds = null; 4857 if (tiArray != null && tiArray.size() > 0) 4858 { 4859 4860 //build modifier bounds///////////////////////////////////////// 4861 modifierBounds = tiArray.get(0).getTextOutlineBounds(); 4862 int size = tiArray.size(); 4863 TextInfo tempShape = null; 4864 for (int i = 1; i < size; i++) 4865 { 4866 tempShape = tiArray.get(i); 4867 modifierBounds.union(tempShape.getTextOutlineBounds()); 4868 } 4869 4870 } 4871 4872 if (modifierBounds != null) 4873 { 4874 4875 imageBounds.union(modifierBounds); 4876 4877 //shift points if needed//////////////////////////////////////// 4878 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4879 { 4880 int shiftX = Math.round(Math.abs(imageBounds.left)), 4881 shiftY = Math.round(Math.abs(imageBounds.top)); 4882 4883 //shift mobility points 4884 int size = tiArray.size(); 4885 TextInfo tempShape = null; 4886 for (int i = 0; i < size; i++) 4887 { 4888 tempShape = tiArray.get(i); 4889 tempShape.shift(shiftX, shiftY); 4890 } 4891 RectUtilities.shift(modifierBounds, shiftX, shiftY); 4892 //modifierBounds.shift(shiftX,shiftY); 4893 4894 //shift image points 4895 centerPoint.offset(shiftX, shiftY); 4896 RectUtilities.shift(symbolBounds, shiftX, shiftY); 4897 RectUtilities.shift(imageBounds, shiftX, shiftY); 4898 RectUtilities.shift(imageBoundsOld, shiftX, shiftY); 4899 /*centerPoint.shift(shiftX, shiftY); 4900 symbolBounds.shift(shiftX, shiftY); 4901 imageBounds.shift(shiftX, shiftY); 4902 imageBoundsOld.shift(shiftX, shiftY);//*/ 4903 } 4904 4905 if (attributes != null && attributes.containsKey(MilStdAttributes.TextColor)) 4906 { 4907 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4908 if(alpha > -1) 4909 textColor.setAlpha(alpha); 4910 } 4911 if (attributes != null && attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4912 { 4913 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4914 if(alpha > -1) 4915 textBackgroundColor.setAlpha(alpha); 4916 } 4917 4918 if(sdi instanceof ImageInfo) 4919 { 4920 ii = (ImageInfo) sdi; 4921 4922 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 4923 Canvas ctx = new Canvas(bmp); 4924 4925 //render//////////////////////////////////////////////////////// 4926 //draw original icon with potential modifiers. 4927 ctx.drawBitmap(ii.getImage(), imageBoundsOld.left, imageBoundsOld.top, null); 4928 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 4929 4930 renderText(ctx, tiArray, textColor, textBackgroundColor, modifierFont); 4931 4932 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 4933 } 4934 else if(sdi instanceof SVGSymbolInfo) 4935 { 4936 ssi = (SVGSymbolInfo)sdi; 4937 StringBuilder sb = new StringBuilder(); 4938 sb.append(ssi.getSVG()); 4939 sb.append(renderTextElements(tiArray,textColor,textBackgroundColor)); 4940 newsdi = new SVGSymbolInfo(sb.toString(),centerPoint,symbolBounds,imageBounds); 4941 } 4942 } 4943 4944 if(newsdi == null) 4945 newsdi = sdi; 4946 4947 return newsdi; 4948 } 4949 private static String renderTextElement(ArrayList<TextInfo> tiArray, Color color, Color backgroundColor) 4950 { 4951 StringBuilder sbSVG = new StringBuilder(); 4952 4953 String svgStroke = RendererUtilities.colorToHexString(RendererUtilities.getIdealOutlineColor(color),false); 4954 if(backgroundColor != null) 4955 svgStroke = RendererUtilities.colorToHexString(backgroundColor,false); 4956 4957 String svgFill = RendererUtilities.colorToHexString(color,false); 4958 String svgStrokeWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth()); 4959 for (TextInfo ti : tiArray) { 4960 sbSVG.append(Shape2SVG.Convert(ti, svgStroke,svgFill,svgStrokeWidth,null,null,null)); 4961 sbSVG.append("\n"); 4962 } 4963 4964 return sbSVG.toString(); 4965 } 4966 4967 private static String renderTextElements(ArrayList<TextInfo> tiArray, Color color, Color backgroundColor) 4968 { 4969 String style = null; 4970 String name = tiArray.get(0).getFontName();//"SansSerif"; 4971 if(!name.endsWith("serif")) 4972 name += ", sans-serif"; 4973 String size = String.valueOf(tiArray.get(0).getFontSize()); 4974 String weight = null; 4975 String anchor = null;//"start"; 4976 if(tiArray.get(0).getFontStyle() == Typeface.BOLD) 4977 weight = "bold"; 4978 StringBuilder sbSVG = new StringBuilder(); 4979 4980 String svgStroke = RendererUtilities.colorToHexString(RendererUtilities.getIdealOutlineColor(color),false); 4981 if(backgroundColor != null) 4982 svgStroke = RendererUtilities.colorToHexString(backgroundColor,false); 4983 4984 String svgFill = RendererUtilities.colorToHexString(color,false); 4985 String svgStrokeWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth()); 4986 sbSVG.append("\n<g"); 4987 sbSVG.append(" font-family=\"").append(name).append('"'); 4988 sbSVG.append(" font-size=\"").append(size).append("px\""); 4989 if(weight != null) 4990 sbSVG.append(" font-weight=\"").append(weight).append("\""); 4991 sbSVG.append(" alignment-baseline=\"alphabetic\"");// 4992 sbSVG.append(">"); 4993 4994 for (TextInfo ti : tiArray) { 4995 sbSVG.append(Shape2SVG.ConvertForGroup(ti, svgStroke,svgFill,svgStrokeWidth,null,null,null)); 4996 sbSVG.append("\n"); 4997 } 4998 sbSVG.append("</g>\n"); 4999 5000 return sbSVG.toString(); 5001 } 5002 private static void renderText(Canvas ctx, ArrayList<TextInfo> tiArray, Color color, Color backgroundColor, Paint font) 5003 { 5004 ModifierRenderer.renderText(ctx, (TextInfo[]) tiArray.toArray(new TextInfo[0]), color, backgroundColor, font); 5005 } 5006 5007 /** 5008 * 5009 * @param ctx 5010 * @param tiArray 5011 * @param color 5012 * @param backgroundColor 5013 */ 5014 public static void renderText(Canvas ctx, TextInfo[] tiArray, Color color, Color backgroundColor, Paint modifierFont) 5015 { 5016 /*for (TextInfo textInfo : tiArray) 5017 { 5018 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5019 }*/ 5020 5021 int size = tiArray.length; 5022 5023 int tbm = RS.getTextBackgroundMethod(); 5024 int outlineWidth = RS.getTextOutlineWidth(); 5025 5026 if (color == null) 5027 { 5028 color = Color.BLACK; 5029 } 5030 5031 Color outlineColor = null; 5032 5033 if(backgroundColor != null) 5034 outlineColor = backgroundColor; 5035 else 5036 outlineColor = RendererUtilities.getIdealOutlineColor(color); 5037 5038 if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE_QUICK) 5039 { 5040 synchronized (modifierFontMutex) { 5041 //draw text outline 5042 modifierFont.setStyle(Style.FILL); 5043 modifierFont.setStrokeWidth(RS.getTextOutlineWidth()); 5044 modifierFont.setColor(outlineColor.toInt()); 5045 5046 if (outlineWidth > 2) 5047 outlineWidth = 2; 5048 5049 if (outlineWidth > 0) { 5050 for (int i = 0; i < size; i++) { 5051 TextInfo textInfo = tiArray[i]; 5052 if (outlineWidth > 0) { 5053 for (int j = 1; j <= outlineWidth; j++) { 5054 if (j == 1) { 5055 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, modifierFont); 5056 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, modifierFont); 5057 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, modifierFont); 5058 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, modifierFont); 5059 5060 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, modifierFont); 5061 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, modifierFont); 5062 5063 } else { 5064 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, modifierFont); 5065 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, modifierFont); 5066 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, modifierFont); 5067 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, modifierFont); 5068 5069 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, modifierFont); 5070 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, modifierFont); 5071 5072 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y + j, modifierFont); 5073 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y - j, modifierFont); 5074 } 5075 5076 } 5077 5078 } 5079 5080 } 5081 } 5082 //draw text 5083 modifierFont.setColor(color.toInt()); 5084 5085 for (int j = 0; j < size; j++) { 5086 TextInfo textInfo = tiArray[j]; 5087 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5088 /*Paint outline = new Paint(); 5089 outline.setStyle(Style.STROKE); 5090 outline.setColor(Color.red.toInt()); 5091 outline.setAlpha(155); 5092 outline.setStrokeWidth(1f); 5093 ctx.drawRect(textInfo.getTextBounds(), outline); 5094 outline.setColor(Color.blue.toInt()); 5095 ctx.drawRect(textInfo.getTextOutlineBounds(), outline);//*/ 5096 } 5097 } 5098 } 5099 else if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE) 5100 { 5101 synchronized (modifierFontMutex) { 5102 //draw text outline 5103 //draw text outline 5104 modifierFont.setStyle(Style.STROKE); 5105 modifierFont.setStrokeWidth(RS.getTextOutlineWidth()); 5106 modifierFont.setColor(outlineColor.toInt()); 5107 if (outlineWidth > 0) { 5108 for (int i = 0; i < size; i++) { 5109 TextInfo textInfo = tiArray[i]; 5110 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5111 } 5112 } 5113 //draw text 5114 modifierFont.setColor(color.toInt()); 5115 modifierFont.setStyle(Style.FILL); 5116 for (int j = 0; j < size; j++) { 5117 TextInfo textInfo = tiArray[j]; 5118 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5119 } 5120 } 5121 } 5122 else if (tbm == RendererSettings.TextBackgroundMethod_COLORFILL) 5123 { 5124 synchronized (modifierFontMutex) { 5125 Paint rectFill = new Paint(); 5126 rectFill.setStyle(Paint.Style.FILL); 5127 rectFill.setColor(outlineColor.toARGB()); 5128 5129 5130 //draw rectangle 5131 for (int k = 0; k < size; k++) { 5132 TextInfo textInfo = tiArray[k]; 5133 ctx.drawRect(textInfo.getTextOutlineBounds(), rectFill); 5134 } 5135 //draw text 5136 modifierFont.setColor(color.toInt()); 5137 modifierFont.setStyle(Style.FILL); 5138 for (int j = 0; j < size; j++) { 5139 TextInfo textInfo = tiArray[j]; 5140 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5141 } 5142 } 5143 } 5144 else if (tbm == RendererSettings.TextBackgroundMethod_NONE) 5145 { 5146 synchronized (modifierFontMutex) { 5147 modifierFont.setColor(color.toInt()); 5148 modifierFont.setStyle(Style.FILL); 5149 for (int j = 0; j < size; j++) { 5150 TextInfo textInfo = tiArray[j]; 5151 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5152 } 5153 } 5154 } 5155 } 5156 5157 /** 5158 * 5159 * @param symbolID 5160 * @param modifiers 5161 * @return int[] where {xposition (-1 left, 0 centered, 1 right), yposition (0 centered, 1+ goes up, 1- goes down), 5162 * centered (0-no, 1-yes)} -999 means passed modifier is not supported by this symbol 5163 */ 5164 private static List<Modifier> getLabelPositionIndexes(String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 5165 { 5166 List<Modifier> mods = null; 5167 if(modifiers != null && !modifiers.isEmpty()) 5168 mods = new ArrayList<>(); 5169 else 5170 return null; 5171 5172 int ver = SymbolID.getVersion(symbolID); 5173 int ss = SymbolID.getSymbolSet(symbolID); 5174 int x = 0; 5175 int y = 0; 5176 boolean centered = true; 5177 int p = RendererSettings.getInstance().getSPModifierPlacement(); 5178 boolean strict = (RendererSettings.getInstance().getSPModifierPlacement() == RendererSettings.ModifierPlacement_STRICT); 5179 if(attributes != null && attributes.containsKey(MilStdAttributes.ModifierPlacement)) 5180 { 5181 String mp = attributes.get(MilStdAttributes.ModifierPlacement); 5182 if(mp.equals("0") || mp.equals("1") || mp.equals("2")) 5183 { 5184 p = Integer.parseInt(mp); 5185 if(p == 0) 5186 strict = true; 5187 else 5188 strict = false; 5189 } 5190 } 5191 String temp = null; 5192 String sep = " "; 5193 if(ss == SymbolID.SymbolSet_DismountedIndividuals) { 5194 ver = SymbolID.Version_2525E; 5195 } 5196 5197 if(ver < SymbolID.Version_2525E) 5198 { 5199 if(ss == SymbolID.SymbolSet_LandUnit || 5200 ss == SymbolID.SymbolSet_LandCivilianUnit_Organization) 5201 { 5202 5203 //Only Command & Control has AA; ec.equals("110000"). Always in the middle of the unit. 5204 if(modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ)) 5205 { 5206 temp = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ); 5207 if(temp != null && !temp.isEmpty()) 5208 mods.add(new Modifier("AA", temp, 0, 0, true)); 5209 } 5210 5211 //Do top center label 5212 x = 0;//centered 5213 y = 9;//on top of symbol 5214 if(modifiers.containsKey(Modifiers.B_ECHELON)) 5215 { 5216 temp = modifiers.get(Modifiers.B_ECHELON); 5217 if(temp != null && !temp.isEmpty()) 5218 mods.add(new Modifier("B", temp, x, y, centered)); 5219 } 5220 5221 //Do right side labels 5222 x = 1;//on right 5223 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5224 { 5225 y = 0;//center 5226 centered = true;//vertically centered, only matters for labels on left and right side 5227 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5228 if(temp != null && !temp.isEmpty()) 5229 mods.add(new Modifier("H", temp, x, y, centered)); 5230 } 5231 else if(!strict) 5232 { 5233 //if no "H', bring G and M closer to the center 5234 centered = false; 5235 } 5236 5237 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5238 { 5239 y = 1;//above center 5240 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5241 if(temp != null && !temp.isEmpty()) 5242 mods.add(new Modifier("G", temp, x, y, centered)); 5243 } 5244 5245 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 5246 { 5247 y = 2; 5248 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5249 y--; 5250 temp = ""; 5251 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 5252 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 5253 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5254 temp += modifiers.get(Modifiers.AS_COUNTRY); 5255 temp = temp.trim(); 5256 if(temp != null && !temp.isEmpty()) 5257 mods.add(new Modifier("F AS", temp, x, y, centered)); 5258 } 5259 5260 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 5261 { 5262 y = -1;//below center 5263 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 5264 if(temp != null && !temp.isEmpty()) 5265 mods.add(new Modifier("M", temp, x, y, centered)); 5266 } 5267 5268 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5269 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 5270 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5271 { 5272 y = -2; 5273 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 5274 y++; 5275 temp = ""; 5276 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5277 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5278 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 5279 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 5280 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5281 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5282 temp = temp.trim(); 5283 if(temp != null && !temp.isEmpty()) 5284 mods.add(new Modifier("J K P", temp, x, y, centered)); 5285 } 5286 5287 //Do left side labels 5288 x = -1;//on left 5289 centered = false; 5290 5291 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5292 { 5293 y = 1; 5294 temp = ""; 5295 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5296 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5297 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5298 temp += modifiers.get(Modifiers.Y_LOCATION); 5299 5300 temp = temp.trim(); 5301 if(temp != null && !temp.isEmpty()) 5302 mods.add(new Modifier("X Y", temp, x, y, centered)); 5303 } 5304 5305 if(modifiers.containsKey(Modifiers.W_DTG_1)) 5306 { 5307 y = 2;//above center 5308 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 5309 y--; 5310 temp = modifiers.get(Modifiers.W_DTG_1); 5311 if(temp != null && !temp.isEmpty()) 5312 mods.add(new Modifier("W", temp, x, y, centered)); 5313 } 5314 5315 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5316 { 5317 y = -1;//below center 5318 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5319 if(temp != null && !temp.isEmpty()) 5320 mods.add(new Modifier("T", temp, x, y, centered)); 5321 } 5322 5323 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5324 { 5325 y = -2; 5326 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5327 y++; 5328 temp = modifiers.get(Modifiers.Z_SPEED); 5329 if(temp != null && !temp.isEmpty()) 5330 mods.add(new Modifier(Modifiers.J_EVALUATION_RATING, temp, x, y, centered)); 5331 } 5332 } 5333 else if(ss == SymbolID.SymbolSet_LandEquipment || 5334 ss == SymbolID.SymbolSet_SignalsIntelligence_Land) 5335 { 5336 //Do top center label 5337 x = 0;//centered 5338 y = 9;//on top of symbol 5339 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 5340 { 5341 temp = modifiers.get(Modifiers.C_QUANTITY); 5342 if(temp != null && !temp.isEmpty()) 5343 mods.add(new Modifier("C", temp, x, y, centered)); 5344 } 5345 5346 //Do right side labels 5347 x = 1;//on right 5348 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 5349 { 5350 y = 0;//center 5351 centered = true;//vertically centered, only matters for labels on left and right side 5352 temp = ""; 5353 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5354 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 5355 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 5356 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 5357 temp = temp.trim(); 5358 if(temp != null && !temp.isEmpty()) 5359 mods.add(new Modifier("H AF", temp, x, y, centered)); 5360 } 5361 else if(!strict) 5362 { 5363 //if no "H', bring G and M closer to the center 5364 centered = false; 5365 } 5366 5367 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5368 { 5369 y = 1;//above center 5370 temp = ""; 5371 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5372 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5373 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5374 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 5375 temp = temp.trim(); 5376 if(temp != null && !temp.isEmpty()) 5377 mods.add(new Modifier("G AQ", temp, x, y, centered)); 5378 } 5379 5380 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5381 { 5382 y = 2; 5383 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 5384 y--; 5385 5386 temp = modifiers.get(Modifiers.AS_COUNTRY); 5387 if(temp != null && !temp.isEmpty()) 5388 mods.add(new Modifier("AS", temp, x, y, centered)); 5389 } 5390 5391 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5392 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 5393 modifiers.containsKey(Modifiers.N_HOSTILE) || 5394 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5395 { 5396 y = -1; 5397 5398 temp = ""; 5399 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5400 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5401 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 5402 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 5403 if(modifiers.containsKey(Modifiers.N_HOSTILE)) 5404 temp += modifiers.get(Modifiers.N_HOSTILE) + sep; 5405 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5406 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5407 temp = temp.trim(); 5408 if(temp != null && !temp.isEmpty()) 5409 mods.add(new Modifier("J L N P", temp, x, y, centered)); 5410 } 5411 5412 //Do left side labels 5413 x = -1;//on left 5414 5415 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 5416 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 5417 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 5418 { 5419 y = 0;//center 5420 centered = true;//vertically centered, only matters for labels on left and right side 5421 5422 temp = ""; 5423 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5424 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 5425 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 5426 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 5427 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 5428 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 5429 temp = temp.trim(); 5430 if(temp != null && !temp.isEmpty()) 5431 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 5432 } 5433 else if(!strict) 5434 { 5435 centered = false; 5436 } 5437 5438 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5439 { 5440 y = 1; 5441 temp = ""; 5442 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5443 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5444 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5445 temp += modifiers.get(Modifiers.Y_LOCATION); 5446 5447 temp = temp.trim(); 5448 mods.add(new Modifier("X Y", temp, x, y, centered)); 5449 } 5450 5451 if(modifiers.containsKey(Modifiers.W_DTG_1) || modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5452 { 5453 y = 2;//above center 5454 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 5455 y--; 5456 5457 temp = modifiers.get(Modifiers.W_DTG_1); 5458 5459 if(temp != null && !temp.isEmpty()) 5460 mods.add(new Modifier("W", temp, x, y, centered)); 5461 } 5462 5463 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5464 { 5465 y = -1;//below center 5466 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5467 if(temp != null && !temp.isEmpty()) 5468 mods.add(new Modifier("T", temp, x, y, centered)); 5469 } 5470 5471 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5472 { 5473 y = -2; 5474 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5475 y++; 5476 temp = modifiers.get(Modifiers.Z_SPEED); 5477 if(temp != null && !temp.isEmpty()) 5478 mods.add(new Modifier("Z", temp, x, y, centered)); 5479 } 5480 } 5481 else if(ss == SymbolID.SymbolSet_LandInstallation) 5482 { 5483 //No top center label 5484 5485 //Do right side labels 5486 x = 1;//on right 5487 5488 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5489 { 5490 y = 0;//center 5491 centered = true;//vertically centered, only matters for labels on left and right side 5492 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5493 5494 if(temp != null && !temp.isEmpty()) 5495 mods.add(new Modifier("H", temp, x, y, centered)); 5496 } 5497 else if(!strict) 5498 { 5499 centered = false; 5500 } 5501 5502 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5503 { 5504 y = 1;//above center 5505 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5506 5507 if(temp != null && !temp.isEmpty()) 5508 mods.add(new Modifier("G", temp, x, y, centered)); 5509 } 5510 5511 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5512 { 5513 y = 2; 5514 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5515 y--; 5516 5517 temp = modifiers.get(Modifiers.AS_COUNTRY); 5518 if(temp != null && !temp.isEmpty()) 5519 mods.add(new Modifier("AS", temp, x, y, centered)); 5520 } 5521 5522 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5523 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 5524 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5525 { 5526 y = -1; 5527 5528 temp = ""; 5529 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5530 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5531 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 5532 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 5533 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5534 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5535 temp = temp.trim(); 5536 mods.add(new Modifier("J K P", temp, x, y, centered)); 5537 } 5538 5539 //Do left side labels 5540 x = -1;//on left 5541 5542 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5543 { 5544 y = 0;//center 5545 centered = true;//vertically centered, only matters for labels on left and right side 5546 5547 temp = ""; 5548 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5549 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5550 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5551 temp += modifiers.get(Modifiers.Y_LOCATION); 5552 temp = temp.trim(); 5553 if(temp != null && !temp.isEmpty()) 5554 mods.add(new Modifier("X Y", temp, x, y, centered)); 5555 } 5556 else if(!strict) 5557 { 5558 centered = false; 5559 } 5560 5561 if(modifiers.containsKey(Modifiers.W_DTG_1)) 5562 { 5563 y = 1;//above center 5564 5565 temp = modifiers.get(Modifiers.W_DTG_1); 5566 5567 if(temp != null && !temp.isEmpty()) 5568 mods.add(new Modifier("W AR", temp, x, y, centered)); 5569 } 5570 5571 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5572 { 5573 y = -1;//below center 5574 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5575 if(temp != null && !temp.isEmpty()) 5576 mods.add(new Modifier("T", temp, x, y, centered)); 5577 } 5578 } 5579 else if(ss == SymbolID.SymbolSet_Air || 5580 ss == SymbolID.SymbolSet_AirMissile || 5581 ss == SymbolID.SymbolSet_SignalsIntelligence_Air) 5582 { 5583 //No top center label 5584 5585 5586 //Do right side labels 5587 x = 1;//on right 5588 centered = false; 5589 5590 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5591 { 5592 y = 1;//above center 5593 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 5594 5595 if(temp != null && !temp.isEmpty()) 5596 mods.add(new Modifier("P", temp, x, y, centered)); 5597 } 5598 5599 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5600 { 5601 y = 2; 5602 if(!strict && !modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5603 y--; 5604 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5605 5606 if(temp != null && !temp.isEmpty()) 5607 mods.add(new Modifier("T", temp, x, y, centered)); 5608 } 5609 5610 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5611 { 5612 y = 3; 5613 if(!strict) 5614 { 5615 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5616 y--; 5617 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5618 y--; 5619 } 5620 5621 temp = modifiers.get(Modifiers.AS_COUNTRY ); 5622 5623 if(temp != null && !temp.isEmpty()) 5624 mods.add(new Modifier("AS", temp, x, y, centered)); 5625 } 5626 5627 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5628 { 5629 y = -1;//below center 5630 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5631 5632 if(temp != null && !temp.isEmpty()) 5633 mods.add(new Modifier("V", temp, x, y, centered)); 5634 } 5635 5636 if(modifiers.containsKey(Modifiers.Z_SPEED) || 5637 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5638 { 5639 y = -2;//below center 5640 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5641 y++; 5642 5643 temp = ""; 5644 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5645 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 5646 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5647 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5648 temp = temp.trim(); 5649 5650 if(temp != null && !temp.isEmpty()) 5651 mods.add(new Modifier("Z X", temp, x, y, centered)); 5652 } 5653 5654 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5655 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5656 { 5657 y = -3; 5658 if(!strict) 5659 { 5660 if(!(modifiers.containsKey(Modifiers.Z_SPEED) || 5661 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5662 y++; 5663 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5664 y++; 5665 } 5666 temp = ""; 5667 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5668 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5669 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5670 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5671 temp = temp.trim(); 5672 if(temp != null && !temp.isEmpty()) 5673 mods.add(new Modifier("G H", temp, x, y, centered)); 5674 } 5675 5676 //No left side labels 5677 5678 } 5679 else if(ss == SymbolID.SymbolSet_Space || 5680 ss == SymbolID.SymbolSet_SpaceMissile || 5681 ss == SymbolID.SymbolSet_SignalsIntelligence_Space) 5682 { 5683 //No top center label 5684 5685 5686 //Do right side labels 5687 x = 1;//on right 5688 centered = false; 5689 5690 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5691 { 5692 y = 1;//above center 5693 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5694 if(temp != null && !temp.isEmpty()) 5695 mods.add(new Modifier("V", temp, x, y, centered)); 5696 } 5697 5698 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5699 { 5700 y = 2; 5701 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5702 y--; 5703 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5704 5705 if(temp != null && !temp.isEmpty()) 5706 mods.add(new Modifier("T", temp, x, y, centered)); 5707 } 5708 5709 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5710 { 5711 y = 3; 5712 if(!strict) 5713 { 5714 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5715 y--; 5716 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5717 y--; 5718 } 5719 5720 temp = modifiers.get(Modifiers.AS_COUNTRY ); 5721 5722 if(temp != null && !temp.isEmpty()) 5723 mods.add(new Modifier("AS", temp, x, y, centered)); 5724 } 5725 5726 if(modifiers.containsKey(Modifiers.Z_SPEED) || 5727 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5728 { 5729 y = -1;//below center 5730 temp = ""; 5731 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5732 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 5733 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5734 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5735 temp = temp.trim(); 5736 5737 if(temp != null && !temp.isEmpty()) 5738 mods.add(new Modifier("Z X", temp, x, y, centered)); 5739 } 5740 5741 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5742 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5743 { 5744 y = -2; 5745 if(!strict && 5746 !(modifiers.containsKey(Modifiers.Z_SPEED) || modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5747 y++; 5748 temp = ""; 5749 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5750 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5751 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5752 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5753 temp = temp.trim(); 5754 if(temp != null && !temp.isEmpty()) 5755 mods.add(new Modifier("G H", temp, x, y, centered)); 5756 } 5757 5758 //No left side labels 5759 } 5760 else if(ss == SymbolID.SymbolSet_SeaSurface || 5761 ss == SymbolID.SymbolSet_SignalsIntelligence_SeaSurface) 5762 { 5763 //No top center label 5764 5765 5766 //Do right side labels 5767 x = 1;//on right 5768 centered = true; 5769 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5770 { 5771 y = 0;//center 5772 centered = true;//vertically centered, only matters for labels on left and right side 5773 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5774 if(temp != null && !temp.isEmpty()) 5775 mods.add(new Modifier("V", temp, x, y, centered)); 5776 } 5777 else if(!strict) 5778 { 5779 //if no "H', bring G and M closer to the center 5780 centered = false; 5781 } 5782 5783 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5784 { 5785 y = 1;//above center 5786 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 5787 if(temp != null && !temp.isEmpty()) 5788 mods.add(new Modifier("P", temp, x, y, centered)); 5789 } 5790 5791 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5792 { 5793 y = 2; 5794 if(!strict && !modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5795 y--; 5796 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5797 5798 if(temp != null && !temp.isEmpty()) 5799 mods.add(new Modifier("T", temp, x, y, centered)); 5800 } 5801 5802 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5803 { 5804 y = 3; 5805 if(!strict) 5806 { 5807 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5808 y--; 5809 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5810 y--; 5811 } 5812 5813 temp = modifiers.get(Modifiers.AS_COUNTRY ); 5814 5815 if(temp != null && !temp.isEmpty()) 5816 mods.add(new Modifier("AS", temp, x, y, centered)); 5817 } 5818 5819 if(modifiers.containsKey(Modifiers.Z_SPEED) || 5820 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5821 { 5822 y = -1;//below center 5823 temp = ""; 5824 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5825 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 5826 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5827 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5828 temp = temp.trim(); 5829 5830 if(temp != null && !temp.isEmpty()) 5831 mods.add(new Modifier("Z X", temp, x, y, centered)); 5832 } 5833 5834 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5835 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5836 { 5837 y = -2; 5838 if(!strict && 5839 !(modifiers.containsKey(Modifiers.Z_SPEED) || modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5840 y++; 5841 temp = ""; 5842 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5843 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5844 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5845 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5846 temp = temp.trim(); 5847 if(temp != null && !temp.isEmpty()) 5848 mods.add(new Modifier("G H", temp, x, y, centered)); 5849 } 5850 5851 //Do left side labels 5852 x = -1; 5853 centered = false; 5854 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) || modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5855 { 5856 y = 3;//above center 5857 if(!strict) 5858 y--; 5859 5860 temp = ""; 5861 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5862 temp = modifiers.get(Modifiers.AQ_GUARDED_UNIT) + sep; 5863 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5864 temp += modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 5865 temp = temp.trim(); 5866 5867 if(temp != null && !temp.isEmpty()) 5868 mods.add(new Modifier("AQ AR", temp, x, y, centered)); 5869 } 5870 } 5871 else if(ss == SymbolID.SymbolSet_SeaSubsurface || 5872 ss == SymbolID.SymbolSet_SignalsIntelligence_SeaSubsurface) 5873 { 5874 //No top center label 5875 5876 5877 //Do right side labels 5878 x = 1;//on right 5879 centered = false; 5880 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5881 { 5882 y = 1;//center 5883 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5884 if(temp != null && !temp.isEmpty()) 5885 mods.add(new Modifier("V", temp, x, y, centered)); 5886 } 5887 5888 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5889 { 5890 y = 2; 5891 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5892 y--; 5893 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5894 5895 if(temp != null && !temp.isEmpty()) 5896 mods.add(new Modifier("T", temp, x, y, centered)); 5897 } 5898 5899 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5900 { 5901 y = 3; 5902 if(!strict) 5903 { 5904 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5905 y--; 5906 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5907 y--; 5908 } 5909 5910 temp = modifiers.get(Modifiers.AS_COUNTRY ); 5911 5912 if(temp != null && !temp.isEmpty()) 5913 mods.add(new Modifier("AS", temp, x, y, centered)); 5914 } 5915 5916 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5917 { 5918 y = -1;//below center 5919 5920 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5921 5922 if(temp != null && !temp.isEmpty()) 5923 mods.add(new Modifier("X", temp, x, y, centered)); 5924 } 5925 5926 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5927 { 5928 y = -2; 5929 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5930 y++; 5931 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5932 5933 if(temp != null && !temp.isEmpty()) 5934 mods.add(new Modifier("G", temp, x, y, centered)); 5935 } 5936 5937 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5938 { 5939 y = -3;//below center 5940 if(!strict) 5941 { 5942 if(!modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5943 y++; 5944 if(!modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5945 y++; 5946 } 5947 5948 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5949 5950 if(temp != null && !temp.isEmpty()) 5951 mods.add(new Modifier("H", temp, x, y, centered)); 5952 } 5953 5954 //Do left side labels 5955 x = -1; 5956 centered = false; 5957 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5958 { 5959 y = 3;//above center 5960 if(!strict) 5961 { 5962 y--; 5963 } 5964 5965 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 5966 5967 if(temp != null && !temp.isEmpty()) 5968 mods.add(new Modifier("AR", temp, x, y, centered)); 5969 } 5970 5971 } 5972 else if(ss == SymbolID.SymbolSet_Activities) 5973 { 5974 //No top center label 5975 5976 //Do right side labels 5977 x = 1;//on right 5978 centered = false; 5979 5980 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5981 { 5982 y = 1; 5983 5984 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5985 if(temp != null && !temp.isEmpty()) 5986 mods.add(new Modifier("G", temp, x, y, centered)); 5987 } 5988 5989 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5990 { 5991 y = 2; 5992 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5993 y--; 5994 temp = modifiers.get(Modifiers.AS_COUNTRY); 5995 5996 if(temp != null && !temp.isEmpty()) 5997 mods.add(new Modifier("AS", temp, x, y, centered)); 5998 } 5999 6000 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6001 { 6002 y = -1;//below center 6003 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6004 if(temp != null && !temp.isEmpty()) 6005 mods.add(new Modifier("H", temp, x, y, centered)); 6006 } 6007 6008 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6009 { 6010 y = -2; 6011 if(!strict && !modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6012 y++; 6013 temp = temp = modifiers.get(Modifiers.J_EVALUATION_RATING); 6014 6015 if(temp != null && !temp.isEmpty()) 6016 mods.add(new Modifier("J", temp, x, y, centered)); 6017 } 6018 6019 //Do left side labels 6020 x = -1;//on left 6021 centered = false; 6022 6023 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6024 { 6025 y = 1; 6026 temp = modifiers.get(Modifiers.Y_LOCATION); 6027 6028 if(temp != null && !temp.isEmpty()) 6029 mods.add(new Modifier("Y", temp, x, y, centered)); 6030 } 6031 6032 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6033 { 6034 y = 2;//above center 6035 if(!strict && !modifiers.containsKey(Modifiers.Y_LOCATION)) 6036 y--; 6037 temp = modifiers.get(Modifiers.W_DTG_1); 6038 if(temp != null && !temp.isEmpty()) 6039 mods.add(new Modifier("W", temp, x, y, centered)); 6040 } 6041 6042 } 6043 else if(ss == SymbolID.SymbolSet_CyberSpace) 6044 { 6045 //Do top center label 6046 x = 0;//centered 6047 y = 9;//on top of symbol 6048 if(modifiers.containsKey(Modifiers.B_ECHELON)) 6049 { 6050 temp = modifiers.get(Modifiers.B_ECHELON); 6051 if(temp != null && !temp.isEmpty()) 6052 mods.add(new Modifier("B", temp, x, y, centered)); 6053 } 6054 6055 //Do right side labels 6056 x = 1;//on right 6057 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6058 { 6059 y = 0;//center 6060 centered = true;//vertically centered, only matters for labels on left and right side 6061 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6062 if(temp != null && !temp.isEmpty()) 6063 mods.add(new Modifier("H", temp, x, y, centered)); 6064 } 6065 else if(!strict) 6066 { 6067 //if no "H', bring G and M closer to the center 6068 centered = false; 6069 } 6070 6071 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6072 { 6073 y = 1;//above center 6074 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 6075 if(temp != null && !temp.isEmpty()) 6076 mods.add(new Modifier("G", temp, x, y, centered)); 6077 } 6078 6079 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 6080 { 6081 y = 2; 6082 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6083 y--; 6084 temp = ""; 6085 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 6086 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 6087 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6088 temp += modifiers.get(Modifiers.AS_COUNTRY); 6089 temp = temp.trim(); 6090 if(temp != null && !temp.isEmpty()) 6091 mods.add(new Modifier("F AS", temp, x, y, centered)); 6092 } 6093 6094 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6095 { 6096 y = -1;//below center 6097 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6098 if(temp != null && !temp.isEmpty()) 6099 mods.add(new Modifier("M", temp, x, y, centered)); 6100 } 6101 6102 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6103 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6104 { 6105 y = -2; 6106 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6107 y++; 6108 temp = ""; 6109 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6110 temp = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6111 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6112 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 6113 6114 temp = temp.trim(); 6115 if(temp != null && !temp.isEmpty()) 6116 mods.add(new Modifier("K L", temp, x, y, centered)); 6117 } 6118 6119 //Do left side labels 6120 x = -1;//on left 6121 centered = true; 6122 6123 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6124 { 6125 y = 0; 6126 temp = modifiers.get(Modifiers.Y_LOCATION); 6127 6128 if(temp != null && !temp.isEmpty()) 6129 mods.add(new Modifier("Y", temp, x, y, centered)); 6130 } 6131 else if (!strict) 6132 { 6133 centered = false; 6134 } 6135 6136 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6137 { 6138 y = 1;//above center 6139 temp = modifiers.get(Modifiers.W_DTG_1); 6140 if(temp != null && !temp.isEmpty()) 6141 mods.add(new Modifier("W", temp, x, y, centered)); 6142 } 6143 6144 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6145 { 6146 y = -1;//below center 6147 temp = ""; 6148 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6149 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 6150 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6151 temp += modifiers.get(Modifiers.V_EQUIP_TYPE); 6152 6153 temp = temp.trim(); 6154 if(temp != null && !temp.isEmpty()) 6155 mods.add(new Modifier("T V", temp, x, y, centered)); 6156 } 6157 6158 } 6159 /*else if(ver == SymbolID.SymbolSet_MineWarfare) 6160 { 6161 //no modifiers 6162 }//*/ 6163 //else//SymbolSet Unknown 6164 //processUnknownTextModifiers 6165 } 6166 else// if(ver >= SymbolID.Version_2525E) 6167 { 6168 int fs = SymbolID.getFrameShape(symbolID); 6169 if(ss == SymbolID.SymbolSet_LandUnit || 6170 ss == SymbolID.SymbolSet_LandCivilianUnit_Organization || 6171 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_LandUnit)) 6172 { 6173 6174 //Only Command & Control has AA; ec.equals("110000"). Always in the middle of the unit. 6175 if(modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ)) 6176 { 6177 temp = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ); 6178 if(temp != null && !temp.isEmpty()) 6179 mods.add(new Modifier("AA", temp, 0, 0, true)); 6180 } 6181 6182 //Do top center label 6183 x = 0;//centered 6184 y = 9;//on top of symbol 6185 if(modifiers.containsKey(Modifiers.B_ECHELON)) 6186 { 6187 temp = modifiers.get(Modifiers.B_ECHELON); 6188 if(temp != null && !temp.isEmpty()) 6189 mods.add(new Modifier("B", temp, x, y, centered)); 6190 } 6191 6192 //Do right side labels 6193 x = 1;//on right 6194 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6195 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6196 { 6197 y = 0;//center 6198 centered = true;//vertically centered, only matters for labels on left and right side 6199 temp = ""; 6200 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6201 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6202 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6203 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6204 temp = temp.trim(); 6205 if(temp != null && !temp.isEmpty()) 6206 mods.add(new Modifier("H AF", temp, x, y, centered)); 6207 } 6208 else if(!strict) 6209 { 6210 //if no "H', bring G and M closer to the center 6211 centered = false; 6212 } 6213 6214 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6215 { 6216 y = 1;//above center 6217 temp = ""; 6218 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6219 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6220 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6221 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6222 temp = temp.trim(); 6223 if(temp != null && !temp.isEmpty()) 6224 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6225 } 6226 6227 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 6228 { 6229 y = 2; 6230 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6231 y--; 6232 temp = ""; 6233 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 6234 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 6235 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6236 temp += modifiers.get(Modifiers.AS_COUNTRY); 6237 temp = temp.trim(); 6238 if(temp != null && !temp.isEmpty()) 6239 mods.add(new Modifier("F AS", temp, x, y, centered)); 6240 } 6241 6242 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6243 { 6244 y = -1;//below center 6245 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6246 if(temp != null && !temp.isEmpty()) 6247 mods.add(new Modifier("M", temp, x, y, centered)); 6248 } 6249 6250 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6251 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6252 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 6253 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6254 { 6255 y = -2; 6256 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6257 y++; 6258 temp = ""; 6259 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6260 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6261 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6262 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6263 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6264 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 6265 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6266 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6267 temp = temp.trim(); 6268 if(temp != null && !temp.isEmpty()) 6269 mods.add(new Modifier("J K L P", temp, x, y, centered)); 6270 } 6271 6272 //Do left side labels 6273 x = -1;//on left 6274 6275 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 6276 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 6277 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6278 { 6279 y = 0;//center 6280 centered = true;//vertically centered, only matters for labels on left and right side 6281 6282 temp = ""; 6283 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6284 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6285 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6286 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 6287 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6288 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6289 temp = temp.trim(); 6290 if(temp != null && !temp.isEmpty()) 6291 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 6292 } 6293 else if(!strict) 6294 { 6295 centered = false; 6296 } 6297 6298 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6299 { 6300 y = 1; 6301 temp = ""; 6302 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6303 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6304 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6305 temp += modifiers.get(Modifiers.Y_LOCATION); 6306 6307 temp = temp.trim(); 6308 mods.add(new Modifier("X Y", temp, x, y, centered)); 6309 } 6310 6311 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6312 { 6313 y = 2;//above center 6314 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6315 y--; 6316 6317 temp = modifiers.get(Modifiers.W_DTG_1); 6318 6319 if(temp != null && !temp.isEmpty()) 6320 mods.add(new Modifier("W", temp, x, y, centered)); 6321 } 6322 6323 if(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6324 { 6325 y = -1;//below center 6326 temp = ""; 6327 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6328 temp = modifiers.get(Modifiers.C_QUANTITY) + sep; 6329 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6330 temp += modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6331 6332 temp = temp.trim(); 6333 if(temp != null && !temp.isEmpty()) 6334 mods.add(new Modifier("C T", temp, x, y, centered)); 6335 } 6336 6337 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6338 { 6339 y = -2; 6340 if(!strict && !(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 6341 y++; 6342 temp = modifiers.get(Modifiers.Z_SPEED); 6343 if(temp != null && !temp.isEmpty()) 6344 mods.add(new Modifier("Z", temp, x, y, centered)); 6345 } 6346 } 6347 else if(ss == SymbolID.SymbolSet_LandEquipment || 6348 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_LandEquipment)) 6349 { 6350 //Do top center label 6351 x = 0;//centered 6352 y = 9;//on top of symbol 6353 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6354 { 6355 temp = modifiers.get(Modifiers.C_QUANTITY); 6356 if(temp != null && !temp.isEmpty()) 6357 mods.add(new Modifier("C", temp, x, y, centered)); 6358 } 6359 6360 //Do right side labels 6361 x = 1;//on right 6362 centered = false; 6363 6364 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6365 { 6366 y = 1;//above center 6367 temp = ""; 6368 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6369 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6370 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6371 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6372 temp = temp.trim(); 6373 if(temp != null && !temp.isEmpty()) 6374 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6375 } 6376 6377 if( modifiers.containsKey(Modifiers.AS_COUNTRY)) 6378 { 6379 y = 2; 6380 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6381 y--; 6382 temp = modifiers.get(Modifiers.AS_COUNTRY); 6383 6384 if(temp != null && !temp.isEmpty()) 6385 mods.add(new Modifier("AS", temp, x, y, centered)); 6386 } 6387 6388 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6389 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6390 { 6391 y = -1; 6392 temp = ""; 6393 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6394 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6395 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6396 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6397 temp = temp.trim(); 6398 if(temp != null && !temp.isEmpty()) 6399 mods.add(new Modifier("H AF", temp, x, y, centered)); 6400 } 6401 6402 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6403 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6404 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 6405 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6406 { 6407 y = -2; 6408 if(!strict && !(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6409 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))) 6410 y++; 6411 temp = ""; 6412 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6413 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6414 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6415 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6416 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6417 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 6418 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6419 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6420 temp = temp.trim(); 6421 if(temp != null && !temp.isEmpty()) 6422 mods.add(new Modifier("J K L P", temp, x, y, centered)); 6423 } 6424 6425 //Do left side labels 6426 x = -1;//on left 6427 6428 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 6429 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 6430 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6431 { 6432 y = 0;//center 6433 centered = true;//vertically centered, only matters for labels on left and right side 6434 6435 temp = ""; 6436 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6437 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6438 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6439 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 6440 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6441 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6442 temp = temp.trim(); 6443 if(temp != null && !temp.isEmpty()) 6444 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 6445 } 6446 else if(!strict) 6447 { 6448 centered = false; 6449 } 6450 6451 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6452 { 6453 y = 1; 6454 temp = ""; 6455 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6456 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6457 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6458 temp += modifiers.get(Modifiers.Y_LOCATION); 6459 6460 temp = temp.trim(); 6461 mods.add(new Modifier("X Y", temp, x, y, centered)); 6462 } 6463 6464 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6465 { 6466 y = 2;//above center 6467 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6468 y--; 6469 6470 temp = modifiers.get(Modifiers.W_DTG_1); 6471 6472 if(temp != null && !temp.isEmpty()) 6473 mods.add(new Modifier("W", temp, x, y, centered)); 6474 } 6475 6476 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6477 { 6478 y = -1;//below center 6479 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6480 6481 temp = temp.trim(); 6482 if(temp != null && !temp.isEmpty()) 6483 mods.add(new Modifier("T", temp, x, y, centered)); 6484 } 6485 6486 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6487 { 6488 y = -2; 6489 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6490 y++; 6491 temp = modifiers.get(Modifiers.Z_SPEED); 6492 if(temp != null && !temp.isEmpty()) 6493 mods.add(new Modifier("Z", temp, x, y, centered)); 6494 } 6495 } 6496 else if(ss == SymbolID.SymbolSet_LandInstallation) 6497 { 6498 //No top center label 6499 6500 //Do right side labels 6501 x = 1;//on right 6502 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6503 { 6504 y = 0;//center 6505 centered = true;//vertically centered, only matters for labels on left and right side 6506 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6507 6508 if(temp != null && !temp.isEmpty()) 6509 mods.add(new Modifier("H", temp, x, y, centered)); 6510 } 6511 else if(!strict) 6512 { 6513 //if no "H', bring G and M closer to the center 6514 centered = false; 6515 } 6516 6517 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6518 { 6519 y = 1;//above center 6520 temp = ""; 6521 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6522 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6523 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6524 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6525 temp = temp.trim(); 6526 if(temp != null && !temp.isEmpty()) 6527 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6528 } 6529 6530 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6531 { 6532 y = 2; 6533 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6534 y--; 6535 temp = modifiers.get(Modifiers.AS_COUNTRY); 6536 6537 if(temp != null && !temp.isEmpty()) 6538 mods.add(new Modifier("AS", temp, x, y, centered)); 6539 } 6540 6541 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6542 { 6543 y = -1;//below center 6544 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6545 if(temp != null && !temp.isEmpty()) 6546 mods.add(new Modifier("M", temp, x, y, centered)); 6547 } 6548 6549 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6550 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6551 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6552 { 6553 y = -2; 6554 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6555 y++; 6556 temp = ""; 6557 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6558 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6559 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6560 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6561 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6562 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6563 temp = temp.trim(); 6564 if(temp != null && !temp.isEmpty()) 6565 mods.add(new Modifier("J K P", temp, x, y, centered)); 6566 } 6567 6568 //Do left side labels 6569 x = -1;//on left 6570 centered = false; 6571 6572 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6573 { 6574 y = 1; 6575 temp = ""; 6576 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6577 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6578 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6579 temp += modifiers.get(Modifiers.Y_LOCATION); 6580 6581 temp = temp.trim(); 6582 mods.add(new Modifier("X Y", temp, x, y, centered)); 6583 } 6584 6585 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6586 { 6587 y = 2;//above center 6588 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6589 y--; 6590 6591 temp = modifiers.get(Modifiers.W_DTG_1); 6592 6593 if(temp != null && !temp.isEmpty()) 6594 mods.add(new Modifier("W", temp, x, y, centered)); 6595 } 6596 6597 if(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6598 { 6599 y = -1;//below center 6600 temp = ""; 6601 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6602 temp = modifiers.get(Modifiers.C_QUANTITY) + sep; 6603 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6604 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6605 6606 temp = temp.trim(); 6607 if(temp != null && !temp.isEmpty()) 6608 mods.add(new Modifier("C AE", temp, x, y, centered)); 6609 } 6610 6611 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6612 { 6613 y = -2; 6614 if(!strict && !(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))) 6615 y++; 6616 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6617 if(temp != null && !temp.isEmpty()) 6618 mods.add(new Modifier("T", temp, x, y, centered)); 6619 } 6620 } 6621 else if(ss == SymbolID.SymbolSet_Space || 6622 ss == SymbolID.SymbolSet_SpaceMissile || 6623 ss == SymbolID.SymbolSet_Air || 6624 ss == SymbolID.SymbolSet_AirMissile || 6625 (ss == SymbolID.SymbolSet_SignalsIntelligence && 6626 (fs == SymbolID.FrameShape_Space || fs == SymbolID.FrameShape_Air))) 6627 { 6628 //No top center label 6629 x = 0;//centered 6630 y = 9;//on top of symbol 6631 6632 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6633 { 6634 temp = modifiers.get(Modifiers.C_QUANTITY); 6635 if(temp != null && !temp.isEmpty()) 6636 mods.add(new Modifier("C", temp, x, y, centered)); 6637 } 6638 else if(modifiers.containsKey(Modifiers.B_ECHELON)) 6639 { 6640 temp = modifiers.get(Modifiers.B_ECHELON); 6641 if(temp != null && !temp.isEmpty()) 6642 mods.add(new Modifier("B", temp, x, y, centered)); 6643 } 6644 6645 6646 //Do right side labels 6647 x = 1;//on right 6648 centered = true; 6649 6650 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6651 { 6652 y = 0;// 6653 temp = ""; 6654 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6655 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6656 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6657 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6658 temp = temp.trim(); 6659 6660 if(temp != null && !temp.isEmpty()) 6661 mods.add(new Modifier("V AF", temp, x, y, centered)); 6662 } 6663 else 6664 { 6665 centered = false; 6666 } 6667 6668 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6669 { 6670 y = 1;//above center 6671 temp = ""; 6672 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6673 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 6674 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6675 temp += modifiers.get(Modifiers.Y_LOCATION); 6676 temp = temp.trim(); 6677 6678 if(temp != null && !temp.isEmpty()) 6679 mods.add(new Modifier("T Y", temp, x, y, centered)); 6680 } 6681 6682 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6683 { 6684 y = 2; 6685 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6686 y--; 6687 temp = modifiers.get(Modifiers.AS_COUNTRY); 6688 6689 if(temp != null && !temp.isEmpty()) 6690 mods.add(new Modifier("AS", temp, x, y, centered)); 6691 } 6692 6693 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) || 6694 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || 6695 modifiers.containsKey(Modifiers.Z_SPEED)) 6696 { 6697 y = -1;//below center 6698 temp = ""; 6699 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6700 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS) + sep; 6701 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6702 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6703 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6704 temp = modifiers.get(Modifiers.Z_SPEED); 6705 6706 temp = temp.trim(); 6707 6708 if(temp != null && !temp.isEmpty()) 6709 mods.add(new Modifier("P X Z", temp, x, y, centered)); 6710 } 6711 6712 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6713 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6714 modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6715 { 6716 y = -2;//below center 6717 if(!(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) || 6718 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || 6719 modifiers.containsKey(Modifiers.Z_SPEED))) 6720 y++; 6721 6722 temp = ""; 6723 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6724 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6725 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6726 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6727 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6728 temp += modifiers.get(Modifiers.J_EVALUATION_RATING); 6729 temp = temp.trim(); 6730 6731 if(temp != null && !temp.isEmpty()) 6732 mods.add(new Modifier("G H J", temp, x, y, centered)); 6733 } 6734 6735 //No left side labels 6736 x = -1;//on right 6737 centered = true; 6738 6739 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6740 { 6741 y = 0;// 6742 temp = temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE); 6743 6744 if(temp != null && !temp.isEmpty()) 6745 mods.add(new Modifier("AD", temp, x, y, centered)); 6746 } 6747 else 6748 { 6749 centered = false; 6750 } 6751 6752 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6753 { 6754 y = 1;//above center 6755 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 6756 6757 if(temp != null && !temp.isEmpty()) 6758 mods.add(new Modifier("AR", temp, x, y, centered)); 6759 } 6760 6761 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6762 { 6763 y = 2; 6764 if(!strict && !modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6765 y--; 6766 temp = modifiers.get(Modifiers.W_DTG_1); 6767 6768 if(temp != null && !temp.isEmpty()) 6769 mods.add(new Modifier("W", temp, x, y, centered)); 6770 } 6771 } 6772 else if(ss == SymbolID.SymbolSet_SeaSurface || 6773 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_SeaSurface)) 6774 { 6775 //No top center label 6776 6777 6778 //Do right side labels 6779 x = 1;//on right 6780 centered = false; 6781 6782 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6783 { 6784 y = 1;//above center 6785 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 6786 6787 if(temp != null && !temp.isEmpty()) 6788 mods.add(new Modifier("V", temp, x, y, centered)); 6789 } 6790 6791 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6792 { 6793 y = 2; 6794 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6795 y--; 6796 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6797 6798 if(temp != null && !temp.isEmpty()) 6799 mods.add(new Modifier("T", temp, x, y, centered)); 6800 } 6801 6802 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6803 { 6804 y = 3; 6805 if(!strict) 6806 { 6807 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6808 y--; 6809 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6810 y--; 6811 } 6812 6813 temp = modifiers.get(Modifiers.AS_COUNTRY ); 6814 6815 if(temp != null && !temp.isEmpty()) 6816 mods.add(new Modifier("AS", temp, x, y, centered)); 6817 } 6818 6819 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6820 { 6821 y = -1;//below center 6822 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 6823 6824 if(temp != null && !temp.isEmpty()) 6825 mods.add(new Modifier("P", temp, x, y, centered)); 6826 } 6827 6828 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6829 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6830 { 6831 y = -2;//below center 6832 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6833 y++; 6834 6835 temp = ""; 6836 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6837 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6838 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6839 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6840 temp = temp.trim(); 6841 6842 if(temp != null && !temp.isEmpty()) 6843 mods.add(new Modifier("G H", temp, x, y, centered)); 6844 } 6845 6846 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 6847 modifiers.containsKey(Modifiers.Z_SPEED)) 6848 { 6849 y = -3; 6850 if(!strict) 6851 { 6852 if(!(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6853 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 6854 y++; 6855 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6856 y++; 6857 } 6858 temp = ""; 6859 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6860 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 6861 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6862 temp += modifiers.get(Modifiers.Z_SPEED); 6863 temp = temp.trim(); 6864 if(temp != null && !temp.isEmpty()) 6865 mods.add(new Modifier("Y Z", temp, x, y, centered)); 6866 } 6867 6868 //No left side labels 6869 x = -1; 6870 centered = false; 6871 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) || 6872 modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6873 { 6874 y = 2; 6875 if(!strict) 6876 { 6877 y--; 6878 } 6879 temp = ""; 6880 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6881 temp = modifiers.get(Modifiers.AQ_GUARDED_UNIT) + sep; 6882 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6883 temp += modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 6884 temp = temp.trim(); 6885 if(temp != null && !temp.isEmpty()) 6886 mods.add(new Modifier("AQ AR", temp, x, y, centered)); 6887 } 6888 } 6889 else if(ss == SymbolID.SymbolSet_SeaSubsurface || 6890 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_SeaSubsurface)) 6891 { 6892 //No top center label 6893 6894 6895 //Do right side labels 6896 x = 1;//on right 6897 centered = false; 6898 6899 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6900 { 6901 y = 1;//above center 6902 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 6903 6904 if(temp != null && !temp.isEmpty()) 6905 mods.add(new Modifier("V", temp, x, y, centered)); 6906 } 6907 6908 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6909 { 6910 y = 2; 6911 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6912 y--; 6913 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6914 6915 if(temp != null && !temp.isEmpty()) 6916 mods.add(new Modifier("T", temp, x, y, centered)); 6917 } 6918 6919 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6920 { 6921 y = 3; 6922 if(!strict) 6923 { 6924 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6925 y--; 6926 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6927 y--; 6928 } 6929 6930 temp = modifiers.get(Modifiers.AS_COUNTRY ); 6931 6932 if(temp != null && !temp.isEmpty()) 6933 mods.add(new Modifier("AS", temp, x, y, centered)); 6934 } 6935 6936 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6937 { 6938 y = -1;//below center 6939 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 6940 6941 if(temp != null && !temp.isEmpty()) 6942 mods.add(new Modifier("P", temp, x, y, centered)); 6943 } 6944 6945 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6946 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6947 { 6948 y = -2;//below center 6949 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6950 y++; 6951 6952 temp = ""; 6953 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6954 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6955 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6956 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6957 temp = temp.trim(); 6958 6959 if(temp != null && !temp.isEmpty()) 6960 mods.add(new Modifier("G H", temp, x, y, centered)); 6961 } 6962 6963 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 6964 modifiers.containsKey(Modifiers.Z_SPEED)) 6965 { 6966 y = -3; 6967 if(!strict) 6968 { 6969 if(!(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6970 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 6971 y++; 6972 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6973 y++; 6974 } 6975 temp = ""; 6976 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6977 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 6978 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6979 temp += modifiers.get(Modifiers.Z_SPEED); 6980 temp = temp.trim(); 6981 if(temp != null && !temp.isEmpty()) 6982 mods.add(new Modifier("Y Z", temp, x, y, centered)); 6983 } 6984 6985 //No left side labels 6986 x = -1; 6987 centered = false; 6988 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6989 { 6990 y = 1; 6991 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 6992 6993 if(temp != null && !temp.isEmpty()) 6994 mods.add(new Modifier("X", temp, x, y, centered)); 6995 } 6996 6997 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6998 { 6999 y = 2; 7000 if(!strict && !modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7001 { 7002 y--; 7003 } 7004 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 7005 temp = temp.trim(); 7006 if(temp != null && !temp.isEmpty()) 7007 mods.add(new Modifier("AR", temp, x, y, centered)); 7008 } 7009 } 7010 else if(ss == SymbolID.SymbolSet_DismountedIndividuals) 7011 { 7012 //No top center label 7013 7014 7015 //Do right side labels 7016 x = 1;//on right 7017 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7018 { 7019 y = 0;//center 7020 centered = true;//vertically centered, only matters for labels on left and right side 7021 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7022 7023 if(temp != null && !temp.isEmpty()) 7024 mods.add(new Modifier("H", temp, x, y, centered)); 7025 } 7026 else if(!strict) 7027 { 7028 centered = false; 7029 } 7030 7031 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7032 { 7033 y = 1;//above center 7034 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 7035 7036 if(temp != null && !temp.isEmpty()) 7037 mods.add(new Modifier("G", temp, x, y, centered)); 7038 } 7039 7040 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7041 { 7042 y = 2; 7043 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))) 7044 y--; 7045 temp = modifiers.get(Modifiers.AS_COUNTRY); 7046 7047 if(temp != null && !temp.isEmpty()) 7048 mods.add(new Modifier("AS", temp, x, y, centered)); 7049 } 7050 7051 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7052 { 7053 y = -1;//below center 7054 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 7055 if(temp != null && !temp.isEmpty()) 7056 mods.add(new Modifier("M", temp, x, y, centered)); 7057 } 7058 7059 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 7060 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 7061 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7062 { 7063 y = -2; 7064 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7065 y++; 7066 temp = ""; 7067 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7068 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 7069 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7070 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 7071 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7072 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 7073 temp = temp.trim(); 7074 if(temp != null && !temp.isEmpty()) 7075 mods.add(new Modifier("J K P", temp, x, y, centered)); 7076 } 7077 7078 //Do left side labels 7079 x = -1;//on left 7080 7081 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 7082 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7083 { 7084 y = 0;//center 7085 centered = true;//vertically centered, only matters for labels on left and right side 7086 7087 temp = ""; 7088 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7089 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 7090 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7091 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 7092 temp = temp.trim(); 7093 if(temp != null && !temp.isEmpty()) 7094 mods.add(new Modifier("V AF", temp, x, y, centered)); 7095 } 7096 else if(!strict) 7097 { 7098 centered = false; 7099 } 7100 7101 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 7102 { 7103 y = 1; 7104 temp = ""; 7105 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7106 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 7107 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7108 temp += modifiers.get(Modifiers.Y_LOCATION); 7109 7110 temp = temp.trim(); 7111 mods.add(new Modifier("X Y", temp, x, y, centered)); 7112 } 7113 7114 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7115 { 7116 y = 2;//above center 7117 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 7118 y--; 7119 7120 temp = modifiers.get(Modifiers.W_DTG_1); 7121 7122 if(temp != null && !temp.isEmpty()) 7123 mods.add(new Modifier("W", temp, x, y, centered)); 7124 } 7125 7126 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7127 { 7128 y = -1;//below center 7129 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7130 7131 if(temp != null && !temp.isEmpty()) 7132 mods.add(new Modifier("T", temp, x, y, centered)); 7133 } 7134 7135 if(modifiers.containsKey(Modifiers.Z_SPEED)) 7136 { 7137 y = -2; 7138 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 7139 y++; 7140 temp = modifiers.get(Modifiers.Z_SPEED); 7141 if(temp != null && !temp.isEmpty()) 7142 mods.add(new Modifier("Z", temp, x, y, centered)); 7143 } 7144 } 7145 else if(ss == SymbolID.SymbolSet_Activities) 7146 { 7147 //No top center label 7148 7149 7150 //Do right side labels 7151 x = 1;//on right 7152 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7153 { 7154 y = 0;//center 7155 centered = true;//vertically centered, only matters for labels on left and right side 7156 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 7157 7158 if(temp != null && !temp.isEmpty()) 7159 mods.add(new Modifier("G", temp, x, y, centered)); 7160 } 7161 else if(!strict) 7162 { 7163 centered = false; 7164 } 7165 7166 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7167 { 7168 y = 1;//above center 7169 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7170 7171 if(temp != null && !temp.isEmpty()) 7172 mods.add(new Modifier("T", temp, x, y, centered)); 7173 } 7174 7175 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7176 { 7177 y = 2; 7178 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 7179 y--; 7180 temp = modifiers.get(Modifiers.AS_COUNTRY); 7181 7182 if(temp != null && !temp.isEmpty()) 7183 mods.add(new Modifier("AS", temp, x, y, centered)); 7184 } 7185 7186 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7187 { 7188 y = -1;//below center 7189 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7190 if(temp != null && !temp.isEmpty()) 7191 mods.add(new Modifier("H", temp, x, y, centered)); 7192 } 7193 7194 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7195 { 7196 y = -2; 7197 if(!strict && !modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7198 y++; 7199 temp = modifiers.get(Modifiers.J_EVALUATION_RATING); 7200 7201 if(temp != null && !temp.isEmpty()) 7202 mods.add(new Modifier("J", temp, x, y, centered)); 7203 } 7204 7205 //Do left side labels 7206 x = -1;//on left 7207 7208 if(!strict) 7209 { 7210 centered = false; 7211 } 7212 7213 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7214 { 7215 y = 1; 7216 temp = modifiers.get(Modifiers.Y_LOCATION); 7217 7218 if(temp != null && !temp.isEmpty()) 7219 mods.add(new Modifier("Y", temp, x, y, centered)); 7220 } 7221 7222 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7223 { 7224 y = 2;//above center 7225 if(!strict && !(modifiers.containsKey(Modifiers.Y_LOCATION))) 7226 y--; 7227 7228 temp = modifiers.get(Modifiers.W_DTG_1); 7229 7230 if(temp != null && !temp.isEmpty()) 7231 mods.add(new Modifier("W", temp, x, y, centered)); 7232 } 7233 7234 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 7235 { 7236 y = -1;//below center 7237 temp = modifiers.get(Modifiers.C_QUANTITY); 7238 7239 if(temp != null && !temp.isEmpty()) 7240 mods.add(new Modifier("C", temp, x, y, centered)); 7241 } 7242 7243 } 7244 else if(ss == SymbolID.SymbolSet_CyberSpace || 7245 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_Cyberspace)) 7246 { 7247 //Do top center label 7248 x = 0;//centered 7249 y = 9;//on top of symbol 7250 if(modifiers.containsKey(Modifiers.B_ECHELON)) 7251 { 7252 temp = modifiers.get(Modifiers.B_ECHELON); 7253 if(temp != null && !temp.isEmpty()) 7254 mods.add(new Modifier("B", temp, x, y, centered)); 7255 } 7256 7257 //Do right side labels 7258 x = 1;//on right 7259 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7260 { 7261 y = 0;//center 7262 centered = true;//vertically centered, only matters for labels on left and right side 7263 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7264 7265 if(temp != null && !temp.isEmpty()) 7266 mods.add(new Modifier("H", temp, x, y, centered)); 7267 } 7268 else if(!strict) 7269 { 7270 centered = false; 7271 } 7272 7273 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7274 { 7275 y = 1;//above center 7276 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 7277 7278 if(temp != null && !temp.isEmpty()) 7279 mods.add(new Modifier("G", temp, x, y, centered)); 7280 } 7281 7282 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 7283 { 7284 y = 2; 7285 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))) 7286 y--; 7287 temp = ""; 7288 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 7289 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 7290 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7291 temp += modifiers.get(Modifiers.AS_COUNTRY); 7292 temp = temp.trim(); 7293 if(temp != null && !temp.isEmpty()) 7294 mods.add(new Modifier("F AS", temp, x, y, centered)); 7295 } 7296 7297 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7298 { 7299 y = -1;//below center 7300 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 7301 if(temp != null && !temp.isEmpty()) 7302 mods.add(new Modifier("M", temp, x, y, centered)); 7303 } 7304 7305 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 7306 { 7307 y = -2; 7308 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7309 y++; 7310 temp = ""; 7311 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7312 temp = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 7313 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 7314 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 7315 temp = temp.trim(); 7316 if(temp != null && !temp.isEmpty()) 7317 mods.add(new Modifier("K L", temp, x, y, centered)); 7318 } 7319 7320 //Do left side labels 7321 x=-1; 7322 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7323 { 7324 y = 0;//center 7325 centered = true;//vertically centered, only matters for labels on left and right side 7326 7327 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 7328 7329 if(temp != null && !temp.isEmpty()) 7330 mods.add(new Modifier("V", temp, x, y, centered)); 7331 } 7332 else if(!strict) 7333 { 7334 centered = false; 7335 } 7336 7337 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7338 { 7339 y = 1; 7340 temp = modifiers.get(Modifiers.Y_LOCATION); 7341 7342 if(temp != null && !temp.isEmpty()) 7343 mods.add(new Modifier("Y", temp, x, y, centered)); 7344 } 7345 7346 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7347 { 7348 y = 2;//above center 7349 if(!strict && !(modifiers.containsKey(Modifiers.Y_LOCATION))) 7350 y--; 7351 7352 temp = modifiers.get(Modifiers.W_DTG_1); 7353 7354 if(temp != null && !temp.isEmpty()) 7355 mods.add(new Modifier("W", temp, x, y, centered)); 7356 } 7357 7358 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7359 { 7360 y = -1;//below center 7361 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7362 7363 if(temp != null && !temp.isEmpty()) 7364 mods.add(new Modifier("T", temp, x, y, centered)); 7365 } 7366 } 7367 /*else if(ver == SymbolID.SymbolSet_MineWarfare) 7368 { 7369 //no modifiers 7370 }//*/ 7371 //else//SymbolSet Unknown 7372 //processUnknownTextModifiers 7373 } 7374 7375 return mods; 7376 } 7377 7378 7379 /** 7380 * @param bounds bounds of the core icon 7381 * @param labelWidth height of the label to be placed 7382 * @param location -1 left, 0 center, 1 right 7383 * @returns 7384 */ 7385 private static double getLabelXPosition(Rect bounds, int labelWidth, int location, float modifierFontHeight) 7386 { 7387 int buffer = (int)modifierFontHeight/2; 7388 7389 double x = 0; 7390 if(location == 1)//on right 7391 { 7392 x = bounds.left + bounds.width() + buffer; 7393 } 7394 else if(location == -1)//left 7395 { 7396 x = bounds.left - labelWidth - buffer; 7397 } 7398 else if(location == 0) 7399 { 7400 x = Math.round((bounds.left + (bounds.width() * 0.5f)) - (labelWidth * 0.5f)); 7401 } 7402 return x; 7403 } 7404 7405 /** 7406 * 7407 * @param bounds bounds of the core icon 7408 * @param labelHeight height of the label to be placed 7409 * @param descent descent of the label to be placed 7410 * @param bufferText spacing buffer if desired 7411 * @param centered if true, there will be a center label location identified by 0 7412 * @param location positive 1, 2, 3 to be above symbol mid-point or negative values to be below 7413 * @returns y position 7414 */ 7415 private static double getLabelYPosition(Rect bounds, int labelHeight, int descent, int bufferText, boolean centered, int location) { 7416 double y = 0; 7417 if (bounds != null && !bounds.isEmpty()) 7418 { 7419 if(centered) 7420 { 7421 switch (location) 7422 { 7423 case 3://3 above center 7424 y = (bounds.height()); 7425 y = ((y * 0.5) + (labelHeight * 0.5)); 7426 y = y - ((labelHeight + bufferText) * 3); 7427 y = bounds.top + y; 7428 break; 7429 case 2://2 above center 7430 y = (bounds.height()); 7431 y = ((y * 0.5) + (labelHeight * 0.5)); 7432 y = y - ((labelHeight + bufferText) * 2); 7433 y = bounds.top + y; 7434 break; 7435 case 1://1 above center 7436 y = (bounds.height()); 7437 y = ((y * 0.5) + (labelHeight * 0.5)); 7438 y = y - ((labelHeight + bufferText)); 7439 y = bounds.top + y; 7440 break; 7441 case 0: //centered 7442 y = (bounds.height()); 7443 y = ((y * 0.5) + ((labelHeight - descent) * 0.5)); 7444 y = bounds.top + y; 7445 break; 7446 case -1://1 below center 7447 y = (bounds.height()); 7448 y = ((y * 0.5) + (labelHeight * 0.5)); 7449 y = y + ((labelHeight + bufferText - descent)); 7450 y = bounds.top + y; 7451 break; 7452 case -2://2 below center 7453 y = (bounds.height()); 7454 y = ((y * 0.5) + (labelHeight * 0.5)); 7455 y = y + ((labelHeight + bufferText) * 2) - (descent); 7456 y = bounds.top + y; 7457 break; 7458 case -3://3 below center 7459 y = (bounds.height()); 7460 y = ((y * 0.5) + (labelHeight * 0.5)); 7461 y = y + ((labelHeight + bufferText) * 3) - (descent); 7462 y = bounds.top + y; 7463 break; 7464 } 7465 } 7466 else//split between top and bottom 7467 { 7468 switch (location) 7469 { 7470 case 3: 7471 y = (bounds.top + ((bounds.height() / 2) - descent - labelHeight*2 - bufferText)); 7472 break; 7473 case 2: 7474 y = (bounds.top + ((bounds.height() / 2) - descent - labelHeight - bufferText)); 7475 break; 7476 case 1: 7477 y = (bounds.top + ((bounds.height() / 2) - descent)); 7478 break; 7479 case -1: 7480 y = (bounds.top + (bounds.height() / 2) + (labelHeight - descent + bufferText)); 7481 break; 7482 case -2: 7483 y = (bounds.top + (bounds.height() / 2) + ((labelHeight*2 - descent + bufferText))); 7484 break; 7485 case -3: 7486 y = (bounds.top + (bounds.height() / 2) + ((labelHeight*3 - descent + bufferText))); 7487 break; 7488 } 7489 } 7490 if(location == 9)//on top of symbol 7491 { 7492 y = Math.round(bounds.top - bufferText - descent); 7493 } 7494 } 7495 return y; 7496 } 7497 7498 /** 7499 * Currently, modifiers are based on Symbol Set. 7500 * The exception is SIGINT which required a frame shape value in 2525E+ 7501 * The SSMC couldn't come to an agreement on if frame shape should dictate modifiers. 7502 * Currently, I'm keeping it tied to Symbol Set. 7503 * @param symbolID 7504 * @return 7505 */ 7506 private static boolean isCOnTop(String symbolID) 7507 { 7508 boolean onTop = false; 7509 7510 int version = SymbolID.getVersion(symbolID); 7511 int ss = SymbolID.getSymbolSet(symbolID); 7512 char frame = SymbolID.getFrameShape(symbolID); 7513 7514 if(SymbolUtilities.hasModifier(symbolID,Modifiers.C_QUANTITY)) { 7515 7516 if(version >= SymbolID.Version_2525E) 7517 { 7518 7519 if (ss == SymbolID.SymbolSet_Air || 7520 ss == SymbolID.SymbolSet_AirMissile || 7521 ss == SymbolID.SymbolSet_Space || 7522 ss == SymbolID.SymbolSet_SpaceMissile || 7523 ss == SymbolID.SymbolSet_LandEquipment) 7524 { 7525 onTop = true; 7526 } 7527 else if(ss == SymbolID.SymbolSet_SignalsIntelligence && 7528 (frame == SymbolID.FrameShape_Air || 7529 frame == SymbolID.FrameShape_Space || 7530 frame == SymbolID.FrameShape_LandEquipment || frame == SymbolID.FrameShape_LandUnit || frame == '0')) 7531 { 7532 onTop = true; 7533 } 7534 7535 }// else if <= SymbolID.Version_2525Dch1 7536 else if (ss == SymbolID.SymbolSet_LandEquipment || 7537 ss == SymbolID.SymbolSet_SignalsIntelligence_Land) 7538 { 7539 onTop = true; 7540 } 7541 } 7542 return onTop; 7543 } 7544 public static boolean hasDisplayModifiers(String symbolID, Map<String,String> modifiers) 7545 { 7546 boolean hasModifiers = false; 7547 int ss = SymbolID.getSymbolSet(symbolID); 7548 int status = SymbolID.getStatus(symbolID); 7549 int context = SymbolID.getContext(symbolID); 7550 7551 if(ss == SymbolID.SymbolSet_ControlMeasure)//check control measure 7552 { 7553 if (SymbolUtilities.isCBRNEvent(symbolID) == true && modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT)) 7554 { 7555 hasModifiers = true; 7556 } 7557 else if(SymbolUtilities.hasFDI(symbolID)) 7558 hasModifiers = true; 7559 } 7560 else if(ss != SymbolID.SymbolSet_Atmospheric && 7561 ss != SymbolID.SymbolSet_Oceanographic && 7562 ss != SymbolID.SymbolSet_MeteorologicalSpace) 7563 {//checking units 7564 7565 if(context > 0) //Exercise or Simulation 7566 hasModifiers = true; 7567 7568 //echelon or mobility, 7569 if (SymbolID.getAmplifierDescriptor(symbolID) > 0 || modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT)) 7570 hasModifiers = true; 7571 7572 if(modifiers.containsKey(Modifiers.AJ_SPEED_LEADER)) 7573 hasModifiers = true; 7574 7575 if(modifiers.containsKey(Modifiers.AO_ENGAGEMENT_BAR)) 7576 hasModifiers = true; 7577 7578 //HQ/Taskforce 7579 if(SymbolID.getHQTFD(symbolID) > 0) 7580 hasModifiers = true; 7581 7582 if(status > 1)//Fully capable, damaged, destroyed 7583 hasModifiers = true; 7584 }//no display modifiers for single point weather 7585 7586 7587 7588 return hasModifiers; 7589 } 7590 7591 public static boolean hasTextModifiers(String symbolID, Map<String,String> modifiers) 7592 { 7593 7594 int ss = SymbolID.getSymbolSet(symbolID); 7595 int ec = SymbolID.getEntityCode(symbolID); 7596 if(ss == SymbolID.SymbolSet_Atmospheric) 7597 { 7598 switch(ec) 7599 { 7600 case 110102: //tropopause low 7601 case 110202: //tropopause high 7602 case 162200: //tropopause level ? 7603 case 162300: //freezing level ? 7604 return true; 7605 default: 7606 return false; 7607 } 7608 } 7609 else if(ss == SymbolID.SymbolSet_Oceanographic || ss == SymbolID.SymbolSet_MeteorologicalSpace) 7610 { 7611 return false; 7612 } 7613 else if (ss == SymbolID.SymbolSet_ControlMeasure) 7614 { 7615 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 7616 7617 if( msi.getModifiers().size() > 0 && modifiers != null && modifiers.size() > 0) 7618 return true; 7619 else 7620 return false; 7621 } 7622 else 7623 { 7624 7625 if (SymbolUtilities.getStandardIdentityModifier(symbolID) != null) 7626 { 7627 return true; 7628 } 7629 7630 int cc = SymbolID.getCountryCode(symbolID); 7631 if (cc > 0 && !GENCLookup.getInstance().get3CharCode(cc).isEmpty()) 7632 { 7633 return true; 7634 }//*/ 7635 7636 else if (modifiers.size() > 0) 7637 { 7638 return true; 7639 } 7640 } 7641 return false; 7642 } 7643 7644 /** 7645 * Rerturns either the default font from RendererSettings or font based on properties 7646 * set in MilStdAttributes. 7647 * @param attributes 7648 * @return 7649 */ 7650 private static Paint getFont(Map<String,String> attributes) 7651 { 7652 Paint p = null; 7653 Typeface tf = null; 7654 7655 p = RendererSettings.getInstance().getModiferFont(); 7656 7657 String[] props = RendererSettings.getInstance().getModiferFontProps(); 7658 7659 String ff = props[0]; 7660 int fstyle = Integer.parseInt(props[1]);// modifierFont.getTypeface().getStyle(); 7661 float fsize = Float.parseFloat(props[2]);// modifierFont.getTextSize(); 7662 String temp = null; 7663 7664 7665 if(attributes.containsKey(MilStdAttributes.FontFamily) || 7666 attributes.containsKey(MilStdAttributes.FontStyle) || 7667 attributes.containsKey(MilStdAttributes.FontSize)) 7668 { 7669 if(attributes.containsKey(MilStdAttributes.FontStyle)) 7670 { 7671 temp = attributes.get(MilStdAttributes.FontStyle); 7672 if (temp != null && !temp.isEmpty()) { 7673 fstyle = Integer.parseInt(temp); 7674 } 7675 } 7676 if(attributes.containsKey(MilStdAttributes.FontSize)) 7677 { 7678 temp = attributes.get(MilStdAttributes.FontSize); 7679 if (temp != null && !temp.isEmpty()) { 7680 fsize = Float.parseFloat(temp); 7681 } 7682 } 7683 if(attributes.containsKey(MilStdAttributes.FontFamily)) 7684 { 7685 temp = attributes.get(MilStdAttributes.FontFamily); 7686 if (temp != null && !temp.isEmpty()) { 7687 ff = temp;//Typeface.create(temp,fstyle); 7688 } 7689 } 7690 tf = Typeface.create(ff,fstyle); 7691 if(tf == null) 7692 tf = Typeface.create(props[0],fstyle); 7693 if(tf == null) 7694 return null; 7695 7696 p = new Paint(); 7697 p.setTextSize(fsize); 7698 p.setAntiAlias(true); 7699 p.setTypeface(tf); 7700 p.setStrokeCap(Cap.BUTT); 7701 p.setStrokeJoin(Join.MITER); 7702 p.setStrokeMiter(3f); 7703 7704 return p; 7705 } 7706 else 7707 return _modifierFont; 7708 7709 } 7710 7711 private static float[] getFontHeightandDescent(Paint font) 7712 { 7713 float[] hd = {0f,0f}; 7714 7715 if(font != null) { 7716 Paint.FontMetrics fm = font.getFontMetrics(); 7717 //_modifierFontHeight = fm.top + fm.bottom; 7718 hd[0] = fm.bottom - fm.top; 7719 hd[1] = fm.descent; 7720 } 7721 return hd; 7722 } 7723 7724}