001package armyc2.c5isr.renderer; 002 003import java.util.ArrayList; 004import java.util.Iterator; 005import java.util.List; 006import java.util.Locale; 007import java.util.Map; 008 009import android.graphics.Bitmap; 010import android.graphics.Canvas; 011import android.graphics.DashPathEffect; 012import android.graphics.Paint; 013import android.graphics.Path; 014import android.graphics.Point; 015import android.graphics.PointF; 016import android.graphics.Rect; 017import android.graphics.RectF; 018import android.graphics.Bitmap.Config; 019import android.graphics.Paint.Cap; 020import android.graphics.Paint.Join; 021import android.graphics.Paint.Style; 022import android.graphics.Path.Direction; 023import android.graphics.Typeface; 024 025import armyc2.c5isr.renderer.utilities.Color; 026import armyc2.c5isr.renderer.utilities.ErrorLogger; 027import armyc2.c5isr.renderer.utilities.GENCLookup; 028import armyc2.c5isr.renderer.utilities.ImageInfo; 029import armyc2.c5isr.renderer.utilities.MSInfo; 030import armyc2.c5isr.renderer.utilities.MSLookup; 031import armyc2.c5isr.renderer.utilities.MilStdAttributes; 032import armyc2.c5isr.renderer.utilities.Modifier; 033import armyc2.c5isr.renderer.utilities.Modifiers; 034import armyc2.c5isr.renderer.utilities.PathUtilities; 035import armyc2.c5isr.renderer.utilities.RectUtilities; 036import armyc2.c5isr.renderer.utilities.RendererSettings; 037import armyc2.c5isr.renderer.utilities.RendererUtilities; 038import armyc2.c5isr.renderer.utilities.SVGInfo; 039import armyc2.c5isr.renderer.utilities.SVGLookup; 040import armyc2.c5isr.renderer.utilities.SVGPath; 041import armyc2.c5isr.renderer.utilities.SVGSymbolInfo; 042import armyc2.c5isr.renderer.utilities.Shape2SVG; 043import armyc2.c5isr.renderer.utilities.SymbolDimensionInfo; 044import armyc2.c5isr.renderer.utilities.SymbolID; 045import armyc2.c5isr.renderer.utilities.SymbolUtilities; 046import armyc2.c5isr.renderer.utilities.TextInfo; 047 048/** 049 * This class is used for rendering the labels/amplifiers/modifiers around the single point symbol. 050 */ 051public class ModifierRenderer 052{ 053 054 private static Paint _modifierFont = null; 055 private static float _modifierFontHeight = 10f; 056 private static float _modifierFontDescent = 2f; 057 private static RendererSettings RS = RendererSettings.getInstance(); 058 059 private static final Object modifierFontMutex = new Object(); 060 public static void setModifierFont(Paint font, float height, float descent) 061 { 062 synchronized (modifierFontMutex) { 063 _modifierFont = font; 064 _modifierFontHeight = height; 065 _modifierFontDescent = descent; 066 } 067 } 068 069 public static SymbolDimensionInfo processUnitDisplayModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Boolean hasTextModifiers, Map<String,String> attributes) 070 { 071 072 ImageInfo ii = null; 073 ImageInfo newii = null; 074 SVGSymbolInfo ssi = null; 075 SymbolDimensionInfo newsdi = null; 076 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 077 Rect imageBounds = new Rect(sdi.getImageBounds()); 078 Point centerPoint = new Point(sdi.getCenterPoint()); 079 Point symbolCenter = new Point(symbolBounds.centerX(), symbolBounds.centerY()); 080 TextInfo tiEchelon = null; 081 TextInfo tiAM = null; 082 Rect echelonBounds = null; 083 Rect amBounds = null; 084 Color textColor = Color.BLACK; 085 Color textBackgroundColor = null; 086 float strokeWidth = 3.0f; 087 float strokeWidthNL = 3.0f; 088 Color lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID); 089 Color fillColor = SymbolUtilities.getFillColorOfAffiliation(symbolID); 090 int buffer = 0; 091 int alpha = 255; 092 //ctx = null; 093 int offsetX = 0; 094 int offsetY = 0; 095 int pixelSize = RendererSettings.getInstance().getDefaultPixelSize(); 096 SVGPath svgMobilityPath = null; 097 String svgMobilityGroup = null; 098 099 Paint modifierFont = getFont(attributes); 100 float[] hd = getFontHeightandDescent(modifierFont); 101 float modifierFontHeight = hd[0]; 102 float modifierFontDescent = hd[1]; 103 104 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 105 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 106 { 107 String temp = attributes.get(MilStdAttributes.FontFamily); 108 if(temp != null && !temp.isEmpty()) 109 modifierFontName = temp; 110 } 111 112 int ss = SymbolID.getSymbolSet(symbolID); 113 114 if (attributes.containsKey(MilStdAttributes.Alpha)) 115 { 116 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 117 textColor.setAlpha(alpha); 118 } 119 if (attributes.containsKey(MilStdAttributes.TextColor)) 120 { 121 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 122 if(alpha > -1) 123 textColor.setAlpha(alpha); 124 } 125 if (attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 126 { 127 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 128 if(alpha > -1) 129 textBackgroundColor.setAlpha(alpha); 130 } 131 if (attributes.containsKey(MilStdAttributes.LineColor)) 132 { 133 lineColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.LineColor)); 134 } 135 if (attributes.containsKey(MilStdAttributes.FillColor)) 136 { 137 fillColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.FillColor)); 138 } 139 if(attributes.containsKey(MilStdAttributes.PixelSize)) 140 { 141 pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize)); 142 } 143 144 //float fontsize = RendererSettings.getInstance().getModiferFont().getTextSize(); 145 146 // <editor-fold defaultstate="collapsed" desc="Build Mobility Modifiers"> 147 float strokeWidthBasedOnDPI = 1;//min//Math.max(RendererSettings.getInstance().getDeviceDPI()/210,1);//min DPI 148 strokeWidthBasedOnDPI = Math.max(pixelSize / 25f,strokeWidthBasedOnDPI);//dpi base on symbol size 149 strokeWidthBasedOnDPI = Math.min(strokeWidthBasedOnDPI,RendererSettings.getInstance().getDeviceDPI()/32f);//max dpi 150 151 RectF mobilityBounds = null; 152 int ad = SymbolID.getAmplifierDescriptor(symbolID);//echelon/mobility 153 List<Path> shapes = new ArrayList<Path>(); 154 Path mobilityPath = null; 155 Path mobilityPathFill = null; 156 if (ad >= SymbolID.Mobility_WheeledLimitedCrossCountry && 157 (SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.R_MOBILITY_INDICATOR) || 158 SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AG_AUX_EQUIP_INDICATOR))) 159 { 160 161 //Draw Mobility 162 int fifth = (int) ((symbolBounds.width() * 0.2) + 0.5f); 163 mobilityPath = new Path(); 164 svgMobilityPath = null; 165 svgMobilityGroup = null; 166 167 int x = 0; 168 int y = 0; 169 int centerX = 0; 170 int bottomY = 0; 171 int height = 0; 172 int width = 0; 173 int middleY = 0; 174 int wheelOffset = 2; 175 int wheelSize = fifth;//10; 176 int rrHeight = fifth;//10; 177 int rrArcWidth = (int) ((fifth * 1.5) + 0.5f);//16; 178 float rad = wheelSize/2; 179 180 181 x = (int) symbolBounds.left + 1; 182 y = (int) symbolBounds.top; 183 height = Math.round(symbolBounds.height()); 184 width = Math.round(symbolBounds.width()) - 3; 185 bottomY = y + height + 2; 186 187 188 189 if (ad >= SymbolID.Mobility_WheeledLimitedCrossCountry && //31, mobility starts above 30 190 SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.R_MOBILITY_INDICATOR)) 191 { 192 bottomY = y + height + 2; 193 194 //wheelSize = width / 7; 195 //rrHeight = width / 7; 196 //rrArcWidth = width / 7; 197 if (ad == SymbolID.Mobility_WheeledLimitedCrossCountry) 198 { 199 //line 200 PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY); 201 202 //left circle 203 PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 204 205 //right circle 206 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 207 208 //SVG 209 svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n"; 210 svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" ></circle>\n"; 211 svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" ></circle>\n"; 212 } 213 else if (ad == SymbolID.Mobility_WheeledCrossCountry) 214 { 215 //line 216 PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY); 217 218 //left circle 219 PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 220 221 //right circle 222 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 223 224 //center wheel 225 PathUtilities.addEllipse(mobilityPath, x + (width / 2) - (wheelSize / 2), bottomY + wheelOffset, wheelSize, wheelSize); 226 227 //SVG 228 svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n"; 229 svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n"; 230 svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n"; 231 svgMobilityGroup += "<circle cx=\"" + (x + (width/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n"; 232 } 233 else if (ad == SymbolID.Mobility_Tracked) 234 { 235 //round rectangle 236 PathUtilities.addRoundedRect(mobilityPath, x, bottomY, width, rrHeight, rrHeight/2, rrHeight); 237 svgMobilityGroup = "<rect width=\"" + width + "\" height=\"" + rrHeight + "\" x=\"" + x + "\" y=\"" + bottomY + "\" rx=\"" + rrHeight/2 + "\" ry=\"" + rrHeight + "\" />\n"; 238 239 } 240 else if (ad == SymbolID.Mobility_Wheeled_Tracked) 241 { 242 //round rectangle 243 PathUtilities.addRoundedRect(mobilityPath, x, bottomY, width, rrHeight, wheelSize/2, rrHeight); 244 svgMobilityGroup = "<rect width=\"" + width + "\" height=\"" + rrHeight + "\" x=\"" + x + "\" y=\"" + bottomY + "\" rx=\"" + rrHeight/2 + "\" ry=\"" + rrHeight + "\" />\n"; 245 246 //left circle 247 PathUtilities.addEllipse(mobilityPath, x - wheelSize - wheelSize, bottomY, wheelSize, wheelSize); 248 svgMobilityGroup += "<circle cx=\"" + (x - wheelSize - wheelSize/2) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n"; 249 } 250 else if (ad == SymbolID.Mobility_Towed) 251 { 252 //line 253 PathUtilities.addLine(mobilityPath, x + wheelSize, bottomY + (wheelSize / 2), 254 x + width - wheelSize, bottomY + (wheelSize / 2)); 255 256 //left circle 257 PathUtilities.addEllipse(mobilityPath, x, bottomY, wheelSize, wheelSize); 258 259 //right circle 260 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY, wheelSize, wheelSize); 261 262 //SVG 263 svgMobilityGroup = "<line x1=\"" + (x + wheelSize) + "\" y1=\"" + (bottomY + (wheelSize/2) + "\" x2=\"" + (x + width - wheelSize) + "\" y2=\"" + (bottomY + (wheelSize/2))) + "\" />\n"; 264 svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" fill=\"none\" stroke=\"black\" ></circle>\n"; 265 svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" fill=\"none\" stroke=\"black\" ></circle>\n"; 266 } 267 else if (ad == SymbolID.Mobility_Rail) 268 { 269 //line 270 PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY); 271 272 //left circle 273 PathUtilities.addEllipse(mobilityPath, x + wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 274 275 //left circle2 276 PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 277 278 //right circle 279 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 280 281 //right circle2 282 PathUtilities.addEllipse(mobilityPath, x + width - wheelSize - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 283 284 //SVG 285 svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n"; 286 287 svgMobilityGroup += "<circle cx=\"" + (x + rad) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n"; 288 svgMobilityGroup += "<circle cx=\"" + (x + rad + wheelSize) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n"; 289 290 svgMobilityGroup += "<circle cx=\"" + (x + width - rad) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n"; 291 svgMobilityGroup += "<circle cx=\"" + (x + width - rad - wheelSize) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n"; 292 293 } 294 else if (ad == SymbolID.Mobility_OverSnow) 295 { 296 float halfWidth = (rrArcWidth * 0.5f); 297 mobilityPath.moveTo(x, bottomY); 298 mobilityPath.lineTo(x + halfWidth, bottomY + halfWidth); 299 mobilityPath.lineTo(x + width, bottomY + halfWidth); 300 301 //SVG 302 svgMobilityPath = new SVGPath(); 303 svgMobilityPath.moveTo(x,bottomY); 304 svgMobilityPath.lineTo(x + halfWidth, bottomY + halfWidth); 305 svgMobilityPath.lineTo(x + width, bottomY + halfWidth); 306 307 } 308 else if (ad == SymbolID.Mobility_Sled) 309 { 310 mobilityPath.moveTo(x, bottomY); 311 312 mobilityPath.cubicTo(x, bottomY, x - rrHeight, bottomY + rrHeight/2, x, bottomY + rrHeight); 313 //mobilityPath.bezierCurveTo(x, bottomY, x-rrArcWidth, bottomY+3, x, bottomY+rrHeight); 314 315 mobilityPath.lineTo(x + width, bottomY + rrHeight); 316 317 mobilityPath.cubicTo(x + width, bottomY + rrHeight, x + width + rrHeight, bottomY + rrHeight/2, x + width, bottomY); 318 //shapeMobility.curveTo(x + width, bottomY + rrHeight, x+ width + rrArcWidth, bottomY+3, x + width, bottomY); 319 320 //SVG 321 svgMobilityPath = new SVGPath(); 322 svgMobilityPath.moveTo(x, bottomY); 323 svgMobilityPath.bezierCurveTo(x, bottomY, x - rrHeight, bottomY + rrHeight/2, x, bottomY + rrHeight); 324 svgMobilityPath.lineTo(x + width, bottomY + rrHeight); 325 svgMobilityPath.bezierCurveTo(x + width, bottomY + rrHeight, x + width + rrHeight, bottomY + rrHeight/2, x + width, bottomY); 326 327 } 328 else if (ad == SymbolID.Mobility_PackAnimals) 329 { 330 centerX = Math.round(RectUtilities.getCenterX(symbolBounds)); 331 int angleWidth = rrHeight / 2; 332 mobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 333 mobilityPath.lineTo(centerX - angleWidth, bottomY); 334 mobilityPath.lineTo(centerX - angleWidth*2, bottomY + rrHeight + 2); 335 336 mobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 337 mobilityPath.lineTo(centerX + angleWidth, bottomY); 338 mobilityPath.lineTo(centerX + angleWidth*2, bottomY + rrHeight + 2); 339 340 //SVG 341 svgMobilityPath = new SVGPath(); 342 svgMobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 343 svgMobilityPath.lineTo(centerX - angleWidth, bottomY); 344 svgMobilityPath.lineTo(centerX - angleWidth*2, bottomY + rrHeight + 2); 345 346 svgMobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 347 svgMobilityPath.lineTo(centerX + angleWidth, bottomY); 348 svgMobilityPath.lineTo(centerX + angleWidth*2, bottomY + rrHeight + 2); 349 } 350 else if (ad == SymbolID.Mobility_Barge) 351 { 352 centerX = Math.round(RectUtilities.getCenterX(symbolBounds)); 353 PathUtilities.addLine(mobilityPath, x + width, bottomY, x, bottomY); 354 //var line = new SO.Line(x + width, bottomY,x, bottomY); 355 356 float quarterX = (centerX - x) / 2; 357 //var quarterY = (((bottomY + rrHeight) - bottomY)/2); 358 359 mobilityPath.moveTo(x, bottomY); 360 mobilityPath.cubicTo(x + quarterX, bottomY + rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY); 361 //shapes.push(new SO.BCurve(x, bottomY,x+quarterX, bottomY+rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY)); 362 363 //SVG 364 svgMobilityPath = new SVGPath(); 365 svgMobilityPath.moveTo(x + width, bottomY); 366 svgMobilityPath.lineTo(x, bottomY); 367 svgMobilityPath.moveTo(x, bottomY); 368 svgMobilityPath.bezierCurveTo(x + quarterX, bottomY + rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY); 369 } 370 371 else if (ad == SymbolID.Mobility_Amphibious) 372 { 373 float incrementX = width / 7; 374 middleY = (bottomY + (rrHeight / 2)); 375 376 x = Math.round(x + (incrementX / 2)); 377 float r = Math.round(incrementX / 2); 378 379 //mobilityPath.arcTo(oval, sAngle, sAngle, moveTo); 380 PathUtilities.arc(mobilityPath, x, middleY, r, 180, 180); 381 PathUtilities.arc(mobilityPath, x + incrementX, middleY, r, 180, -180, false); 382 PathUtilities.arc(mobilityPath, x + incrementX * 2, middleY, r, 180, 180, false); 383 PathUtilities.arc(mobilityPath, x + incrementX * 3, middleY, r, 180, -180, false); 384 PathUtilities.arc(mobilityPath, x + incrementX * 4, middleY, r, 180, 180, false); 385 PathUtilities.arc(mobilityPath, x + incrementX * 5, middleY, r, 180, -180, false); 386 PathUtilities.arc(mobilityPath, x + incrementX * 6, middleY, r, 180, 180, false); 387 388 //SVG 389 x = symbolBounds.left + 1; 390 svgMobilityGroup = "<path d=\"M" + x + " " + middleY + " "; 391 svgMobilityGroup += "C " + x + " " + bottomY + " " + (x + incrementX) + " " + bottomY + " " + (x + incrementX) + " " + middleY + " "; 392 svgMobilityGroup += "C " + (x + incrementX) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 2)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*2)) + " " + middleY + " "; 393 svgMobilityGroup += "C " + (x + (incrementX*2)) + " " + bottomY + " " + (x + (incrementX*3)) + " " + bottomY + " " + (x + incrementX*3) + " " + middleY + " "; 394 svgMobilityGroup += "C " + (x + (incrementX*3)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 4)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*4)) + " " + middleY + " "; 395 svgMobilityGroup += "C " + (x + (incrementX*4)) + " " + bottomY + " " + (x + (incrementX*5)) + " " + bottomY + " " + (x + incrementX*5) + " " + middleY + " "; 396 svgMobilityGroup += "C " + (x + (incrementX*5)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 6)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*6)) + " " + middleY + " "; 397 svgMobilityGroup += "C " + (x + (incrementX*6)) + " " + bottomY + " " + (x + (incrementX*7)) + " " + bottomY + " " + (x + incrementX*7) + " " + middleY + " "; 398 svgMobilityGroup += "\"/>"; 399 400 401 } 402 403 if(svgMobilityGroup != null) 404 svgMobilityGroup = "<g stroke-width=\"" + strokeWidthBasedOnDPI + "\" fill=\"none\"" + " stroke=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" + ">\n" + svgMobilityGroup + "</g>\n"; 405 406 } 407 //Draw Towed Array Sonar 408 if ((ad == SymbolID.Mobility_ShortTowedArray || ad == SymbolID.Mobility_LongTowedArray) && 409 SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AG_AUX_EQUIP_INDICATOR)) { 410 int boxHeight = (int) ((rrHeight * 0.8f) + 0.5f); 411 bottomY = y + height + (boxHeight / 7); 412 mobilityPathFill = new Path(); 413 offsetY = boxHeight / 7;//1; 414 centerX = Math.round(symbolBounds.left + (symbolBounds.right - symbolBounds.left) / 2); 415 int squareOffset = Math.round(boxHeight * 0.5f); 416 middleY = ((boxHeight / 2) + bottomY) + offsetY;//+1 for offset from symbol 417 if (ad == SymbolID.Mobility_ShortTowedArray) { 418 //subtract 0.5 because lines 1 pixel thick get aliased into 419 //a line two pixels wide. 420 //line 421 PathUtilities.addLine(mobilityPath, centerX - 1, bottomY - 1, centerX - 1, bottomY + offsetY + boxHeight + offsetY); 422 //shapes.push(new SO.Line(centerX-1,bottomY-1,centerX-1, bottomY + rrHeight + 3)); 423 //shapeLines.append(new Line2D.Double(centerX,bottomY - 2,centerX, bottomY + rrHeight + 1), false); 424 //line 425 PathUtilities.addLine(mobilityPath, x, middleY, x + width, middleY); 426 //shapes.push(new SO.Line(x,middleY,x + width, middleY)); 427 //shapeLines.append(new Line2D.Double(x,middleY,x + width, middleY), false); 428 //square 429 mobilityPathFill.addRect(PathUtilities.makeRectF(x - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 430 //shapes.push(new SO.Rectangle(x-squareOffset, bottomY+offsetY, 5, 5)); 431 //shapeSquares.append(new Rectangle2D.Double(x-squareOffset, bottomY, 5, 5), false); 432 //square 433 mobilityPathFill.addRect(PathUtilities.makeRectF(Math.round(centerX - squareOffset), bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 434 //shapes.push(new SO.Rectangle(Math.round(centerX-squareOffset), bottomY+offsetY, 5, 5)); 435 //shapeSquares.append(new Rectangle2D.Double(centerX-squareOffset, bottomY, 5, 5), false); 436 //square 437 mobilityPathFill.addRect(PathUtilities.makeRectF(x + width - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 438 //shapes.push(new SO.Rectangle(x + width - squareOffset, bottomY+offsetY, 5, 5)); 439 //shapeSquares.append(new Rectangle2D.Double(x + width - squareOffset, bottomY, 5, 5), false); 440 441 //SVG 442 String svgColor = RendererUtilities.colorToHexString(lineColor,false); 443 svgMobilityGroup = "<line x1=\"" + (centerX - 1) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (centerX - 1) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 444 svgMobilityGroup += "<line x1=\"" + (x) + "\" y1=\"" + (middleY) + "\" x2=\"" + (x + width) + "\" y2=\"" + (middleY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 445 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 446 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (centerX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 447 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x + width - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 448 449 450 } else if (ad == SymbolID.Mobility_LongTowedArray) { 451 int leftX = x + (centerX - x) / 2, 452 rightX = centerX + (x + width - centerX) / 2; 453 454 //line vertical left 455 PathUtilities.addLine(mobilityPath, leftX, bottomY - 1, leftX, bottomY + offsetY + boxHeight + offsetY); 456 //shapes.push(new SO.Line(leftX,bottomY - 1,leftX, bottomY + rrHeight + 3)); 457 //shapeLines.append(new Line2D.Double(leftX,bottomY - 2,leftX, bottomY + rrHeight + 1), false); 458 //line vertical right 459 PathUtilities.addLine(mobilityPath, rightX, bottomY - 1, rightX, bottomY + offsetY + boxHeight + offsetY); 460 //shapes.push(new SO.Line(rightX,bottomY - 1,rightX, bottomY + rrHeight + 3)); 461 //shapeLines.append(new Line2D.Double(rightX,bottomY - 2,rightX, bottomY + rrHeight + 1), false); 462 //line horizontal 463 PathUtilities.addLine(mobilityPath, x, middleY, x + width, middleY); 464 //shapes.push(new SO.Line(x,middleY,x + width, middleY)); 465 //shapeLines.append(new Line2D.Double(x,middleY,x + width, middleY), false); 466 //square left 467 mobilityPathFill.addRect(PathUtilities.makeRectF(x - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 468 //shapes.push(new SO.Rectangle(x-squareOffset, bottomY+offsetY, 5, 5)); 469 //shapeSquares.append(new Rectangle2D.Double(x-squareOffset, bottomY, 5, 5), false); 470 //square middle 471 mobilityPathFill.addRect(PathUtilities.makeRectF(centerX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 472 //shapes.push(new SO.Rectangle(centerX-squareOffset, bottomY+offsetY, 5, 5)); 473 //shapeSquares.append(new Rectangle2D.Double(centerX-squareOffset, bottomY, 5, 5), false); 474 //square right 475 mobilityPathFill.addRect(PathUtilities.makeRectF(x + width - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 476 //shapes.push(new SO.Rectangle(x + width - squareOffset, bottomY+offsetY, 5, 5)); 477 //shapeSquares.append(new Rectangle2D.Double(x + width - squareOffset, bottomY, 5, 5), false); 478 //square middle left 479 mobilityPathFill.addRect(PathUtilities.makeRectF(leftX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 480 //shapes.push(new SO.Rectangle(leftX - squareOffset, bottomY+offsetY, 5, 5)); 481 //shapeSquares.append(new Rectangle2D.Double(leftX - squareOffset, bottomY, 5, 5), false); 482 //square middle right 483 mobilityPathFill.addRect(PathUtilities.makeRectF(rightX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 484 //shapes.push(new SO.Rectangle(rightX - squareOffset, bottomY+offsetY, 5, 5)); 485 //shapeSquares.append(new Rectangle2D.Double(rightX - squareOffset, bottomY, 5, 5), false); 486 487 //SVG 488 String svgColor = RendererUtilities.colorToHexString(lineColor,false); 489 svgMobilityGroup = "<line x1=\"" + (leftX) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (leftX) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 490 svgMobilityGroup += "<line x1=\"" + (rightX) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (rightX) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 491 svgMobilityGroup += "<line x1=\"" + (x) + "\" y1=\"" + (middleY) + "\" x2=\"" + (x + width) + "\" y2=\"" + (middleY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n"; 492 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 493 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (centerX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 494 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x + width - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 495 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (leftX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 496 svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (rightX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n"; 497 498 } 499 if(svgMobilityGroup != null) 500 svgMobilityGroup = "<g stroke-width=\"" + strokeWidthBasedOnDPI + "\" fill=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" + " stroke=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" + ">\n" + svgMobilityGroup + "\n</g>"; 501 } 502 503 //get mobility bounds 504 if (mobilityPath != null) 505 { 506 507 //build mobility bounds 508 mobilityBounds = new RectF(); 509 mobilityPath.computeBounds(mobilityBounds, true); 510 511 RectF mobilityFillBounds = new RectF(); 512 if (mobilityPathFill != null) 513 { 514 mobilityPathFill.computeBounds(mobilityFillBounds, true); 515 mobilityBounds.union(mobilityFillBounds); 516 } 517 518 //grow by one because we use a line thickness of 2. 519 RectUtilities.grow(mobilityBounds,Math.round(strokeWidthBasedOnDPI/2)); 520 //mobilityBounds.set(mobilityBounds.left - 1, mobilityBounds.top - 1, mobilityBounds.right + 1, mobilityBounds.bottom + 1); 521 imageBounds.union(RectUtilities.makeRectFromRectF(mobilityBounds)); 522 } 523 } 524 // </editor-fold> 525 526 // <editor-fold defaultstate="collapsed" desc="Leadership Indicator Modifier"> 527 RectF liBounds = null; 528 Path liPath = null; 529 PointF liTop = null; 530 PointF liLeft = null; 531 PointF liRight = null; 532 if(ad == SymbolID.Leadership_Individual && ss == SymbolID.SymbolSet_DismountedIndividuals && 533 (SymbolID.getFrameShape(symbolID)==SymbolID.FrameShape_DismountedIndividuals || 534 SymbolID.getFrameShape(symbolID)==SymbolID.FrameShape_Unknown)) 535 { 536 liPath = new Path(); 537 538 int si = SymbolID.getStandardIdentity(symbolID); 539 int af = SymbolID.getAffiliation(symbolID); 540 int c = SymbolID.getContext(symbolID); 541 //int fs = SymbolID.getFrameShape(symbolID); 542 double centerOffset = 0; 543 double sideOffset = 0; 544 double left = symbolBounds.left; 545 double right = symbolBounds.left + symbolBounds.width(); 546 547 if(af == SymbolID.StandardIdentity_Affiliation_Unknown || af == SymbolID.StandardIdentity_Affiliation_Pending) 548 { 549 centerOffset = (symbolBounds.height()*0.1012528735632184); 550 sideOffset = (right - left)*0.3583513488109785; 551 //left = symbolBounds.getCenterX() - ((symbolBounds.getWidth() / 2) * 0.66420458); 552 //right = symbolBounds.getCenterX() + ((symbolBounds.getWidth() / 2) * 0.66420458); 553 } 554 if(af == SymbolID.StandardIdentity_Affiliation_Neutral) 555 { 556 centerOffset = (symbolBounds.height()*0.25378787878787878); 557 sideOffset = (right - left)*0.2051402812352822; 558 } 559 if(SymbolUtilities.isReality(symbolID) || SymbolUtilities.isSimulation(symbolID)) 560 { 561 if(af==SymbolID.StandardIdentity_Affiliation_Friend || af==SymbolID.StandardIdentity_Affiliation_AssumedFriend) 562 {//hexagon friend/assumed friend 563 centerOffset = (symbolBounds.height()*0.08); 564 sideOffset = (right - left)*0.282714524168219;//(symbolBounds.getHeight()*0.29); 565 } 566 else if(af==SymbolID.StandardIdentity_Affiliation_Hostile_Faker || af==SymbolID.StandardIdentity_Affiliation_Suspect_Joker) 567 {//diamond hostile/suspect 568 569 left = symbolBounds.centerX() - ((symbolBounds.width() / 2) * 1.0653694149);//1.07);//1.0653694149); 570 right = symbolBounds.centerX() + ((symbolBounds.width() / 2) * 1.0653694149);//1.07);//1.0653694149); 571 572 centerOffset = (symbolBounds.height()*0.08);//0.0751139601139601 573 sideOffset = (right - left)*0.4923255424955992; 574 } 575 } 576 else//Exercise 577 { 578 //hexagon 579 if(af!=SymbolID.StandardIdentity_Affiliation_Unknown || 580 af==SymbolID.StandardIdentity_Affiliation_Neutral) 581 { 582 centerOffset = (symbolBounds.height()*0.08); 583 sideOffset = (right - left)*0.282714524168219; 584 } 585 } 586 587 //create leadership indicator /\ 588 liTop = new PointF(symbolBounds.centerX(), (float)(symbolBounds.top - centerOffset)); 589 liLeft = new PointF((float)left, (float)(liTop.y + sideOffset)); 590 liRight = new PointF((float)right, (float)(liTop.y + sideOffset)); 591 592 593 liPath.moveTo(liTop.x, liTop.y); 594 liPath.lineTo(liLeft.x, liLeft.y); 595 liPath.moveTo(liTop.x, liTop.y); 596 liPath.lineTo(liRight.x, liRight.y);//*/ 597 598 599 liBounds = new RectF(liLeft.x, liTop.y, liRight.x - liLeft.x, liLeft.y - liTop.y); 600 601 RectUtilities.grow(liBounds,2); 602 603 imageBounds.union(RectUtilities.makeRectFromRectF(liBounds)); 604 } 605 606 // </editor-fold> 607 608 // <editor-fold defaultstate="collapsed" desc="Build Echelon"> 609 //Draw Echelon 610 int intEchelon = SymbolID.getAmplifierDescriptor(symbolID); 611 String strEchelon = SymbolUtilities.getEchelonText(intEchelon); 612 613 if (strEchelon != null 614 && SymbolUtilities.hasModifier(symbolID, Modifiers.B_ECHELON)) 615 { 616 617 int echelonOffset = 2, 618 outlineOffset = RS.getTextOutlineWidth(); 619 620 tiEchelon = new TextInfo(strEchelon, 0, 0, modifierFont, modifierFontName); 621 echelonBounds = tiEchelon.getTextBounds(); 622 623 int y = Math.round(symbolBounds.left - echelonOffset); 624 int x = Math.round(symbolBounds.left + (symbolBounds.width() / 2) 625 - (echelonBounds.width() / 2)); 626 tiEchelon.setLocation(x, y); 627 628 //There will never be lowercase characters in an echelon so trim that fat. 629 //Remove the descent from the bounding box. 630 tiEchelon.getTextOutlineBounds();//.shiftBR(0,Math.round(-(echelonBounds.height()*0.3))); 631 632 //make echelon bounds a little more spacious for things like nearby labels and Task Force. 633 RectUtilities.grow(echelonBounds, outlineOffset); 634 //tiEchelon.getTextOutlineBounds(); 635// RectUtilities.shift(echelonBounds, x, -outlineOffset); 636 //echelonBounds.shift(0,-outlineOffset);// - Math.round(echelonOffset/2)); 637 tiEchelon.setLocation(x, y - outlineOffset); 638 639 imageBounds.union(echelonBounds); 640 641 } 642 // </editor-fold> 643 644 // <editor-fold defaultstate="collapsed" desc="Build Affiliation Modifier"> 645 //Draw Echelon 646 String affiliationModifier = null; 647 if (RS.getDrawAffiliationModifierAsLabel() == false) 648 { 649 affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID); 650 } 651 if (affiliationModifier != null) 652 { 653 654 int amOffset = 2; 655 int outlineOffset = RS.getTextOutlineWidth(); 656 657 tiAM = new TextInfo(affiliationModifier, 0, 0, modifierFont, modifierFontName); 658 amBounds = tiAM.getTextBounds(); 659 660 int x, y; 661 662 if (echelonBounds != null 663 && ((echelonBounds.left + echelonBounds.width() > symbolBounds.left + symbolBounds.width()))) 664 { 665 y = Math.round(symbolBounds.top - amOffset); 666 x = echelonBounds.left + echelonBounds.width(); 667 } 668 else 669 { 670 y = Math.round(symbolBounds.top - amOffset); 671 x = Math.round(symbolBounds.left + symbolBounds.width()); 672 } 673 tiAM.setLocation(x, y); 674 675 //adjust for outline. 676 RectUtilities.grow(amBounds, outlineOffset); 677 RectUtilities.shift(amBounds, 0, -outlineOffset); 678 tiAM.setLocation(x, y - outlineOffset); 679 680 imageBounds.union(amBounds); 681 } 682 // </editor-fold> 683 684 // <editor-fold defaultstate="collapsed" desc="Build Task Force"> 685 Rect tfBounds = null; 686 Rect tfRectangle = null; 687 if (SymbolUtilities.isTaskForce(symbolID) && SymbolUtilities.hasModifier(symbolID, Modifiers.D_TASK_FORCE_INDICATOR)) 688 { 689 690 int height = Math.round(symbolBounds.height() / 4.0f); 691 int width = Math.round(symbolBounds.width() / 3.0f); 692 693 if(!SymbolUtilities.hasRectangleFrame(symbolID)) 694 { 695 height = (int)Math.round(symbolBounds.height() / 6.0f); 696 } 697 698 tfRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 699 (int) symbolBounds.top - height, 700 width, 701 height); 702 703 tfBounds = RectUtilities.makeRect(tfRectangle.left + -1, 704 tfRectangle.top - 1, 705 tfRectangle.width() + 2, 706 tfRectangle.height() + 2); 707 708 if (echelonBounds != null) 709 { 710 /*tfRectangle = new Rect(echelonBounds.left, 711 echelonBounds.top,// + outlineOffset, 712 echelonBounds.right, 713 symbolBounds.top-1); 714 tfBounds = new Rect(tfRectangle);*/ 715 716 int tfx = tfRectangle.left; 717 int tfw = tfRectangle.width(); 718 int tfy = tfRectangle.top; 719 int tfh = tfRectangle.height(); 720 721 if(echelonBounds.width() > tfRectangle.width()) 722 { 723 tfx = symbolBounds.left + symbolBounds.width()/2 - (echelonBounds.width()/2) - 1; 724 tfw = echelonBounds.width()+2; 725 } 726 if(echelonBounds.height() > tfRectangle.height()) 727 { 728 tfy = echelonBounds.top-1; 729 tfh = echelonBounds.height()+2; 730 731 } 732 tfRectangle = RectUtilities.makeRect((int)tfx, 733 tfy,// + outlineOffset, 734 tfw, 735 tfh); 736 737 738 tfBounds = RectUtilities.makeRect((tfRectangle.left - 1), 739 (tfRectangle.top - 1), 740 (tfRectangle.width() + 2), 741 (tfRectangle.height() + 2)); 742 } 743 744 imageBounds.union(tfBounds); 745 } 746 // </editor-fold> 747 748 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 749 Rect fdiBounds = null; 750 Point fdiTop = null; 751 Point fdiLeft = null; 752 Point fdiRight = null; 753 754 755 if (SymbolUtilities.hasFDI(symbolID) 756 && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AB_FEINT_DUMMY_INDICATOR)) 757 { 758 //create feint indicator /\ 759 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 760 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 761 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f))); 762 763 764 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 765 fdiBounds.union(fdiTop.x, fdiTop.y); 766 fdiBounds.union(fdiRight.x, fdiRight.y); 767 768 float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 769 RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2)); 770 771 if (echelonBounds != null) 772 { 773 int shiftY = Math.round(symbolBounds.top - echelonBounds.height() - 2); 774 fdiLeft.offset(0, shiftY); 775 fdiTop.offset(0, shiftY); 776 fdiRight.offset(0, shiftY); 777 fdiBounds.offset(0, shiftY); 778 } 779 780 imageBounds.union(fdiBounds); 781 782 } 783 // </editor-fold> 784 785 //Using SVG files for installation indicator now 786 // <editor-fold defaultstate="collapsed" desc="Build Installation"> 787 /*//Using SVG files for the installation indicator 788 Rect instRectangle = null; 789 Rect instBounds = null; 790 if (SymbolUtilities.hasInstallationModifier(symbolID) 791 && SymbolUtilitiesD.canSymbolHaveModifier(symbolID, Modifiers.AC_INSTALLATION)) 792 {//the actual installation symbols have the modifier 793 //built in. everything else, we have to draw it. 794 // 795 ////get indicator dimensions//////////////////////////////// 796 int width; 797 int height; 798 char affiliation = SymbolUtilities.getAffiliation(symbolID); 799 800 if (affiliation == 'F' 801 || affiliation == 'A' 802 || affiliation == 'D' 803 || affiliation == 'M' 804 || affiliation == 'J' 805 || affiliation == 'K') 806 { 807 //4th height, 3rd width 808 height = Math.round(symbolBounds.height() / 4); 809 width = Math.round(symbolBounds.width() / 3); 810 } 811 else if (affiliation == 'H' || affiliation == 'S')//hostile,suspect 812 { 813 //6th height, 3rd width 814 height = Math.round(symbolBounds.height() / 6); 815 width = Math.round(symbolBounds.width() / 3); 816 } 817 else if (affiliation == 'N' || affiliation == 'L')//neutral,exercise neutral 818 { 819 //6th height, 3rd width 820 height = Math.round(symbolBounds.height() / 6); 821 width = Math.round(symbolBounds.width() / 3); 822 } 823 else if (affiliation == 'P' 824 || affiliation == 'U' 825 || affiliation == 'G' 826 || affiliation == 'W') 827 { 828 //6th height, 3rd width 829 height = Math.round(symbolBounds.height() / 6); 830 width = Math.round(symbolBounds.width() / 3); 831 } 832 else 833 { 834 //6th height, 3rd width 835 height = Math.round(symbolBounds.height() / 6); 836 width = Math.round(symbolBounds.width() / 3); 837 } 838 839// if(width * 3 < symbolBounds.width()) 840// width++; 841 //set installation position///////////////////////////////// 842 //set position of indicator 843 if (affiliation == 'F' 844 || affiliation == 'A' 845 || affiliation == 'D' 846 || affiliation == 'M' 847 || affiliation == 'J' 848 || affiliation == 'K' 849 || affiliation == 'N' 850 || affiliation == 'L') 851 { 852 instRectangle = RectUtilities.makeRect((int) (symbolBounds.left + width), 853 (int) (symbolBounds.top - height), 854 width, 855 height); 856 } 857 else if (affiliation == 'H' || affiliation == 'S')//hostile,suspect 858 { 859 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 860 Math.round((int) symbolBounds.top - (height * 0.15f)), 861 width, 862 height); 863 } 864 else if (affiliation == 'P' 865 || affiliation == 'U' 866 || affiliation == 'G' 867 || affiliation == 'W') 868 { 869 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 870 Math.round(symbolBounds.top - (height * 0.3f)), 871 width, 872 height); 873 } 874 else 875 { 876 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 877 Math.round(symbolBounds.top - (height * 0.3f)), 878 width, 879 height); 880 } 881 882 //generate installation bounds////////////////////////////// 883 instBounds = new Rect(instRectangle.left + -1, 884 instRectangle.top - 1, 885 instRectangle.width() + 2, 886 instRectangle.height() + 2); 887 888 imageBounds.union(instBounds); 889 890 }//*/ 891 // </editor-fold> 892 893 // <editor-fold defaultstate="collapsed" desc="Build Engagement Bar (AO)"> 894 //A:BBB-CC 895 String strAO = null; 896 Rect ebRectangle = null; 897 Rect ebBounds = null; 898 Rect ebTextBounds = null; 899 TextInfo ebText = null; 900 901 int ebTop = 0; 902 int ebLeft = 0; 903 int ebWidth = 0; 904 int ebHeight = 0; 905 Color ebColor = null;//SymbolUtilities.getFillColorOfAffiliation(symbolID); 906 907 if(attributes.containsKey(MilStdAttributes.EngagementBarColor)) 908 ebColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.EngagementBarColor)); 909 else 910 ebColor = fillColor; 911 912 if(SymbolUtilities.hasModifier(symbolID, Modifiers.AO_ENGAGEMENT_BAR) && 913 modifiers.containsKey(Modifiers.AO_ENGAGEMENT_BAR)) 914 strAO = modifiers.get(Modifiers.AO_ENGAGEMENT_BAR); 915 if(strAO != null) 916 { 917 ebText = new TextInfo(strAO, 0, 0, modifierFont, modifierFontName); 918 ebTextBounds = ebText.getTextBounds(); 919 ebHeight = ebTextBounds.height() + 4; 920 921 int barOffset = Math.max(RendererSettings.getInstance().getDeviceDPI()/32, 4); 922 923 if(fdiBounds != null)//set bar above FDI if present 924 { 925 ebTop = fdiBounds.top - ebHeight - barOffset; 926 } 927 else if(tfBounds != null)//set bar above TF if present 928 { 929 ebTop = tfBounds.top - ebHeight - barOffset; 930 } 931 else if(echelonBounds != null)//set bar above echelon if present 932 { 933 ebTop = echelonBounds.top - ebHeight - barOffset; 934 } 935 else if(isCOnTop(symbolID) && modifiers.containsKey(Modifiers.C_QUANTITY))//OR frame in air/space 936 { 937 ebTop = symbolBounds.top - (int)(ebHeight*2.5f); 938 } 939 else if(ss == SymbolID.SymbolSet_LandInstallation) 940 { 941 ebTop = symbolBounds.top - ebHeight - (barOffset * 2); 942 } 943 else//position above symbol 944 { 945 ebTop = symbolBounds.top - ebHeight - barOffset; 946 } 947 948 //if text wider than symbol, extend the bar. 949 if(ebTextBounds.width() > symbolBounds.width()) 950 { 951 ebWidth = ebTextBounds.width() + 4; 952 ebLeft = symbolCenter.x - (ebWidth/2); 953 } 954 else 955 { 956 ebLeft = symbolBounds.left + (int)Math.ceil(strokeWidthBasedOnDPI/2f);//1;//leave room for outline 957 ebWidth = symbolBounds.width() - (int)Math.ceil(strokeWidthBasedOnDPI);//2;//leave room for outline 958 } 959 960 //set text location within the bar 961 ebText.setLocation(symbolCenter.x - (ebTextBounds.width()/2), ebTop + ebHeight - ((ebHeight - ebTextBounds.height()) / 2)); 962 963 ebRectangle = RectUtilities.makeRect(ebLeft,ebTop,ebWidth,ebHeight); 964 ebBounds = new Rect(ebRectangle); 965 RectUtilities.grow(ebBounds,(int)Math.ceil(strokeWidthBasedOnDPI/2f)); 966 967 imageBounds.union(ebBounds); 968 } 969 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 for(int i = 0; i < mods.size(); i++) 3124 { 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 // </editor-fold> 3142 3143 //Shift Points and Draw 3144 newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes, modifierFont); 3145 3146 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 3147 tiArray = null; 3148 tiTemp = null; 3149 //tempShape = null; 3150 //ctx = null; 3151 //buffer = null; 3152 // </editor-fold> 3153 3154 return newsdi; 3155 } 3156 3157 public static SymbolDimensionInfo ProcessTGSPWithSpecialModifierLayout(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes, Color lineColor) 3158 { 3159 Paint modifierFont = getFont(attributes); 3160 float[] hd = getFontHeightandDescent(modifierFont); 3161 float modifierFontHeight = hd[0]; 3162 float modifierFontDescent = hd[1]; 3163 3164 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 3165 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 3166 { 3167 String temp = attributes.get(MilStdAttributes.FontFamily); 3168 if(temp != null && !temp.isEmpty()) 3169 modifierFontName = temp; 3170 } 3171 3172 ImageInfo ii = null; 3173 SVGSymbolInfo ssi = null; 3174 3175 int bufferXL = 6; 3176 int bufferXR = 4; 3177 int bufferY = 2; 3178 int bufferText = 2; 3179 int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel 3180 int x = 0; 3181 int y = 0; 3182 int x2 = 0; 3183 int y2 = 0; 3184 3185 int outlineOffset = RS.getTextOutlineWidth(); 3186 int labelHeight = 0; 3187 int labelWidth = 0; 3188 int alpha = -1; 3189 SymbolDimensionInfo newsdi = null; 3190 Color textColor = lineColor; 3191 Color textBackgroundColor = null; 3192 int ss = SymbolID.getSymbolSet(symbolID); 3193 int ec = SymbolID.getEntityCode(symbolID); 3194 int e = SymbolID.getEntity(symbolID); 3195 int et = SymbolID.getEntityType(symbolID); 3196 int est = SymbolID.getEntitySubtype(symbolID); 3197 3198 //Feint Dummy Indicator variables 3199 Rect fdiBounds = null; 3200 Point fdiTop = null; 3201 Point fdiLeft = null; 3202 Point fdiRight = null; 3203 3204 ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>(); 3205 boolean duplicate = false; 3206 3207 Rect bounds = new Rect(sdi.getSymbolBounds()); 3208 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 3209 Point centerPoint = new Point(sdi.getCenterPoint()); 3210 Rect imageBounds = new Rect(sdi.getImageBounds()); 3211 3212 if (attributes.containsKey(MilStdAttributes.Alpha)) 3213 { 3214 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 3215 textColor.setAlpha(alpha); 3216 } 3217 3218 centerPoint = new Point(Math.round(sdi.getCenterPoint().x), Math.round(sdi.getCenterPoint().y)); 3219 3220 boolean byLabelHeight = false; 3221 labelHeight = (int) (modifierFontHeight + 0.5f); 3222 3223 int maxHeight = (symbolBounds.height()); 3224 if ((labelHeight * 3) > maxHeight) 3225 { 3226 byLabelHeight = true; 3227 } 3228 3229 int descent = (int) (modifierFontDescent + 0.5f); 3230 int yForY = -1; 3231 3232 Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0); 3233 Rect labelBounds2 = null; 3234 String strText = ""; 3235 String strText1 = ""; 3236 String strText2 = ""; 3237 TextInfo text1 = null; 3238 TextInfo text2 = null; 3239 3240 3241 if (outlineOffset > 2) 3242 { 3243 outlineOffset = ((outlineOffset - 1) / 2); 3244 } 3245 else 3246 { 3247 outlineOffset = 0; 3248 } 3249 3250 3251 // <editor-fold defaultstate="collapsed" desc="Process Special Modifiers"> 3252 TextInfo ti = null; 3253 if (SymbolUtilities.isCBRNEvent(symbolID))//chemical 3254 { 3255 if ((labelHeight * 3) > bounds.height()) 3256 { 3257 byLabelHeight = true; 3258 } 3259 } 3260 3261 if(ss == SymbolID.SymbolSet_ControlMeasure) { 3262 if (ec == 130500 //contact point 3263 || ec == 130700) //decision 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 } else if (ec == 212800)//harbor 3281 { 3282 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3283 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3284 if (strText != null) { 3285 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3286 labelWidth = Math.round(ti.getTextBounds().width()); 3287 //One modifier symbols and modifier goes in center 3288 x = bounds.left + (int) (bounds.width() * 0.5f); 3289 x = x - (int) (labelWidth * 0.5f); 3290 y = bounds.top + (int) (bounds.height() * 0.5f); 3291 y = y + (int) (labelHeight * 0.5f); 3292 3293 ti.setLocation(Math.round(x), Math.round(y)); 3294 arrMods.add(ti); 3295 } 3296 } 3297 } else if (ec == 131300)//point of interest 3298 { 3299 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3300 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3301 if (strText != null) { 3302 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3303 labelWidth = Math.round(ti.getTextBounds().width()); 3304 //One modifier symbols, top third & center 3305 x = bounds.left + (int) (bounds.width() * 0.5f); 3306 x = x - (int) (labelWidth * 0.5f); 3307 y = bounds.top + (int) (bounds.height() * 0.25f); 3308 y = y + (int) (labelHeight * 0.5f); 3309 3310 ti.setLocation(Math.round(x), Math.round(y)); 3311 arrMods.add(ti); 3312 } 3313 } 3314 } else if (ec == 131800//waypoint 3315 || ec == 240900)//fire support station 3316 { 3317 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3318 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3319 if (strText != null) { 3320 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3321 3322 //One modifier symbols and modifier goes right of center 3323 if (ec == 131800) 3324 x = bounds.left + (int) (bounds.width() * 0.75f); 3325 else 3326 x = bounds.left + (bounds.width()); 3327 y = bounds.top + (int) (bounds.height() * 0.5f); 3328 y = y + (int) ((labelHeight - descent) * 0.5f); 3329 3330 ti.setLocation(Math.round(x), Math.round(y)); 3331 arrMods.add(ti); 3332 } 3333 } 3334 } 3335 else if (ec == 131900)//Airfield (AEGIS Only) 3336 { 3337 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3338 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3339 if (strText != null) { 3340 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3341 3342 //One modifier symbols and modifier goes right of symbol 3343 3344 x = bounds.left + (bounds.width() + bufferXR); 3345 3346 y = bounds.top + (int) (bounds.height() * 0.5f); 3347 y = y + (int) ((labelHeight - descent) * 0.5f); 3348 3349 ti.setLocation(Math.round(x), Math.round(y)); 3350 arrMods.add(ti); 3351 } 3352 } 3353 } 3354 else if (ec == 180100 //Air Control point 3355 || ec == 180200) //Communications Check point 3356 { 3357 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3358 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3359 if (strText != null) { 3360 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3361 labelWidth = ti.getTextBounds().width(); 3362 //One modifier symbols and modifier goes just below of center 3363 x = bounds.left + (int) (bounds.width() * 0.5); 3364 x = x - (int) (labelWidth * 0.5); 3365 y = bounds.top + (int) (bounds.height() * 0.5f); 3366 y = y + (int) (((bounds.height() * 0.5f) - labelHeight) / 2) + labelHeight - descent; 3367 3368 ti.setLocation(Math.round(x), Math.round(y)); 3369 arrMods.add(ti); 3370 } 3371 } 3372 } else if (ec == 160300 || //T (target reference point) 3373 ec == 132000 || //T (Target Handover) 3374 ec == 240601 || //ap,ap1,x,h (Point/Single Target) 3375 ec == 240602) //ap (nuclear target) 3376 { //Targets with special modifier positions 3377 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) 3378 && ec == 240601)//H //point single target 3379 { 3380 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3381 if (strText != null) { 3382 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3383 3384 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3385 y = bounds.top + (int) (bounds.height() * 0.75f); 3386 y = y + (int) (labelHeight * 0.5f); 3387 3388 ti.setLocation(Math.round(x), Math.round(y)); 3389 arrMods.add(ti); 3390 } 3391 } 3392 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) 3393 && ec == 240601)//X point or single target 3394 { 3395 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3396 if (strText != null) { 3397 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3398 labelWidth = Math.round(ti.getTextBounds().width()); 3399 x = RectUtilities.getCenterX(bounds) - (int) (bounds.width() * 0.15f); 3400 x = x - (labelWidth); 3401 y = bounds.top + (int) (bounds.height() * 0.75f); 3402 y = y + (int) (labelHeight * 0.5f); 3403 3404 ti.setLocation(Math.round(x), Math.round(y)); 3405 arrMods.add(ti); 3406 } 3407 } 3408 strText = null; 3409 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) && (ec == 160300 || ec == 132000)) { 3410 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3411 if (strText != null) { 3412 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3413 3414 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3415 y = bounds.top + (int) (bounds.height() * 0.25f); 3416 y = y + (int) (labelHeight * 0.5f); 3417 3418 ti.setLocation(Math.round(x), Math.round(y)); 3419 arrMods.add(ti); 3420 } 3421 } 3422 if (ec == 240601 || ec == 240602) 3423 { 3424 if (modifiers.containsKey(Modifiers.AP_TARGET_NUMBER)) { 3425 strText = modifiers.get(Modifiers.AP_TARGET_NUMBER); 3426 } 3427 if (ec == 240601 && modifiers.containsKey(Modifiers.AP1_TARGET_NUMBER_EXTENSION)) { 3428 if (strText != null) 3429 strText = strText + " " + modifiers.get(Modifiers.AP1_TARGET_NUMBER_EXTENSION); 3430 else 3431 strText = modifiers.get(Modifiers.AP1_TARGET_NUMBER_EXTENSION); 3432 } 3433 if (strText != null) { 3434 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3435 3436 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 3437 y = bounds.top + (int) (bounds.height() * 0.25f); 3438 y = y + (int) (labelHeight * 0.5f); 3439 3440 ti.setLocation(Math.round(x), Math.round(y)); 3441 arrMods.add(ti); 3442 } 3443 } 3444 } 3445 else if (ec == 132100)//Key Terrain 3446 { 3447 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3448 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3449 if (strText != null) { 3450 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3451 3452 //One modifier symbols and modifier goes right of symbol 3453 3454 x = bounds.left + (int)(bounds.width() * 0.5) + bufferXL; 3455 3456 y = bounds.top + (int) (bounds.height() * 0.5f); 3457 y = y + (int) ((labelHeight - descent) * 0.5f); 3458 3459 ti.setLocation(Math.round(x), Math.round(y)); 3460 arrMods.add(ti); 3461 } 3462 } 3463 } 3464 else if(ec == 182600)//Isolated Personnel Location 3465 { 3466 if (modifiers.containsKey(Modifiers.C_QUANTITY)) { 3467 strText = modifiers.get(Modifiers.C_QUANTITY); 3468 if (strText != null) { 3469 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3470 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3471 //subset of NBC, just nuclear 3472 x = (int)(bounds.left + (bounds.width() * 0.5)); 3473 x = x - (int) (labelWidth * 0.5); 3474 y = (int)bounds.top - descent; 3475 ti.setLocation(Math.round(x), Math.round(y)); 3476 arrMods.add(ti); 3477 } 3478 } 3479 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3480 strText = modifiers.get(Modifiers.W_DTG_1); 3481 if (strText != null) { 3482 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3483 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3484 3485 x = (int)bounds.left - labelWidth - bufferXL; 3486 if (!byLabelHeight) { 3487 y = (int)bounds.top + labelHeight - descent; 3488 } else { 3489 //y = bounds.y + ((bounds.getHeight * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3490 y = (int)(bounds.top + ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText))); 3491 } 3492 3493 ti.setLocation(Math.round(x), Math.round(y)); 3494 arrMods.add(ti); 3495 } 3496 } 3497 if (modifiers.containsKey(Modifiers.W1_DTG_2)) { 3498 strText = modifiers.get(Modifiers.W1_DTG_2); 3499 if (strText != null) { 3500 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3501 labelWidth = (int)Math.round(ti.getTextBounds().width()); 3502 3503 x = (int)bounds.left - labelWidth - bufferXL; 3504 if (!byLabelHeight) { 3505 y = (int)bounds.top + labelHeight - descent; 3506 } else { 3507 //y = bounds.y + ((bounds.getHeight * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3508 y = (int)(bounds.top + ((bounds.height() * 0.5) - (((labelHeight * 2) - descent) * 0.5) + (-descent - bufferText))); 3509 } 3510 3511 ti.setLocation(Math.round(x), Math.round(y)); 3512 arrMods.add(ti); 3513 } 3514 } 3515 } 3516 else if (SymbolUtilities.isCBRNEvent(symbolID)) //CBRN 3517 { 3518 if (modifiers.containsKey(Modifiers.N_HOSTILE)) { 3519 strText = modifiers.get(Modifiers.N_HOSTILE); 3520 if (strText != null) { 3521 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3522 3523 x = bounds.left + bounds.width() + bufferXR; 3524 3525 if (!byLabelHeight) { 3526 y = bounds.top + bounds.height(); 3527 } else { 3528 y = bounds.top + (int) ((bounds.height() * 0.5f) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText)); 3529 } 3530 3531 ti.setLocation(Math.round(x), Math.round(y)); 3532 arrMods.add(ti); 3533 } 3534 3535 } 3536 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3537 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3538 if (strText != null) { 3539 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3540 3541 x = bounds.left + bounds.width() + bufferXR; 3542 if (!byLabelHeight) { 3543 y = bounds.top + labelHeight - descent; 3544 } else { 3545 //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3546 y = bounds.top + (int) ((bounds.height() * 0.5f) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)); 3547 } 3548 3549 ti.setLocation(Math.round(x), Math.round(y)); 3550 arrMods.add(ti); 3551 } 3552 } 3553 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3554 strText = modifiers.get(Modifiers.W_DTG_1); 3555 if (strText != null) { 3556 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3557 labelWidth = Math.round(ti.getTextBounds().width()); 3558 3559 x = bounds.left - labelWidth - bufferXL; 3560 if (!byLabelHeight) { 3561 y = bounds.top + labelHeight - descent; 3562 } else { 3563 //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 3564 y = bounds.top + (int) ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)); 3565 } 3566 3567 ti.setLocation(Math.round(x), Math.round(y)); 3568 arrMods.add(ti); 3569 } 3570 } 3571 if ((ec == 281500 || ec == 281600) && modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) {//nuclear event or nuclear fallout producing event 3572 strText = modifiers.get(Modifiers.V_EQUIP_TYPE); 3573 if (strText != null) { 3574 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3575 3576 //subset of nbc, just nuclear 3577 labelWidth = Math.round(ti.getTextBounds().width()); 3578 x = bounds.left - labelWidth - bufferXL; 3579 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5));//((bounds.height / 2) - (labelHeight/2)); 3580 3581 ti.setLocation(Math.round(x), Math.round(y)); 3582 arrMods.add(ti); 3583 } 3584 } 3585 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3586 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3587 if (strText != null) { 3588 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3589 labelWidth = Math.round(ti.getTextBounds().width()); 3590 x = bounds.left - labelWidth - bufferXL; 3591 if (!byLabelHeight) { 3592 y = bounds.top + bounds.height(); 3593 } else { 3594 //y = bounds.y + ((bounds.height * 0.5) + ((labelHeight-descent) * 0.5) + (labelHeight + bufferText)); 3595 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText)); 3596 } 3597 ti.setLocation(Math.round(x), Math.round(y)); 3598 arrMods.add(ti); 3599 } 3600 } 3601 if (modifiers.containsKey(Modifiers.Y_LOCATION)) { 3602 strText = modifiers.get(Modifiers.Y_LOCATION); 3603 if (strText != null) { 3604 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3605 labelWidth = Math.round(ti.getTextBounds().width()); 3606 //just NBC 3607 //x = bounds.left + (bounds.width() * 0.5); 3608 //x = x - (labelWidth * 0.5); 3609 x = bounds.left + (int) (bounds.width() * 0.5f); 3610 x = x - (int) (labelWidth * 0.5f); 3611 3612 if (!byLabelHeight) { 3613 y = bounds.top + bounds.height() + labelHeight - descent + bufferY; 3614 } else { 3615 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + ((labelHeight + bufferText) * 2) - descent); 3616 3617 } 3618 yForY = y + descent; //so we know where to start the DOM arrow. 3619 ti.setLocation(Math.round(x), Math.round(y)); 3620 arrMods.add(ti); 3621 } 3622 3623 } 3624 if (modifiers.containsKey(Modifiers.C_QUANTITY)) { 3625 strText = modifiers.get(Modifiers.C_QUANTITY); 3626 if (strText != null) { 3627 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3628 labelWidth = Math.round(ti.getTextBounds().width()); 3629 //subset of NBC, just nuclear 3630 x = bounds.left + (int) (bounds.width() * 0.5); 3631 x = x - (int) (labelWidth * 0.5); 3632 y = bounds.top - descent; 3633 ti.setLocation(Math.round(x), Math.round(y)); 3634 arrMods.add(ti); 3635 } 3636 3637 } 3638 } 3639 else if (ec == 270701)//static depiction 3640 { 3641 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3642 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3643 if (strText != null) { 3644 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3645 labelWidth = Math.round(ti.getTextBounds().width()); 3646 x = bounds.left + (int) (bounds.width() * 0.5); 3647 x = x - (int) (labelWidth * 0.5); 3648 y = bounds.top - descent;// + (bounds.height * 0.5); 3649 //y = y + (labelHeight * 0.5); 3650 3651 ti.setLocation(Math.round(x), Math.round(y)); 3652 arrMods.add(ti); 3653 } 3654 3655 } 3656 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3657 strText = modifiers.get(Modifiers.W_DTG_1); 3658 if (strText != null) { 3659 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3660 labelWidth = Math.round(ti.getTextBounds().width()); 3661 x = bounds.left + (int) (bounds.width() * 0.5); 3662 x = x - (int) (labelWidth * 0.5); 3663 y = bounds.top + (bounds.height()); 3664 y = y + (labelHeight); 3665 3666 ti.setLocation(Math.round(x), Math.round(y)); 3667 arrMods.add(ti); 3668 } 3669 } 3670 if (modifiers.containsKey(Modifiers.N_HOSTILE)) { 3671 strText = modifiers.get(Modifiers.N_HOSTILE); 3672 if (strText != null) { 3673 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3674 TextInfo ti2 = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3675 labelWidth = Math.round(ti.getTextBounds().width()); 3676 x = bounds.left + (bounds.width()) + bufferXR;//right 3677 //x = x + labelWidth;//- (labelBounds.width * 0.75); 3678 3679 duplicate = true; 3680 3681 x2 = bounds.left;//left 3682 x2 = x2 - labelWidth - bufferXL;// - (labelBounds.width * 0.25); 3683 3684 y = bounds.top + (int) (bounds.height() * 0.5);//center 3685 y = y + (int) ((labelHeight - descent) * 0.5); 3686 3687 y2 = y; 3688 3689 ti.setLocation(Math.round(x), Math.round(y)); 3690 ti2.setLocation(Math.round(x2), Math.round(y2)); 3691 arrMods.add(ti); 3692 arrMods.add(ti2); 3693 } 3694 } 3695 3696 } 3697 else if(e == 21 && et == 35)//sonobuoys 3698 { 3699 //H sitting on center of circle to the right 3700 //T above H 3701 centerPoint = SymbolUtilities.getCMSymbolAnchorPoint(symbolID,RectUtilities.makeRectFFromRect(bounds)); 3702 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3703 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 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 y = centerPoint.y; 3710 3711 ti.setLocation(Math.round(x), Math.round(y)); 3712 arrMods.add(ti); 3713 } 3714 } 3715 if (est == 0 || est == 1 || est == 4 || est == 7 || est == 8 || est == 15) { 3716 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3717 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3718 if (strText != null) { 3719 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3720 TextInfo ti2 = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3721 labelWidth = Math.round(ti.getTextBounds().width()); 3722 x = bounds.left + (bounds.width()) + bufferXR;//right 3723 y = centerPoint.y - labelHeight; 3724 3725 ti.setLocation(Math.round(x), Math.round(y)); 3726 arrMods.add(ti); 3727 } 3728 } 3729 } 3730 } 3731 else if(ec == 282001 || //tower, low 3732 ec == 282002) //tower, high 3733 { 3734 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) { 3735 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3736 if (strText != null) { 3737 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3738 labelWidth = Math.round(ti.getTextBounds().width()); 3739 x = bounds.left + (int) (bounds.width() * 0.7); 3740 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3741 //y = y + (labelHeight * 0.5); 3742 3743 ti.setLocation(Math.round(x), Math.round(y)); 3744 arrMods.add(ti); 3745 } 3746 3747 } 3748 } 3749 else if(ec == 180600)//TACAN 3750 { 3751 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3752 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3753 if (strText != null) { 3754 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3755 labelWidth = Math.round(ti.getTextBounds().width()); 3756 x = bounds.left + bounds.width() + bufferXR; 3757 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3758 //y = y + (labelHeight * 0.5); 3759 3760 ti.setLocation(Math.round(x), Math.round(y)); 3761 arrMods.add(ti); 3762 } 3763 3764 } 3765 } 3766 else if(ec == 210300)//Defended Asset 3767 { 3768 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3769 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3770 if (strText != null) { 3771 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3772 labelWidth = Math.round(ti.getTextBounds().width()); 3773 x = bounds.left - labelWidth - bufferXL; 3774 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3775 //y = y + (labelHeight * 0.5); 3776 3777 ti.setLocation(Math.round(x), Math.round(y)); 3778 arrMods.add(ti); 3779 } 3780 3781 } 3782 } 3783 else if(ec == 210600)//Air Detonation 3784 { 3785 if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) { 3786 strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 3787 if (strText != null) { 3788 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3789 labelWidth = Math.round(ti.getTextBounds().width()); 3790 x = bounds.left + (bounds.width() + bufferXR); 3791 y = bounds.top + labelHeight;// + (bounds.height * 0.5); 3792 //y = y + (labelHeight * 0.5); 3793 3794 ti.setLocation(Math.round(x), Math.round(y)); 3795 arrMods.add(ti); 3796 } 3797 3798 } 3799 } 3800 else if(ec == 210800)//Impact Point 3801 { 3802 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3803 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3804 if (strText != null) { 3805 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3806 labelWidth = Math.round(ti.getTextBounds().width()); 3807 x = bounds.left + (int) (bounds.width() * 0.65f); 3808// x = x - (labelBounds.width * 0.5); 3809 y = bounds.top + (int) (bounds.height() * 0.25f); 3810 y = y + (int) (labelHeight * 0.5f); 3811 //y = y + (labelHeight * 0.5); 3812 3813 ti.setLocation(Math.round(x), Math.round(y)); 3814 arrMods.add(ti); 3815 } 3816 3817 } 3818 } 3819 else if(ec == 211000)//Launched Torpedo 3820 { 3821 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3822 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3823 if (strText != null) { 3824 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3825 labelWidth = Math.round(ti.getTextBounds().width()); 3826 x = (int)(bounds.left + (bounds.width() * 0.5) - (labelWidth/2)); 3827 y = bounds.top - bufferY; 3828 3829 ti.setLocation(Math.round(x), Math.round(y)); 3830 arrMods.add(ti); 3831 } 3832 3833 } 3834 } 3835 else if(ec == 214900 || ec == 215600)//General Sea SubSurface Station & General Sea Surface Station 3836 { 3837 if (modifiers.containsKey(Modifiers.W_DTG_1)) { 3838 strText = modifiers.get(Modifiers.W_DTG_1); 3839 if (strText != null) { 3840 ti = new TextInfo(strText + " - ", 0, 0, modifierFont, modifierFontName); 3841 x = bounds.left + (bounds.width() + bufferXR); 3842 y = bounds.top + labelHeight; 3843 3844 ti.setLocation(Math.round(x), Math.round(y)); 3845 arrMods.add(ti); 3846 } 3847 3848 } 3849 if (modifiers.containsKey(Modifiers.W1_DTG_2)) { 3850 strText = modifiers.get(Modifiers.W1_DTG_2); 3851 if (strText != null) { 3852 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3853 x = bounds.left + (bounds.width() + bufferXR); 3854 y = bounds.top + (labelHeight * 2); 3855 3856 ti.setLocation(Math.round(x), Math.round(y)); 3857 arrMods.add(ti); 3858 } 3859 3860 } 3861 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3862 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3863 if (strText != null) { 3864 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3865 x = bounds.left + (bounds.width() + bufferXR); 3866 y = bounds.top + (labelHeight * 3); 3867 3868 ti.setLocation(Math.round(x), Math.round(y)); 3869 arrMods.add(ti); 3870 } 3871 3872 } 3873 } 3874 else if(ec == 217000)//Shore Control Station 3875 { 3876 if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) { 3877 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 3878 if (strText != null) { 3879 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3880 labelWidth = Math.round(ti.getTextBounds().width()); 3881 x = (int)(bounds.left + (bounds.width() * 0.5) - (labelWidth/2)); 3882 y = bounds.top + bounds.height() + labelHeight + bufferY; 3883 3884 ti.setLocation(Math.round(x), Math.round(y)); 3885 arrMods.add(ti); 3886 } 3887 3888 } 3889 } 3890 else if(ec == 250600)//Known Point 3891 { 3892 if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) { 3893 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 3894 if (strText != null) { 3895 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3896 labelWidth = Math.round(ti.getTextBounds().width()); 3897 x = bounds.left + (bounds.width() + bufferXR); 3898// x = x - (labelBounds.width * 0.5); 3899 y = bounds.top + (int) (bounds.height() * 0.25f); 3900 y = y + (int) (labelHeight * 0.5f); 3901 //y = y + (labelHeight * 0.5); 3902 3903 ti.setLocation(Math.round(x), Math.round(y)); 3904 arrMods.add(ti); 3905 } 3906 3907 } 3908 } 3909 } 3910 else if(ss == SymbolID.SymbolSet_Atmospheric) 3911 { 3912 String modX = null; 3913 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 3914 modX = (modifiers.get(Modifiers.X_ALTITUDE_DEPTH)); 3915 3916 if(ec == 162300)//Freezing Level 3917 { 3918 strText = "0" + (char)(176) + ":"; 3919 if(modX != null) 3920 strText += modX; 3921 else 3922 strText += "?"; 3923 3924 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3925 labelWidth = Math.round(ti.getTextBounds().width()); 3926 //One modifier symbols and modifier goes in center 3927 x = bounds.left + (int) (bounds.width() * 0.5f); 3928 x = x - (int) (labelWidth * 0.5f); 3929 y = bounds.top + (int) (bounds.height() * 0.5f); 3930 y = y + (int) ((labelHeight - modifierFontDescent) * 0.5f); 3931 3932 ti.setLocation(Math.round(x), Math.round(y)); 3933 arrMods.add(ti); 3934 } 3935 else if(ec == 162200)//tropopause Level 3936 { 3937 strText = "X?"; 3938 if(modX != null) 3939 strText = modX; 3940 3941 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3942 labelWidth = Math.round(ti.getTextBounds().width()); 3943 //One modifier symbols and modifier goes in center 3944 x = bounds.left + (int) (bounds.width() * 0.5f); 3945 x = x - (int) (labelWidth * 0.5f); 3946 y = bounds.top + (int) (bounds.height() * 0.5f); 3947 y = y + (int) ((labelHeight - modifierFontDescent) * 0.5f); 3948 3949 ti.setLocation(Math.round(x), Math.round(y)); 3950 arrMods.add(ti); 3951 } 3952 else if(ec == 110102)//tropopause Low 3953 { 3954 strText = "X?"; 3955 if(modX != null) 3956 strText = modX; 3957 3958 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3959 labelWidth = Math.round(ti.getTextBounds().width()); 3960 //One modifier symbols and modifier goes in center 3961 x = bounds.left + (int) (bounds.width() * 0.5f); 3962 x = x - (int) (labelWidth * 0.5f); 3963 y = bounds.top + (int) (bounds.height() * 0.5f); 3964 y = y - descent; 3965 3966 ti.setLocation(Math.round(x), Math.round(y)); 3967 arrMods.add(ti); 3968 } 3969 else if(ec == 110202)//tropopause High 3970 { 3971 strText = "X?"; 3972 if(modX != null) 3973 strText = modX; 3974 3975 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 3976 labelWidth = Math.round(ti.getTextBounds().width()); 3977 //One modifier symbols and modifier goes in center 3978 x = bounds.left + (int) (bounds.width() * 0.5f); 3979 x = x - (int) (labelWidth * 0.5f); 3980 y = bounds.top + (int) (bounds.height() * 0.5f); 3981 //y = y + (int) ((labelHeight * 0.5f) + (labelHeight/2)); 3982 y = y + (int) (((labelHeight * 0.5f) - (labelHeight/2)) + labelHeight - descent); 3983 3984 ti.setLocation(Math.round(x), Math.round(y)); 3985 arrMods.add(ti); 3986 } 3987 } 3988 // </editor-fold> 3989 3990 // <editor-fold defaultstate="collapsed" desc="DOM Arrow"> 3991 Point[] domPoints = null; 3992 Rect domBounds = null; 3993 3994 if (modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT) && 3995 SymbolUtilities.isCBRNEvent(symbolID))//CBRN events 3996 { 3997 strText = modifiers.get(Modifiers.Q_DIRECTION_OF_MOVEMENT); 3998 if(strText != null && SymbolUtilities.isNumber(strText)) 3999 { 4000 float q = Float.parseFloat(strText); 4001 Rect tempBounds = new Rect(bounds); 4002 tempBounds.union(RectUtilities.getCenterX(bounds), yForY); 4003 4004 domPoints = createDOMArrowPoints(symbolID, tempBounds, sdi.getCenterPoint(), q, false, modifierFontHeight); 4005 4006 domBounds = RectUtilities.makeRect(domPoints[0].x, domPoints[0].y, 1, 1); 4007 4008 Point temp = null; 4009 for (int i = 1; i < 6; i++) 4010 { 4011 temp = domPoints[i]; 4012 if (temp != null) 4013 { 4014 domBounds.union(temp.x, temp.y); 4015 } 4016 } 4017 imageBounds.union(domBounds); 4018 } 4019 } 4020 // </editor-fold> 4021 4022 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 4023 if (SymbolUtilities.hasFDI(symbolID)) 4024 { 4025 //create feint indicator /\ 4026 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 4027 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 4028 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f))); 4029 4030 4031 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 4032 fdiBounds.union(fdiTop.x, fdiTop.y); 4033 fdiBounds.union(fdiRight.x, fdiRight.y); 4034 4035 float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4036 RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2)); 4037 4038 ti = new TextInfo("TEST",0,0, modifierFont, modifierFontName); 4039 if (ti != null && SymbolUtilities.isCBRNEvent(symbolID)) 4040 { 4041 int shiftY = Math.round(symbolBounds.top - ti.getTextBounds().height() - 2); 4042 fdiLeft.offset(0, shiftY); 4043 fdiTop.offset(0, shiftY); 4044 fdiRight.offset(0, shiftY); 4045 fdiBounds.offset(0, shiftY); 4046 } 4047 4048 imageBounds.union(fdiBounds); 4049 4050 } 4051 // </editor-fold> 4052 4053 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 4054 Rect modifierBounds = null; 4055 if (arrMods != null && arrMods.size() > 0) 4056 { 4057 4058 //build modifier bounds///////////////////////////////////////// 4059 modifierBounds = arrMods.get(0).getTextOutlineBounds(); 4060 int size = arrMods.size(); 4061 TextInfo tempShape = null; 4062 for (int i = 1; i < size; i++) 4063 { 4064 tempShape = arrMods.get(i); 4065 modifierBounds.union(tempShape.getTextOutlineBounds()); 4066 } 4067 4068 } 4069 4070 if (modifierBounds != null || domBounds != null || fdiBounds != null) 4071 { 4072 4073 if (modifierBounds != null) 4074 { 4075 imageBounds.union(modifierBounds); 4076 } 4077 if (domBounds != null) 4078 { 4079 imageBounds.union(domBounds); 4080 } 4081 if (fdiBounds != null) 4082 { 4083 imageBounds.union(fdiBounds); 4084 } 4085 4086 //shift points if needed//////////////////////////////////////// 4087 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4088 { 4089 int shiftX = Math.abs(imageBounds.left); 4090 int shiftY = Math.abs(imageBounds.top); 4091 4092 //shift mobility points 4093 int size = arrMods.size(); 4094 TextInfo tempShape = null; 4095 for (int i = 0; i < size; i++) 4096 { 4097 tempShape = arrMods.get(i); 4098 tempShape.shift(shiftX, shiftY); 4099 } 4100 if(modifierBounds != null) 4101 modifierBounds.offset(shiftX, shiftY); 4102 4103 if (domBounds != null) 4104 { 4105 for (int i = 0; i < 6; i++) 4106 { 4107 Point temp = domPoints[i]; 4108 if (temp != null) 4109 { 4110 temp.offset(shiftX, shiftY); 4111 } 4112 } 4113 domBounds.offset(shiftX, shiftY); 4114 } 4115 4116 //If there's an FDI 4117 if (fdiBounds != null) 4118 { 4119 fdiBounds.offset(shiftX, shiftY); 4120 fdiLeft.offset(shiftX, shiftY); 4121 fdiTop.offset(shiftX, shiftY); 4122 fdiRight.offset(shiftX, shiftY); 4123 } 4124 4125 //shift image points 4126 centerPoint.offset(shiftX, shiftY); 4127 symbolBounds.offset(shiftX, shiftY); 4128 imageBounds.offset(shiftX, shiftY); 4129 } 4130 4131 4132 if (attributes.containsKey(MilStdAttributes.TextColor)) 4133 { 4134 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4135 if(alpha > -1) 4136 textColor.setAlpha(alpha); 4137 } 4138 if (attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4139 { 4140 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4141 if(alpha > -1) 4142 textBackgroundColor.setAlpha(alpha); 4143 } 4144 4145 if(sdi instanceof ImageInfo) { 4146 ii = (ImageInfo)sdi; 4147 //Render modifiers////////////////////////////////////////////////// 4148 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 4149 Canvas ctx = new Canvas(bmp); 4150 4151 //render//////////////////////////////////////////////////////// 4152 //draw original icon with potential modifiers. 4153 ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null); 4154 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 4155 4156 4157 renderText(ctx, arrMods, textColor, textBackgroundColor, modifierFont); 4158 4159 //draw DOM arrow 4160 if (domBounds != null) 4161 { 4162 drawDOMArrow(ctx, domPoints, alpha, lineColor); 4163 } 4164 4165 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4166 if (fdiBounds != null) { 4167 4168 Paint fdiPaint = new Paint(); 4169 fdiPaint.setAntiAlias(true); 4170 fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 4171 if (alpha > -1) 4172 fdiPaint.setAlpha(alpha); 4173 fdiPaint.setStyle(Style.STROKE); 4174 4175 int dpi = RendererSettings.getInstance().getDeviceDPI(); 4176 int lineLength = dpi / 96 * 6; 4177 int lineGap = dpi / 96 * 4; 4178 4179 /// /////////////////////////////////// 4180 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4181 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4182 //distance = distance / 14f; 4183 lineGap = (int)((distance / 14f) * 2); 4184 lineLength = (int)((distance / 14f) * 3); 4185 /// ////////////////////////////////// 4186 4187 fdiPaint.setPathEffect(new DashPathEffect(new float[] 4188 { 4189 lineLength, lineGap 4190 }, 0)); 4191 4192 float fdiStrokeWidth = Math.round(dpi / 96f); 4193 if (fdiStrokeWidth < 2) 4194 fdiStrokeWidth = 2; 4195 4196 fdiPaint.setStrokeCap(Cap.ROUND); 4197 fdiPaint.setStrokeJoin(Join.MITER); 4198 fdiPaint.setStrokeWidth(fdiStrokeWidth); 4199 4200 Path fdiPath = new Path(); 4201 4202 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4203 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4204 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4205 fdiPath.lineTo(fdiRight.x, fdiRight.y); 4206 ctx.drawPath(fdiPath, fdiPaint); 4207 4208 fdiBounds = null; 4209 4210 } 4211 //</editor-fold> 4212 4213 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 4214 ctx = null; 4215 } 4216 else if(sdi instanceof SVGSymbolInfo) 4217 { 4218 float strokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4219 if(strokeWidth < 1) 4220 strokeWidth=1; 4221 String svgStroke = RendererUtilities.colorToHexString(lineColor,false); 4222 String svgStrokeWidth = String.valueOf(strokeWidth);//"3"; 4223 4224 ssi = (SVGSymbolInfo)sdi; 4225 StringBuilder sbSVG = new StringBuilder(); 4226 sbSVG.append(ssi.getSVG()); 4227 sbSVG.append(renderTextElements(arrMods,textColor,textBackgroundColor)); 4228 4229 // <editor-fold defaultstate="collapsed" desc="DOM arrow"> 4230 if (domBounds != null && domPoints.length == 6) 4231 { 4232 SVGPath domPath = new SVGPath() ; 4233 4234 domPath.moveTo(domPoints[0].x, domPoints[0].y); 4235 if (domPoints[1] != null) 4236 { 4237 domPath.lineTo(domPoints[1].x, domPoints[1].y); 4238 } 4239 if (domPoints[2] != null) 4240 { 4241 domPath.lineTo(domPoints[2].x, domPoints[2].y); 4242 } 4243 sbSVG.append(domPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,null)); 4244 4245 domPath = new SVGPath(); 4246 4247 domPath.moveTo(domPoints[3].x, domPoints[3].y); 4248 domPath.lineTo(domPoints[4].x, domPoints[4].y); 4249 domPath.lineTo(domPoints[5].x, domPoints[5].y); 4250 sbSVG.append(domPath.toSVGElement(null,0f,svgStroke,1f,1f,null)); 4251 4252 domBounds = null; 4253 domPoints = null; 4254 } 4255 // </editor-fold> 4256 4257 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4258 if (fdiBounds != null) 4259 { 4260 4261 /*int dpi = RendererSettings.getInstance().getDeviceDPI(); 4262 int lineLength = dpi / 96 * 6; 4263 int lineGap = dpi / 96 * 4; 4264 String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/ 4265 4266 /// /////////////////////////////////// 4267 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4268 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4269 //distance = distance / 14f; 4270 int lineGap = (int)((distance / 14f) * 2); 4271 int lineLength = (int)((distance / 14f) * 3); 4272 String svgFDIDashArray = "" + lineLength + " " + lineGap; 4273 /// ////////////////////////////////// 4274 4275 SVGPath fdiPath = new SVGPath(); 4276 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4277 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4278 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4279 fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/ 4280 4281 fdiPath.setLineDash(svgFDIDashArray); 4282 4283 sbSVG.append(fdiPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,"round")); 4284 //sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray)); 4285 } 4286 //</editor-fold> 4287 4288 newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds); 4289 } 4290 4291 4292 4293 4294 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 4295 //ctx = null; 4296 // </editor-fold> 4297 4298 return newsdi; 4299 4300 } 4301 else 4302 { 4303 return null; 4304 } 4305 // </editor-fold> 4306 4307 } 4308 4309 /** 4310 * Process modifiers for action points 4311 */ 4312 public static SymbolDimensionInfo ProcessTGSPModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes, Color lineColor) 4313 { 4314 4315 Paint modifierFont = getFont(attributes); 4316 float[] hd = getFontHeightandDescent(modifierFont); 4317 float modifierFontHeight = hd[0]; 4318 float modifierFontDescent = hd[1]; 4319 4320 String modifierFontName = RendererSettings.getInstance().getModiferFontProps()[0]; 4321 if(attributes != null && attributes.containsKey(MilStdAttributes.FontFamily)) 4322 { 4323 String temp = attributes.get(MilStdAttributes.FontFamily); 4324 if(temp != null && !temp.isEmpty()) 4325 modifierFontName = temp; 4326 } 4327 4328 // <editor-fold defaultstate="collapsed" desc="Variables"> 4329 ImageInfo ii = null; 4330 SVGSymbolInfo ssi = null; 4331 4332 int bufferXL = 6; 4333 int bufferXR = 4; 4334 int bufferY = 2; 4335 int bufferText = 2; 4336 int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel 4337 int x = 0; 4338 int y = 0; 4339 int x2 = 0; 4340 int y2 = 0; 4341 4342 //Feint Dummy Indicator variables 4343 Rect fdiBounds = null; 4344 Point fdiTop = null; 4345 Point fdiLeft = null; 4346 Point fdiRight = null; 4347 4348 int outlineOffset = RS.getTextOutlineWidth(); 4349 int labelHeight = 0; 4350 int labelWidth = 0; 4351 int alpha = -1; 4352 SymbolDimensionInfo newsdi = null; 4353 4354 Color textColor = lineColor; 4355 Color textBackgroundColor = null; 4356 4357 ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>(); 4358 boolean duplicate = false; 4359 4360 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 4361 4362 4363 if (attributes.containsKey(MilStdAttributes.Alpha)) 4364 { 4365 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 4366 } 4367 4368 Rect bounds = new Rect(sdi.getSymbolBounds()); 4369 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 4370 Point centerPoint = new Point(sdi.getCenterPoint()); 4371 Rect imageBounds = new Rect(sdi.getImageBounds()); 4372 4373 centerPoint = new Point(Math.round(sdi.getCenterPoint().x), Math.round(sdi.getCenterPoint().y)); 4374 4375 boolean byLabelHeight = false; 4376 4377 labelHeight = Math.round(modifierFontHeight + 0.5f); 4378 int maxHeight = (symbolBounds.height()); 4379 if ((labelHeight * 3) > maxHeight) 4380 { 4381 byLabelHeight = true; 4382 } 4383 4384 int descent = (int) (modifierFontDescent + 0.5f); 4385 int yForY = -1; 4386 4387 Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0); 4388 Rect labelBounds2 = null; 4389 String strText = ""; 4390 String strText1 = ""; 4391 String strText2 = ""; 4392 TextInfo text1 = null; 4393 TextInfo text2 = null; 4394 4395 String basicID = SymbolUtilities.getBasicSymbolID(symbolID); 4396 4397 if (outlineOffset > 2) 4398 { 4399 outlineOffset = ((outlineOffset - 1) / 2); 4400 } 4401 else 4402 { 4403 outlineOffset = 0; 4404 } 4405 4406 /*bufferXL += outlineOffset; 4407 bufferXR += outlineOffset; 4408 bufferY += outlineOffset; 4409 bufferText += outlineOffset;*/ 4410 // </editor-fold> 4411 // <editor-fold defaultstate="collapsed" desc="Process Modifiers"> 4412 TextInfo ti = null; 4413 4414 { 4415 if (msi.getModifiers().contains(Modifiers.N_HOSTILE) && modifiers.containsKey(Modifiers.N_HOSTILE)) 4416 { 4417 strText = modifiers.get(Modifiers.N_HOSTILE); 4418 if(strText != null) 4419 { 4420 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4421 4422 x = bounds.left + bounds.width() + bufferXR; 4423 4424 if (!byLabelHeight) 4425 { 4426 y = ((bounds.height() / 3) * 2);//checkpoint, get box above the point 4427 y = bounds.top + y; 4428 } 4429 else 4430 { 4431 //y = ((labelHeight + bufferText) * 3); 4432 //y = bounds.y + y - descent; 4433 y = bounds.top + bounds.height(); 4434 } 4435 4436 ti.setLocation(x, y); 4437 arrMods.add(ti); 4438 } 4439 4440 } 4441 if (msi.getModifiers().contains(Modifiers.H_ADDITIONAL_INFO_1) && modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 4442 { 4443 strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 4444 if(strText != null) 4445 { 4446 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4447 labelWidth = Math.round(ti.getTextBounds().width()); 4448 4449 x = bounds.left + (int) (bounds.width() * 0.5f); 4450 x = x - (int) (labelWidth * 0.5f); 4451 y = bounds.top - descent; 4452 4453 ti.setLocation(x, y); 4454 arrMods.add(ti); 4455 } 4456 } 4457 if (msi.getModifiers().contains(Modifiers.H1_ADDITIONAL_INFO_2) && modifiers.containsKey(Modifiers.H1_ADDITIONAL_INFO_2)) 4458 { 4459 strText = modifiers.get(Modifiers.H1_ADDITIONAL_INFO_2); 4460 if(strText != null) 4461 { 4462 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4463 labelWidth = Math.round(ti.getTextBounds().width()); 4464 4465 x = bounds.left + (int) (bounds.width() * 0.5); 4466 x = x - (int) (labelWidth * 0.5); 4467 y = bounds.top + labelHeight - descent + (int) (bounds.height() * 0.07); 4468 4469 ti.setLocation(x, y); 4470 arrMods.add(ti); 4471 } 4472 } 4473 if (msi.getModifiers().contains(Modifiers.A_SYMBOL_ICON)) 4474 { 4475 if(modifiers.containsKey(Modifiers.A_SYMBOL_ICON)) 4476 strText = modifiers.get(Modifiers.A_SYMBOL_ICON); 4477 else if(SymbolID.getEntityCode(symbolID)==321706)//NATO Multiple Supply Class Point 4478 strText = "ALL?";//make it clear the required 'A' value wasn't set for this symbol. 4479 4480 if(strText != null) 4481 { 4482 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4483 labelWidth = Math.round(ti.getTextBounds().width()); 4484 4485 x = bounds.left + (int) (bounds.width() * 0.5); 4486 x = x - (int) (labelWidth * 0.5); 4487 y = bounds.top + labelHeight - descent + (int) (bounds.height() * 0.07); 4488 4489 ti.setLocation(x, y); 4490 arrMods.add(ti); 4491 } 4492 } 4493 if (msi.getModifiers().contains(Modifiers.W_DTG_1) && modifiers.containsKey(Modifiers.W_DTG_1)) 4494 { 4495 strText = modifiers.get(Modifiers.W_DTG_1); 4496 if(strText != null) 4497 { 4498 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4499 labelWidth = Math.round(ti.getTextBounds().width()); 4500 4501 x = bounds.left - labelWidth - bufferXL; 4502 y = bounds.top + labelHeight - descent; 4503 4504 ti.setLocation(x, y); 4505 arrMods.add(ti); 4506 } 4507 } 4508 if (msi.getModifiers().contains(Modifiers.W1_DTG_2) && modifiers.containsKey(Modifiers.W1_DTG_2)) 4509 { 4510 strText = modifiers.get(Modifiers.W1_DTG_2); 4511 if(strText != null) 4512 { 4513 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4514 labelWidth = Math.round(ti.getTextBounds().width()); 4515 4516 x = bounds.left - labelWidth - bufferXL; 4517 4518 y = ((labelHeight - descent + bufferText) * 2); 4519 y = bounds.top + y; 4520 4521 ti.setLocation(x, y); 4522 arrMods.add(ti); 4523 } 4524 } 4525 if (msi.getModifiers().contains(Modifiers.T_UNIQUE_DESIGNATION_1) && modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 4526 { 4527 strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 4528 if(strText != null) 4529 { 4530 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4531 4532 x = bounds.left + bounds.width() + bufferXR; 4533 y = bounds.top + labelHeight - descent; 4534 4535 ti.setLocation(x, y); 4536 arrMods.add(ti); 4537 } 4538 } 4539 if (msi.getModifiers().contains(Modifiers.T1_UNIQUE_DESIGNATION_2) && modifiers.containsKey(Modifiers.T1_UNIQUE_DESIGNATION_2)) 4540 { 4541 strText = modifiers.get(Modifiers.T1_UNIQUE_DESIGNATION_2); 4542 if(strText != null) 4543 { 4544 ti = new TextInfo(strText, 0, 0, modifierFont, modifierFontName); 4545 labelWidth = Math.round(ti.getTextBounds().width()); 4546 4547 //points 4548 x = bounds.left + (int) (bounds.width() * 0.5); 4549 x = x - (int) (labelWidth * 0.5); 4550 //y = bounds.y + (bounds.height * 0.5); 4551 4552 y = (int) ((bounds.height() * 0.55));//633333333 4553 y = bounds.top + y; 4554 4555 ti.setLocation(x, y); 4556 arrMods.add(ti); 4557 } 4558 } 4559 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 4560 if (SymbolUtilities.hasFDI(symbolID)) 4561 { 4562 //create feint indicator /\ 4563 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 4564 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 4565 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f))); 4566 4567 4568 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 4569 fdiBounds.union(fdiTop.x, fdiTop.y); 4570 fdiBounds.union(fdiRight.x, fdiRight.y); 4571 4572 float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f); 4573 RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2)); 4574 4575 ti = new TextInfo("TEST",0,0, modifierFont, modifierFontName); 4576 if (ti != null) 4577 { 4578 int shiftY = Math.round(symbolBounds.top - ti.getTextBounds().height() - 2); 4579 fdiLeft.offset(0, shiftY); 4580 fdiTop.offset(0, shiftY); 4581 fdiRight.offset(0, shiftY); 4582 fdiBounds.offset(0, shiftY); 4583 } 4584 4585 imageBounds.union(fdiBounds); 4586 4587 } 4588 // </editor-fold> 4589 } 4590 4591 // </editor-fold> 4592 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 4593 Rect modifierBounds = null; 4594 if (arrMods != null && arrMods.size() > 0) 4595 { 4596 4597 //build modifier bounds///////////////////////////////////////// 4598 modifierBounds = arrMods.get(0).getTextOutlineBounds(); 4599 int size = arrMods.size(); 4600 TextInfo tempShape = null; 4601 for (int i = 1; i < size; i++) 4602 { 4603 tempShape = arrMods.get(i); 4604 modifierBounds.union(tempShape.getTextOutlineBounds()); 4605 } 4606 4607 } 4608 4609 if(fdiBounds != null) 4610 { 4611 if(modifierBounds != null) 4612 modifierBounds.union(fdiBounds); 4613 else 4614 modifierBounds = fdiBounds; 4615 } 4616 4617 if (modifierBounds != null) 4618 { 4619 4620 imageBounds.union(modifierBounds); 4621 4622 //shift points if needed//////////////////////////////////////// 4623 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4624 { 4625 int shiftX = Math.abs(imageBounds.left); 4626 int shiftY = Math.abs(imageBounds.top); 4627 4628 //shift mobility points 4629 int size = arrMods.size(); 4630 TextInfo tempShape = null; 4631 for (int i = 0; i < size; i++) 4632 { 4633 tempShape = arrMods.get(i); 4634 tempShape.shift(shiftX, shiftY); 4635 } 4636 modifierBounds.offset(shiftX, shiftY); 4637 4638 //shift image points 4639 centerPoint.offset(shiftX, shiftY); 4640 symbolBounds.offset(shiftX, shiftY); 4641 imageBounds.offset(shiftX, shiftY); 4642 4643 //If there's an FDI 4644 if (fdiBounds != null) 4645 { 4646 fdiBounds.offset(shiftX, shiftY); 4647 fdiLeft.offset(shiftX, shiftY); 4648 fdiTop.offset(shiftX, shiftY); 4649 fdiRight.offset(shiftX, shiftY); 4650 } 4651 } 4652 4653 if (attributes.containsKey(MilStdAttributes.TextColor)) 4654 { 4655 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4656 if(alpha > -1) 4657 textColor.setAlpha(alpha); 4658 } 4659 if (attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4660 { 4661 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4662 if(alpha > -1) 4663 textBackgroundColor.setAlpha(alpha); 4664 } 4665 4666 if(sdi instanceof ImageInfo) 4667 { 4668 ii = (ImageInfo) sdi; 4669 //Render modifiers////////////////////////////////////////////////// 4670 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 4671 Canvas ctx = new Canvas(bmp); 4672 4673 //draw original icon with potential modifiers. 4674 ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null); 4675 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 4676 4677 4678 renderText(ctx, arrMods, textColor, textBackgroundColor, modifierFont); 4679 4680 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4681 if (fdiBounds != null) { 4682 4683 Paint fdiPaint = new Paint(); 4684 fdiPaint.setAntiAlias(true); 4685 fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 4686 if (alpha > -1) 4687 fdiPaint.setAlpha(alpha); 4688 fdiPaint.setStyle(Style.STROKE); 4689 4690 int dpi = RendererSettings.getInstance().getDeviceDPI(); 4691 int lineLength = dpi / 96 * 6; 4692 int lineGap = dpi / 96 * 4; 4693 4694 /// /////////////////////////////////// 4695 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4696 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4697 //distance = distance / 14f; 4698 lineGap = (int)((distance / 14f) * 2); 4699 lineLength = (int)((distance / 14f) * 3); 4700 /// ////////////////////////////////// 4701 4702 fdiPaint.setPathEffect(new DashPathEffect(new float[] 4703 { 4704 lineLength, lineGap 4705 }, 0)); 4706 4707 float fdiStrokeWidth = Math.round(dpi / 96f); 4708 if (fdiStrokeWidth < 2) 4709 fdiStrokeWidth = 2; 4710 4711 fdiPaint.setStrokeCap(Cap.ROUND); 4712 fdiPaint.setStrokeJoin(Join.MITER); 4713 fdiPaint.setStrokeWidth(fdiStrokeWidth); 4714 4715 Path fdiPath = new Path(); 4716 4717 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4718 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4719 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4720 fdiPath.lineTo(fdiRight.x, fdiRight.y); 4721 ctx.drawPath(fdiPath, fdiPaint); 4722 4723 fdiBounds = null; 4724 4725 } 4726 //</editor-fold> 4727 4728 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 4729 } 4730 else if(sdi instanceof SVGSymbolInfo) 4731 { 4732 String svgStroke = RendererUtilities.colorToHexString(lineColor,false); 4733 String svgStrokeWidth = "3"; 4734 String svgAlpha = null; 4735 if(alpha > -1) 4736 svgAlpha = String.valueOf(alpha); 4737 ssi = (SVGSymbolInfo)sdi; 4738 StringBuilder sbSVG = new StringBuilder(); 4739 sbSVG.append(ssi.getSVG()); 4740 sbSVG.append(renderTextElements(arrMods,textColor,textBackgroundColor)); 4741 4742 //<editor-fold defaultstate="collapsed" desc="Draw FDI"> 4743 if (fdiBounds != null) 4744 { 4745 /*int dpi = RendererSettings.getInstance().getDeviceDPI(); 4746 int lineLength = dpi / 96 * 6; 4747 int lineGap = dpi / 96 * 4; 4748 String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/ 4749 4750 /// /////////////////////////////////// 4751 //Divide line in 14 parts. line is 3 parts to 2 parts gap 4752 float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft); 4753 //distance = distance / 14f; 4754 int lineGap = (int)((distance / 14f) * 2); 4755 int lineLength = (int)((distance / 14f) * 3); 4756 String svgFDIDashArray = "" + lineLength + " " + lineGap; 4757 /// ////////////////////////////////// 4758 4759 SVGPath fdiPath = new SVGPath(); 4760 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4761 fdiPath.lineTo(fdiLeft.x, fdiLeft.y); 4762 fdiPath.moveTo(fdiTop.x, fdiTop.y); 4763 fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/ 4764 4765 fdiPath.setLineDash(svgFDIDashArray); 4766 sbSVG.append(fdiPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,"round")); 4767 //sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray)); 4768 } 4769 //</editor-fold> 4770 4771 newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds); 4772 } 4773 4774 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 4775 //ctx = null; 4776 4777 // </editor-fold> 4778 } 4779 // </editor-fold> 4780 return newsdi; 4781 4782 } 4783 4784 private static SymbolDimensionInfo shiftUnitPointsAndDraw(ArrayList<TextInfo> tiArray, SymbolDimensionInfo sdi, Map<String,String> attributes, Paint modifierFont) 4785 { 4786 4787 ImageInfo ii = null; 4788 SVGSymbolInfo ssi = null; 4789 SymbolDimensionInfo newsdi = null; 4790 4791 int alpha = -1; 4792 4793 4794 if (attributes != null && attributes.containsKey(MilStdAttributes.Alpha)) 4795 { 4796 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 4797 } 4798 4799 Color textColor = Color.BLACK; 4800 Color textBackgroundColor = null; 4801 4802 Rect symbolBounds = new Rect(sdi.getSymbolBounds()); 4803 Point centerPoint = new Point(sdi.getCenterPoint()); 4804 Rect imageBounds = new Rect(sdi.getImageBounds()); 4805 Rect imageBoundsOld = new Rect(sdi.getImageBounds()); 4806 4807 Rect modifierBounds = null; 4808 if (tiArray != null && tiArray.size() > 0) 4809 { 4810 4811 //build modifier bounds///////////////////////////////////////// 4812 modifierBounds = tiArray.get(0).getTextOutlineBounds(); 4813 int size = tiArray.size(); 4814 TextInfo tempShape = null; 4815 for (int i = 1; i < size; i++) 4816 { 4817 tempShape = tiArray.get(i); 4818 modifierBounds.union(tempShape.getTextOutlineBounds()); 4819 } 4820 4821 } 4822 4823 if (modifierBounds != null) 4824 { 4825 4826 imageBounds.union(modifierBounds); 4827 4828 //shift points if needed//////////////////////////////////////// 4829 if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0)) 4830 { 4831 int shiftX = Math.round(Math.abs(imageBounds.left)), 4832 shiftY = Math.round(Math.abs(imageBounds.top)); 4833 4834 //shift mobility points 4835 int size = tiArray.size(); 4836 TextInfo tempShape = null; 4837 for (int i = 0; i < size; i++) 4838 { 4839 tempShape = tiArray.get(i); 4840 tempShape.shift(shiftX, shiftY); 4841 } 4842 RectUtilities.shift(modifierBounds, shiftX, shiftY); 4843 //modifierBounds.shift(shiftX,shiftY); 4844 4845 //shift image points 4846 centerPoint.offset(shiftX, shiftY); 4847 RectUtilities.shift(symbolBounds, shiftX, shiftY); 4848 RectUtilities.shift(imageBounds, shiftX, shiftY); 4849 RectUtilities.shift(imageBoundsOld, shiftX, shiftY); 4850 /*centerPoint.shift(shiftX, shiftY); 4851 symbolBounds.shift(shiftX, shiftY); 4852 imageBounds.shift(shiftX, shiftY); 4853 imageBoundsOld.shift(shiftX, shiftY);//*/ 4854 } 4855 4856 if (attributes != null && attributes.containsKey(MilStdAttributes.TextColor)) 4857 { 4858 textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 4859 if(alpha > -1) 4860 textColor.setAlpha(alpha); 4861 } 4862 if (attributes != null && attributes.containsKey(MilStdAttributes.TextBackgroundColor)) 4863 { 4864 textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 4865 if(alpha > -1) 4866 textBackgroundColor.setAlpha(alpha); 4867 } 4868 4869 if(sdi instanceof ImageInfo) 4870 { 4871 ii = (ImageInfo) sdi; 4872 4873 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 4874 Canvas ctx = new Canvas(bmp); 4875 4876 //render//////////////////////////////////////////////////////// 4877 //draw original icon with potential modifiers. 4878 ctx.drawBitmap(ii.getImage(), imageBoundsOld.left, imageBoundsOld.top, null); 4879 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 4880 4881 renderText(ctx, tiArray, textColor, textBackgroundColor, modifierFont); 4882 4883 newsdi = new ImageInfo(bmp, centerPoint, symbolBounds); 4884 } 4885 else if(sdi instanceof SVGSymbolInfo) 4886 { 4887 ssi = (SVGSymbolInfo)sdi; 4888 StringBuilder sb = new StringBuilder(); 4889 sb.append(ssi.getSVG()); 4890 sb.append(renderTextElements(tiArray,textColor,textBackgroundColor)); 4891 newsdi = new SVGSymbolInfo(sb.toString(),centerPoint,symbolBounds,imageBounds); 4892 } 4893 } 4894 4895 if(newsdi == null) 4896 newsdi = sdi; 4897 4898 return newsdi; 4899 } 4900 private static String renderTextElement(ArrayList<TextInfo> tiArray, Color color, Color backgroundColor) 4901 { 4902 StringBuilder sbSVG = new StringBuilder(); 4903 4904 String svgStroke = RendererUtilities.colorToHexString(RendererUtilities.getIdealOutlineColor(color),false); 4905 if(backgroundColor != null) 4906 svgStroke = RendererUtilities.colorToHexString(backgroundColor,false); 4907 4908 String svgFill = RendererUtilities.colorToHexString(color,false); 4909 String svgStrokeWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth()); 4910 for (TextInfo ti : tiArray) { 4911 sbSVG.append(Shape2SVG.Convert(ti, svgStroke,svgFill,svgStrokeWidth,null,null,null)); 4912 sbSVG.append("\n"); 4913 } 4914 4915 return sbSVG.toString(); 4916 } 4917 4918 private static String renderTextElements(ArrayList<TextInfo> tiArray, Color color, Color backgroundColor) 4919 { 4920 String style = null; 4921 String name = tiArray.get(0).getFontName();//"SansSerif"; 4922 if(!name.endsWith("serif")) 4923 name += ", sans-serif"; 4924 String size = String.valueOf(tiArray.get(0).getFontSize()); 4925 String weight = null; 4926 String anchor = null;//"start"; 4927 if(tiArray.get(0).getFontStyle() == Typeface.BOLD) 4928 weight = "bold"; 4929 StringBuilder sbSVG = new StringBuilder(); 4930 4931 String svgStroke = RendererUtilities.colorToHexString(RendererUtilities.getIdealOutlineColor(color),false); 4932 if(backgroundColor != null) 4933 svgStroke = RendererUtilities.colorToHexString(backgroundColor,false); 4934 4935 String svgFill = RendererUtilities.colorToHexString(color,false); 4936 String svgStrokeWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth()); 4937 sbSVG.append("\n<g"); 4938 sbSVG.append(" font-family=\"").append(name).append('"'); 4939 sbSVG.append(" font-size=\"").append(size).append("px\""); 4940 if(weight != null) 4941 sbSVG.append(" font-weight=\"").append(weight).append("\""); 4942 sbSVG.append(" alignment-baseline=\"alphabetic\"");// 4943 sbSVG.append(">"); 4944 4945 for (TextInfo ti : tiArray) { 4946 sbSVG.append(Shape2SVG.ConvertForGroup(ti, svgStroke,svgFill,svgStrokeWidth,null,null,null)); 4947 sbSVG.append("\n"); 4948 } 4949 sbSVG.append("</g>\n"); 4950 4951 return sbSVG.toString(); 4952 } 4953 private static void renderText(Canvas ctx, ArrayList<TextInfo> tiArray, Color color, Color backgroundColor, Paint font) 4954 { 4955 ModifierRenderer.renderText(ctx, (TextInfo[]) tiArray.toArray(new TextInfo[0]), color, backgroundColor, font); 4956 } 4957 4958 /** 4959 * 4960 * @param ctx 4961 * @param tiArray 4962 * @param color 4963 * @param backgroundColor 4964 */ 4965 public static void renderText(Canvas ctx, TextInfo[] tiArray, Color color, Color backgroundColor, Paint modifierFont) 4966 { 4967 /*for (TextInfo textInfo : tiArray) 4968 { 4969 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 4970 }*/ 4971 4972 int size = tiArray.length; 4973 4974 int tbm = RS.getTextBackgroundMethod(); 4975 int outlineWidth = RS.getTextOutlineWidth(); 4976 4977 if (color == null) 4978 { 4979 color = Color.BLACK; 4980 } 4981 4982 Color outlineColor = null; 4983 4984 if(backgroundColor != null) 4985 outlineColor = backgroundColor; 4986 else 4987 outlineColor = RendererUtilities.getIdealOutlineColor(color); 4988 4989 if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE_QUICK) 4990 { 4991 synchronized (modifierFontMutex) { 4992 //draw text outline 4993 modifierFont.setStyle(Style.FILL); 4994 modifierFont.setStrokeWidth(RS.getTextOutlineWidth()); 4995 modifierFont.setColor(outlineColor.toInt()); 4996 4997 if (outlineWidth > 2) 4998 outlineWidth = 2; 4999 5000 if (outlineWidth > 0) { 5001 for (int i = 0; i < size; i++) { 5002 TextInfo textInfo = tiArray[i]; 5003 if (outlineWidth > 0) { 5004 for (int j = 1; j <= outlineWidth; j++) { 5005 if (j == 1) { 5006 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, modifierFont); 5007 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, modifierFont); 5008 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, modifierFont); 5009 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, modifierFont); 5010 5011 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, modifierFont); 5012 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, modifierFont); 5013 5014 } else { 5015 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, modifierFont); 5016 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, modifierFont); 5017 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, modifierFont); 5018 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, modifierFont); 5019 5020 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, modifierFont); 5021 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, modifierFont); 5022 5023 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y + j, modifierFont); 5024 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y - j, modifierFont); 5025 } 5026 5027 } 5028 5029 } 5030 5031 } 5032 } 5033 //draw text 5034 modifierFont.setColor(color.toInt()); 5035 5036 for (int j = 0; j < size; j++) { 5037 TextInfo textInfo = tiArray[j]; 5038 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5039 /*Paint outline = new Paint(); 5040 outline.setStyle(Style.STROKE); 5041 outline.setColor(Color.red.toInt()); 5042 outline.setAlpha(155); 5043 outline.setStrokeWidth(1f); 5044 ctx.drawRect(textInfo.getTextBounds(), outline); 5045 outline.setColor(Color.blue.toInt()); 5046 ctx.drawRect(textInfo.getTextOutlineBounds(), outline);//*/ 5047 } 5048 } 5049 } 5050 else if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE) 5051 { 5052 synchronized (modifierFontMutex) { 5053 //draw text outline 5054 //draw text outline 5055 modifierFont.setStyle(Style.STROKE); 5056 modifierFont.setStrokeWidth(RS.getTextOutlineWidth()); 5057 modifierFont.setColor(outlineColor.toInt()); 5058 if (outlineWidth > 0) { 5059 for (int i = 0; i < size; i++) { 5060 TextInfo textInfo = tiArray[i]; 5061 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5062 } 5063 } 5064 //draw text 5065 modifierFont.setColor(color.toInt()); 5066 modifierFont.setStyle(Style.FILL); 5067 for (int j = 0; j < size; j++) { 5068 TextInfo textInfo = tiArray[j]; 5069 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5070 } 5071 } 5072 } 5073 else if (tbm == RendererSettings.TextBackgroundMethod_COLORFILL) 5074 { 5075 synchronized (modifierFontMutex) { 5076 Paint rectFill = new Paint(); 5077 rectFill.setStyle(Paint.Style.FILL); 5078 rectFill.setColor(outlineColor.toARGB()); 5079 5080 5081 //draw rectangle 5082 for (int k = 0; k < size; k++) { 5083 TextInfo textInfo = tiArray[k]; 5084 ctx.drawRect(textInfo.getTextOutlineBounds(), rectFill); 5085 } 5086 //draw text 5087 modifierFont.setColor(color.toInt()); 5088 modifierFont.setStyle(Style.FILL); 5089 for (int j = 0; j < size; j++) { 5090 TextInfo textInfo = tiArray[j]; 5091 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5092 } 5093 } 5094 } 5095 else if (tbm == RendererSettings.TextBackgroundMethod_NONE) 5096 { 5097 synchronized (modifierFontMutex) { 5098 modifierFont.setColor(color.toInt()); 5099 modifierFont.setStyle(Style.FILL); 5100 for (int j = 0; j < size; j++) { 5101 TextInfo textInfo = tiArray[j]; 5102 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, modifierFont); 5103 } 5104 } 5105 } 5106 } 5107 5108 /** 5109 * 5110 * @param symbolID 5111 * @param modifiers 5112 * @return int[] where {xposition (-1 left, 0 centered, 1 right), yposition (0 centered, 1+ goes up, 1- goes down), 5113 * centered (0-no, 1-yes)} -999 means passed modifier is not supported by this symbol 5114 */ 5115 private static List<Modifier> getLabelPositionIndexes(String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 5116 { 5117 List<Modifier> mods = null; 5118 if(modifiers != null && !modifiers.isEmpty()) 5119 mods = new ArrayList<>(); 5120 else 5121 return null; 5122 5123 int ver = SymbolID.getVersion(symbolID); 5124 int ss = SymbolID.getSymbolSet(symbolID); 5125 int x = 0; 5126 int y = 0; 5127 boolean centered = true; 5128 int p = RendererSettings.getInstance().getSPModifierPlacement(); 5129 boolean strict = (RendererSettings.getInstance().getSPModifierPlacement() == RendererSettings.ModifierPlacement_STRICT); 5130 if(attributes != null && attributes.containsKey(MilStdAttributes.ModifierPlacement)) 5131 { 5132 String mp = attributes.get(MilStdAttributes.ModifierPlacement); 5133 if(mp.equals("0") || mp.equals("1") || mp.equals("2")) 5134 { 5135 p = Integer.parseInt(mp); 5136 if(p == 0) 5137 strict = true; 5138 else 5139 strict = false; 5140 } 5141 } 5142 String temp = null; 5143 String sep = " "; 5144 if(ss == SymbolID.SymbolSet_DismountedIndividuals) { 5145 ver = SymbolID.Version_2525E; 5146 } 5147 5148 if(ver < SymbolID.Version_2525E) 5149 { 5150 if(ss == SymbolID.SymbolSet_LandUnit || 5151 ss == SymbolID.SymbolSet_LandCivilianUnit_Organization) 5152 { 5153 //Do top center label 5154 x = 0;//centered 5155 y = 9;//on top of symbol 5156 if(modifiers.containsKey(Modifiers.B_ECHELON)) 5157 { 5158 temp = modifiers.get(Modifiers.B_ECHELON); 5159 if(temp != null && !temp.isEmpty()) 5160 mods.add(new Modifier("B", temp, x, y, centered)); 5161 } 5162 5163 //Do right side labels 5164 x = 1;//on right 5165 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5166 { 5167 y = 0;//center 5168 centered = true;//vertically centered, only matters for labels on left and right side 5169 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5170 if(temp != null && !temp.isEmpty()) 5171 mods.add(new Modifier("H", temp, x, y, centered)); 5172 } 5173 else if(!strict) 5174 { 5175 //if no "H', bring G and M closer to the center 5176 centered = false; 5177 } 5178 5179 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5180 { 5181 y = 1;//above center 5182 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5183 if(temp != null && !temp.isEmpty()) 5184 mods.add(new Modifier("G", temp, x, y, centered)); 5185 } 5186 5187 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 5188 { 5189 y = 2; 5190 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5191 y--; 5192 temp = ""; 5193 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 5194 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 5195 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5196 temp += modifiers.get(Modifiers.AS_COUNTRY); 5197 temp = temp.trim(); 5198 if(temp != null && !temp.isEmpty()) 5199 mods.add(new Modifier("F AS", temp, x, y, centered)); 5200 } 5201 5202 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 5203 { 5204 y = -1;//below center 5205 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 5206 if(temp != null && !temp.isEmpty()) 5207 mods.add(new Modifier("M", temp, x, y, centered)); 5208 } 5209 5210 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5211 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 5212 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5213 { 5214 y = -2; 5215 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 5216 y++; 5217 temp = ""; 5218 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5219 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5220 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 5221 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 5222 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5223 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5224 temp = temp.trim(); 5225 if(temp != null && !temp.isEmpty()) 5226 mods.add(new Modifier("J K P", temp, x, y, centered)); 5227 } 5228 5229 //Do left side labels 5230 x = -1;//on left 5231 centered = false; 5232 5233 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5234 { 5235 y = 1; 5236 temp = ""; 5237 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5238 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5239 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5240 temp += modifiers.get(Modifiers.Y_LOCATION); 5241 5242 temp = temp.trim(); 5243 if(temp != null && !temp.isEmpty()) 5244 mods.add(new Modifier("X Y", temp, x, y, centered)); 5245 } 5246 5247 if(modifiers.containsKey(Modifiers.W_DTG_1)) 5248 { 5249 y = 2;//above center 5250 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 5251 y--; 5252 temp = modifiers.get(Modifiers.W_DTG_1); 5253 if(temp != null && !temp.isEmpty()) 5254 mods.add(new Modifier("W", temp, x, y, centered)); 5255 } 5256 5257 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5258 { 5259 y = -1;//below center 5260 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5261 if(temp != null && !temp.isEmpty()) 5262 mods.add(new Modifier("T", temp, x, y, centered)); 5263 } 5264 5265 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5266 { 5267 y = -2; 5268 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5269 y++; 5270 temp = modifiers.get(Modifiers.Z_SPEED); 5271 if(temp != null && !temp.isEmpty()) 5272 mods.add(new Modifier(Modifiers.J_EVALUATION_RATING, temp, x, y, centered)); 5273 } 5274 } 5275 else if(ss == SymbolID.SymbolSet_LandEquipment || 5276 ss == SymbolID.SymbolSet_SignalsIntelligence_Land) 5277 { 5278 //Do top center label 5279 x = 0;//centered 5280 y = 9;//on top of symbol 5281 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 5282 { 5283 temp = modifiers.get(Modifiers.C_QUANTITY); 5284 if(temp != null && !temp.isEmpty()) 5285 mods.add(new Modifier("C", temp, x, y, centered)); 5286 } 5287 5288 //Do right side labels 5289 x = 1;//on right 5290 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 5291 { 5292 y = 0;//center 5293 centered = true;//vertically centered, only matters for labels on left and right side 5294 temp = ""; 5295 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5296 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 5297 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 5298 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 5299 temp = temp.trim(); 5300 if(temp != null && !temp.isEmpty()) 5301 mods.add(new Modifier("H AF", temp, x, y, centered)); 5302 } 5303 else if(!strict) 5304 { 5305 //if no "H', bring G and M closer to the center 5306 centered = false; 5307 } 5308 5309 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5310 { 5311 y = 1;//above center 5312 temp = ""; 5313 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5314 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5315 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5316 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 5317 temp = temp.trim(); 5318 if(temp != null && !temp.isEmpty()) 5319 mods.add(new Modifier("G AQ", temp, x, y, centered)); 5320 } 5321 5322 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5323 { 5324 y = 2; 5325 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 5326 y--; 5327 5328 temp = modifiers.get(Modifiers.AS_COUNTRY); 5329 if(temp != null && !temp.isEmpty()) 5330 mods.add(new Modifier("AS", temp, x, y, centered)); 5331 } 5332 5333 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5334 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 5335 modifiers.containsKey(Modifiers.N_HOSTILE) || 5336 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5337 { 5338 y = -1; 5339 5340 temp = ""; 5341 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5342 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5343 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 5344 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 5345 if(modifiers.containsKey(Modifiers.N_HOSTILE)) 5346 temp += modifiers.get(Modifiers.N_HOSTILE) + sep; 5347 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5348 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5349 temp = temp.trim(); 5350 if(temp != null && !temp.isEmpty()) 5351 mods.add(new Modifier("J L N P", temp, x, y, centered)); 5352 } 5353 5354 //Do left side labels 5355 x = -1;//on left 5356 5357 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 5358 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 5359 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 5360 { 5361 y = 0;//center 5362 centered = true;//vertically centered, only matters for labels on left and right side 5363 5364 temp = ""; 5365 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5366 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 5367 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 5368 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 5369 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 5370 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 5371 temp = temp.trim(); 5372 if(temp != null && !temp.isEmpty()) 5373 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 5374 } 5375 else if(!strict) 5376 { 5377 centered = false; 5378 } 5379 5380 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5381 { 5382 y = 1; 5383 temp = ""; 5384 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5385 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5386 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5387 temp += modifiers.get(Modifiers.Y_LOCATION); 5388 5389 temp = temp.trim(); 5390 mods.add(new Modifier("X Y", temp, x, y, centered)); 5391 } 5392 5393 if(modifiers.containsKey(Modifiers.W_DTG_1) || modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5394 { 5395 y = 2;//above center 5396 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 5397 y--; 5398 5399 temp = modifiers.get(Modifiers.W_DTG_1); 5400 5401 if(temp != null && !temp.isEmpty()) 5402 mods.add(new Modifier("W", temp, x, y, centered)); 5403 } 5404 5405 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5406 { 5407 y = -1;//below center 5408 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5409 if(temp != null && !temp.isEmpty()) 5410 mods.add(new Modifier("T", temp, x, y, centered)); 5411 } 5412 5413 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5414 { 5415 y = -2; 5416 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5417 y++; 5418 temp = modifiers.get(Modifiers.Z_SPEED); 5419 if(temp != null && !temp.isEmpty()) 5420 mods.add(new Modifier("Z", temp, x, y, centered)); 5421 } 5422 } 5423 else if(ss == SymbolID.SymbolSet_LandInstallation) 5424 { 5425 //No top center label 5426 5427 //Do right side labels 5428 x = 1;//on right 5429 5430 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5431 { 5432 y = 0;//center 5433 centered = true;//vertically centered, only matters for labels on left and right side 5434 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5435 5436 if(temp != null && !temp.isEmpty()) 5437 mods.add(new Modifier("H", temp, x, y, centered)); 5438 } 5439 else if(!strict) 5440 { 5441 centered = false; 5442 } 5443 5444 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5445 { 5446 y = 1;//above center 5447 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5448 5449 if(temp != null && !temp.isEmpty()) 5450 mods.add(new Modifier("G", temp, x, y, centered)); 5451 } 5452 5453 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5454 { 5455 y = 2; 5456 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5457 y--; 5458 5459 temp = modifiers.get(Modifiers.AS_COUNTRY); 5460 if(temp != null && !temp.isEmpty()) 5461 mods.add(new Modifier("AS", temp, x, y, centered)); 5462 } 5463 5464 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 5465 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 5466 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5467 { 5468 y = -1; 5469 5470 temp = ""; 5471 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5472 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 5473 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 5474 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 5475 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5476 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 5477 temp = temp.trim(); 5478 mods.add(new Modifier("J K P", temp, x, y, centered)); 5479 } 5480 5481 //Do left side labels 5482 x = -1;//on left 5483 5484 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 5485 { 5486 y = 0;//center 5487 centered = true;//vertically centered, only matters for labels on left and right side 5488 5489 temp = ""; 5490 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5491 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 5492 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5493 temp += modifiers.get(Modifiers.Y_LOCATION); 5494 temp = temp.trim(); 5495 if(temp != null && !temp.isEmpty()) 5496 mods.add(new Modifier("X Y", temp, x, y, centered)); 5497 } 5498 else if(!strict) 5499 { 5500 centered = false; 5501 } 5502 5503 if(modifiers.containsKey(Modifiers.W_DTG_1)) 5504 { 5505 y = 1;//above center 5506 5507 temp = modifiers.get(Modifiers.W_DTG_1); 5508 5509 if(temp != null && !temp.isEmpty()) 5510 mods.add(new Modifier("W AR", temp, x, y, centered)); 5511 } 5512 5513 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5514 { 5515 y = -1;//below center 5516 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5517 if(temp != null && !temp.isEmpty()) 5518 mods.add(new Modifier("T", temp, x, y, centered)); 5519 } 5520 } 5521 else if(ss == SymbolID.SymbolSet_Air || 5522 ss == SymbolID.SymbolSet_AirMissile || 5523 ss == SymbolID.SymbolSet_SignalsIntelligence_Air) 5524 { 5525 //No top center label 5526 5527 5528 //Do right side labels 5529 x = 1;//on right 5530 centered = false; 5531 5532 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5533 { 5534 y = 1;//above center 5535 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 5536 5537 if(temp != null && !temp.isEmpty()) 5538 mods.add(new Modifier("P", temp, x, y, centered)); 5539 } 5540 5541 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5542 { 5543 y = 2; 5544 if(!strict && !modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5545 y--; 5546 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5547 5548 if(temp != null && !temp.isEmpty()) 5549 mods.add(new Modifier("T", temp, x, y, centered)); 5550 } 5551 5552 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5553 { 5554 y = 3; 5555 if(!strict) 5556 { 5557 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5558 y--; 5559 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5560 y--; 5561 } 5562 5563 temp = modifiers.get(Modifiers.AS_COUNTRY ); 5564 5565 if(temp != null && !temp.isEmpty()) 5566 mods.add(new Modifier("AS", temp, x, y, centered)); 5567 } 5568 5569 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5570 { 5571 y = -1;//below center 5572 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5573 5574 if(temp != null && !temp.isEmpty()) 5575 mods.add(new Modifier("V", temp, x, y, centered)); 5576 } 5577 5578 if(modifiers.containsKey(Modifiers.Z_SPEED) || 5579 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5580 { 5581 y = -2;//below center 5582 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5583 y++; 5584 5585 temp = ""; 5586 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5587 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 5588 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5589 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5590 temp = temp.trim(); 5591 5592 if(temp != null && !temp.isEmpty()) 5593 mods.add(new Modifier("Z X", temp, x, y, centered)); 5594 } 5595 5596 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5597 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5598 { 5599 y = -3; 5600 if(!strict) 5601 { 5602 if(!(modifiers.containsKey(Modifiers.Z_SPEED) || 5603 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5604 y++; 5605 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5606 y++; 5607 } 5608 temp = ""; 5609 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5610 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5611 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5612 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5613 temp = temp.trim(); 5614 if(temp != null && !temp.isEmpty()) 5615 mods.add(new Modifier("G H", temp, x, y, centered)); 5616 } 5617 5618 //No left side labels 5619 5620 } 5621 else if(ss == SymbolID.SymbolSet_Space || 5622 ss == SymbolID.SymbolSet_SpaceMissile || 5623 ss == SymbolID.SymbolSet_SignalsIntelligence_Space) 5624 { 5625 //No top center label 5626 5627 5628 //Do right side labels 5629 x = 1;//on right 5630 centered = false; 5631 5632 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5633 { 5634 y = 1;//above center 5635 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5636 if(temp != null && !temp.isEmpty()) 5637 mods.add(new Modifier("V", temp, x, y, centered)); 5638 } 5639 5640 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5641 { 5642 y = 2; 5643 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5644 y--; 5645 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5646 5647 if(temp != null && !temp.isEmpty()) 5648 mods.add(new Modifier("T", temp, x, y, centered)); 5649 } 5650 5651 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5652 { 5653 y = 3; 5654 if(!strict) 5655 { 5656 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5657 y--; 5658 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5659 y--; 5660 } 5661 5662 temp = modifiers.get(Modifiers.AS_COUNTRY ); 5663 5664 if(temp != null && !temp.isEmpty()) 5665 mods.add(new Modifier("AS", temp, x, y, centered)); 5666 } 5667 5668 if(modifiers.containsKey(Modifiers.Z_SPEED) || 5669 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5670 { 5671 y = -1;//below center 5672 temp = ""; 5673 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5674 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 5675 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5676 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5677 temp = temp.trim(); 5678 5679 if(temp != null && !temp.isEmpty()) 5680 mods.add(new Modifier("Z X", temp, x, y, centered)); 5681 } 5682 5683 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5684 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5685 { 5686 y = -2; 5687 if(!strict && 5688 !(modifiers.containsKey(Modifiers.Z_SPEED) || modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5689 y++; 5690 temp = ""; 5691 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5692 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5693 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5694 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5695 temp = temp.trim(); 5696 if(temp != null && !temp.isEmpty()) 5697 mods.add(new Modifier("G H", temp, x, y, centered)); 5698 } 5699 5700 //No left side labels 5701 } 5702 else if(ss == SymbolID.SymbolSet_SeaSurface || 5703 ss == SymbolID.SymbolSet_SignalsIntelligence_SeaSurface) 5704 { 5705 //No top center label 5706 5707 5708 //Do right side labels 5709 x = 1;//on right 5710 centered = true; 5711 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5712 { 5713 y = 0;//center 5714 centered = true;//vertically centered, only matters for labels on left and right side 5715 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5716 if(temp != null && !temp.isEmpty()) 5717 mods.add(new Modifier("V", temp, x, y, centered)); 5718 } 5719 else if(!strict) 5720 { 5721 //if no "H', bring G and M closer to the center 5722 centered = false; 5723 } 5724 5725 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5726 { 5727 y = 1;//above center 5728 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 5729 if(temp != null && !temp.isEmpty()) 5730 mods.add(new Modifier("P", temp, x, y, centered)); 5731 } 5732 5733 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5734 { 5735 y = 2; 5736 if(!strict && !modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 5737 y--; 5738 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5739 5740 if(temp != null && !temp.isEmpty()) 5741 mods.add(new Modifier("T", temp, x, y, centered)); 5742 } 5743 5744 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5745 { 5746 y = 3; 5747 if(!strict) 5748 { 5749 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5750 y--; 5751 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5752 y--; 5753 } 5754 5755 temp = modifiers.get(Modifiers.AS_COUNTRY ); 5756 5757 if(temp != null && !temp.isEmpty()) 5758 mods.add(new Modifier("AS", temp, x, y, centered)); 5759 } 5760 5761 if(modifiers.containsKey(Modifiers.Z_SPEED) || 5762 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5763 { 5764 y = -1;//below center 5765 temp = ""; 5766 if(modifiers.containsKey(Modifiers.Z_SPEED)) 5767 temp = modifiers.get(Modifiers.Z_SPEED) + sep; 5768 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5769 temp += modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5770 temp = temp.trim(); 5771 5772 if(temp != null && !temp.isEmpty()) 5773 mods.add(new Modifier("Z X", temp, x, y, centered)); 5774 } 5775 5776 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 5777 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5778 { 5779 y = -2; 5780 if(!strict && 5781 !(modifiers.containsKey(Modifiers.Z_SPEED) || modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5782 y++; 5783 temp = ""; 5784 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5785 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 5786 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5787 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5788 temp = temp.trim(); 5789 if(temp != null && !temp.isEmpty()) 5790 mods.add(new Modifier("G H", temp, x, y, centered)); 5791 } 5792 5793 //Do left side labels 5794 x = -1; 5795 centered = false; 5796 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) || modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5797 { 5798 y = 3;//above center 5799 if(!strict) 5800 y--; 5801 5802 temp = ""; 5803 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 5804 temp = modifiers.get(Modifiers.AQ_GUARDED_UNIT) + sep; 5805 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5806 temp += modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 5807 temp = temp.trim(); 5808 5809 if(temp != null && !temp.isEmpty()) 5810 mods.add(new Modifier("AQ AR", temp, x, y, centered)); 5811 } 5812 } 5813 else if(ss == SymbolID.SymbolSet_SeaSubsurface || 5814 ss == SymbolID.SymbolSet_SignalsIntelligence_SeaSubsurface) 5815 { 5816 //No top center label 5817 5818 5819 //Do right side labels 5820 x = 1;//on right 5821 centered = false; 5822 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5823 { 5824 y = 1;//center 5825 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 5826 if(temp != null && !temp.isEmpty()) 5827 mods.add(new Modifier("V", temp, x, y, centered)); 5828 } 5829 5830 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5831 { 5832 y = 2; 5833 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5834 y--; 5835 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 5836 5837 if(temp != null && !temp.isEmpty()) 5838 mods.add(new Modifier("T", temp, x, y, centered)); 5839 } 5840 5841 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5842 { 5843 y = 3; 5844 if(!strict) 5845 { 5846 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 5847 y--; 5848 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 5849 y--; 5850 } 5851 5852 temp = modifiers.get(Modifiers.AS_COUNTRY ); 5853 5854 if(temp != null && !temp.isEmpty()) 5855 mods.add(new Modifier("AS", temp, x, y, centered)); 5856 } 5857 5858 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5859 { 5860 y = -1;//below center 5861 5862 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 5863 5864 if(temp != null && !temp.isEmpty()) 5865 mods.add(new Modifier("X", temp, x, y, centered)); 5866 } 5867 5868 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5869 { 5870 y = -2; 5871 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))) 5872 y++; 5873 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5874 5875 if(temp != null && !temp.isEmpty()) 5876 mods.add(new Modifier("G", temp, x, y, centered)); 5877 } 5878 5879 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5880 { 5881 y = -3;//below center 5882 if(!strict) 5883 { 5884 if(!modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5885 y++; 5886 if(!modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 5887 y++; 5888 } 5889 5890 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5891 5892 if(temp != null && !temp.isEmpty()) 5893 mods.add(new Modifier("H", temp, x, y, centered)); 5894 } 5895 5896 //Do left side labels 5897 x = -1; 5898 centered = false; 5899 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 5900 { 5901 y = 3;//above center 5902 if(!strict) 5903 { 5904 y--; 5905 } 5906 5907 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 5908 5909 if(temp != null && !temp.isEmpty()) 5910 mods.add(new Modifier("AR", temp, x, y, centered)); 5911 } 5912 5913 } 5914 else if(ss == SymbolID.SymbolSet_Activities) 5915 { 5916 //No top center label 5917 5918 //Do right side labels 5919 x = 1;//on right 5920 centered = false; 5921 5922 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5923 { 5924 y = 1; 5925 5926 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 5927 if(temp != null && !temp.isEmpty()) 5928 mods.add(new Modifier("G", temp, x, y, centered)); 5929 } 5930 5931 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 5932 { 5933 y = 2; 5934 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 5935 y--; 5936 temp = modifiers.get(Modifiers.AS_COUNTRY); 5937 5938 if(temp != null && !temp.isEmpty()) 5939 mods.add(new Modifier("AS", temp, x, y, centered)); 5940 } 5941 5942 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5943 { 5944 y = -1;//below center 5945 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 5946 if(temp != null && !temp.isEmpty()) 5947 mods.add(new Modifier("H", temp, x, y, centered)); 5948 } 5949 5950 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 5951 { 5952 y = -2; 5953 if(!strict && !modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 5954 y++; 5955 temp = temp = modifiers.get(Modifiers.J_EVALUATION_RATING); 5956 5957 if(temp != null && !temp.isEmpty()) 5958 mods.add(new Modifier("J", temp, x, y, centered)); 5959 } 5960 5961 //Do left side labels 5962 x = -1;//on left 5963 centered = false; 5964 5965 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 5966 { 5967 y = 1; 5968 temp = modifiers.get(Modifiers.Y_LOCATION); 5969 5970 if(temp != null && !temp.isEmpty()) 5971 mods.add(new Modifier("Y", temp, x, y, centered)); 5972 } 5973 5974 if(modifiers.containsKey(Modifiers.W_DTG_1)) 5975 { 5976 y = 2;//above center 5977 if(!strict && !modifiers.containsKey(Modifiers.Y_LOCATION)) 5978 y--; 5979 temp = modifiers.get(Modifiers.W_DTG_1); 5980 if(temp != null && !temp.isEmpty()) 5981 mods.add(new Modifier("W", temp, x, y, centered)); 5982 } 5983 5984 } 5985 else if(ss == SymbolID.SymbolSet_CyberSpace) 5986 { 5987 //Do top center label 5988 x = 0;//centered 5989 y = 9;//on top of symbol 5990 if(modifiers.containsKey(Modifiers.B_ECHELON)) 5991 { 5992 temp = modifiers.get(Modifiers.B_ECHELON); 5993 if(temp != null && !temp.isEmpty()) 5994 mods.add(new Modifier("B", temp, x, y, centered)); 5995 } 5996 5997 //Do right side labels 5998 x = 1;//on right 5999 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6000 { 6001 y = 0;//center 6002 centered = true;//vertically centered, only matters for labels on left and right side 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 else if(!strict) 6008 { 6009 //if no "H', bring G and M closer to the center 6010 centered = false; 6011 } 6012 6013 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6014 { 6015 y = 1;//above center 6016 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 6017 if(temp != null && !temp.isEmpty()) 6018 mods.add(new Modifier("G", temp, x, y, centered)); 6019 } 6020 6021 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 6022 { 6023 y = 2; 6024 if(!strict && !modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6025 y--; 6026 temp = ""; 6027 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 6028 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 6029 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6030 temp += modifiers.get(Modifiers.AS_COUNTRY); 6031 temp = temp.trim(); 6032 if(temp != null && !temp.isEmpty()) 6033 mods.add(new Modifier("F AS", temp, x, y, centered)); 6034 } 6035 6036 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6037 { 6038 y = -1;//below center 6039 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6040 if(temp != null && !temp.isEmpty()) 6041 mods.add(new Modifier("M", temp, x, y, centered)); 6042 } 6043 6044 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6045 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6046 { 6047 y = -2; 6048 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6049 y++; 6050 temp = ""; 6051 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6052 temp = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6053 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6054 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 6055 6056 temp = temp.trim(); 6057 if(temp != null && !temp.isEmpty()) 6058 mods.add(new Modifier("K L", temp, x, y, centered)); 6059 } 6060 6061 //Do left side labels 6062 x = -1;//on left 6063 centered = true; 6064 6065 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6066 { 6067 y = 0; 6068 temp = modifiers.get(Modifiers.Y_LOCATION); 6069 6070 if(temp != null && !temp.isEmpty()) 6071 mods.add(new Modifier("Y", temp, x, y, centered)); 6072 } 6073 else if (!strict) 6074 { 6075 centered = false; 6076 } 6077 6078 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6079 { 6080 y = 1;//above center 6081 temp = modifiers.get(Modifiers.W_DTG_1); 6082 if(temp != null && !temp.isEmpty()) 6083 mods.add(new Modifier("W", temp, x, y, centered)); 6084 } 6085 6086 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6087 { 6088 y = -1;//below center 6089 temp = ""; 6090 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6091 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 6092 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6093 temp += modifiers.get(Modifiers.V_EQUIP_TYPE); 6094 6095 temp = temp.trim(); 6096 if(temp != null && !temp.isEmpty()) 6097 mods.add(new Modifier("T V", temp, x, y, centered)); 6098 } 6099 6100 } 6101 /*else if(ver == SymbolID.SymbolSet_MineWarfare) 6102 { 6103 //no modifiers 6104 }//*/ 6105 //else//SymbolSet Unknown 6106 //processUnknownTextModifiers 6107 } 6108 else// if(ver >= SymbolID.Version_2525E) 6109 { 6110 int fs = SymbolID.getFrameShape(symbolID); 6111 if(ss == SymbolID.SymbolSet_LandUnit || 6112 ss == SymbolID.SymbolSet_LandCivilianUnit_Organization || 6113 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_LandUnit)) 6114 { 6115 //Do top center label 6116 x = 0;//centered 6117 y = 9;//on top of symbol 6118 if(modifiers.containsKey(Modifiers.B_ECHELON)) 6119 { 6120 temp = modifiers.get(Modifiers.B_ECHELON); 6121 if(temp != null && !temp.isEmpty()) 6122 mods.add(new Modifier("B", temp, x, y, centered)); 6123 } 6124 6125 //Do right side labels 6126 x = 1;//on right 6127 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6128 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6129 { 6130 y = 0;//center 6131 centered = true;//vertically centered, only matters for labels on left and right side 6132 temp = ""; 6133 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6134 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6135 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6136 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6137 temp = temp.trim(); 6138 if(temp != null && !temp.isEmpty()) 6139 mods.add(new Modifier("H AF", temp, x, y, centered)); 6140 } 6141 else if(!strict) 6142 { 6143 //if no "H', bring G and M closer to the center 6144 centered = false; 6145 } 6146 6147 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6148 { 6149 y = 1;//above center 6150 temp = ""; 6151 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6152 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6153 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6154 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6155 temp = temp.trim(); 6156 if(temp != null && !temp.isEmpty()) 6157 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6158 } 6159 6160 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 6161 { 6162 y = 2; 6163 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6164 y--; 6165 temp = ""; 6166 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 6167 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 6168 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6169 temp += modifiers.get(Modifiers.AS_COUNTRY); 6170 temp = temp.trim(); 6171 if(temp != null && !temp.isEmpty()) 6172 mods.add(new Modifier("F AS", temp, x, y, centered)); 6173 } 6174 6175 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6176 { 6177 y = -1;//below center 6178 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6179 if(temp != null && !temp.isEmpty()) 6180 mods.add(new Modifier("M", temp, x, y, centered)); 6181 } 6182 6183 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6184 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6185 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 6186 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6187 { 6188 y = -2; 6189 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6190 y++; 6191 temp = ""; 6192 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6193 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6194 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6195 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6196 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6197 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 6198 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6199 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6200 temp = temp.trim(); 6201 if(temp != null && !temp.isEmpty()) 6202 mods.add(new Modifier("J K L P", temp, x, y, centered)); 6203 } 6204 6205 //Do left side labels 6206 x = -1;//on left 6207 6208 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 6209 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 6210 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6211 { 6212 y = 0;//center 6213 centered = true;//vertically centered, only matters for labels on left and right side 6214 6215 temp = ""; 6216 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6217 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6218 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6219 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 6220 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6221 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6222 temp = temp.trim(); 6223 if(temp != null && !temp.isEmpty()) 6224 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 6225 } 6226 else if(!strict) 6227 { 6228 centered = false; 6229 } 6230 6231 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6232 { 6233 y = 1; 6234 temp = ""; 6235 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6236 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6237 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6238 temp += modifiers.get(Modifiers.Y_LOCATION); 6239 6240 temp = temp.trim(); 6241 mods.add(new Modifier("X Y", temp, x, y, centered)); 6242 } 6243 6244 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6245 { 6246 y = 2;//above center 6247 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6248 y--; 6249 6250 temp = modifiers.get(Modifiers.W_DTG_1); 6251 6252 if(temp != null && !temp.isEmpty()) 6253 mods.add(new Modifier("W", temp, x, y, centered)); 6254 } 6255 6256 if(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6257 { 6258 y = -1;//below center 6259 temp = ""; 6260 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6261 temp = modifiers.get(Modifiers.C_QUANTITY) + sep; 6262 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6263 temp += modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6264 6265 temp = temp.trim(); 6266 if(temp != null && !temp.isEmpty()) 6267 mods.add(new Modifier("C T", temp, x, y, centered)); 6268 } 6269 6270 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6271 { 6272 y = -2; 6273 if(!strict && !(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 6274 y++; 6275 temp = modifiers.get(Modifiers.Z_SPEED); 6276 if(temp != null && !temp.isEmpty()) 6277 mods.add(new Modifier("Z", temp, x, y, centered)); 6278 } 6279 } 6280 else if(ss == SymbolID.SymbolSet_LandEquipment || 6281 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_LandEquipment)) 6282 { 6283 //Do top center label 6284 x = 0;//centered 6285 y = 9;//on top of symbol 6286 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6287 { 6288 temp = modifiers.get(Modifiers.C_QUANTITY); 6289 if(temp != null && !temp.isEmpty()) 6290 mods.add(new Modifier("C", temp, x, y, centered)); 6291 } 6292 6293 //Do right side labels 6294 x = 1;//on right 6295 centered = false; 6296 6297 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6298 { 6299 y = 1;//above center 6300 temp = ""; 6301 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6302 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6303 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6304 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6305 temp = temp.trim(); 6306 if(temp != null && !temp.isEmpty()) 6307 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6308 } 6309 6310 if( modifiers.containsKey(Modifiers.AS_COUNTRY)) 6311 { 6312 y = 2; 6313 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6314 y--; 6315 temp = modifiers.get(Modifiers.AS_COUNTRY); 6316 6317 if(temp != null && !temp.isEmpty()) 6318 mods.add(new Modifier("AS", temp, x, y, centered)); 6319 } 6320 6321 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6322 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6323 { 6324 y = -1; 6325 temp = ""; 6326 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6327 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6328 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6329 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6330 temp = temp.trim(); 6331 if(temp != null && !temp.isEmpty()) 6332 mods.add(new Modifier("H AF", temp, x, y, centered)); 6333 } 6334 6335 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6336 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6337 modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) || 6338 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6339 { 6340 y = -2; 6341 if(!strict && !(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6342 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))) 6343 y++; 6344 temp = ""; 6345 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6346 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6347 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6348 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6349 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 6350 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP) + sep; 6351 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6352 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6353 temp = temp.trim(); 6354 if(temp != null && !temp.isEmpty()) 6355 mods.add(new Modifier("J K L P", temp, x, y, centered)); 6356 } 6357 6358 //Do left side labels 6359 x = -1;//on left 6360 6361 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 6362 modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || 6363 modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6364 { 6365 y = 0;//center 6366 centered = true;//vertically centered, only matters for labels on left and right side 6367 6368 temp = ""; 6369 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6370 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6371 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6372 temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE) + sep; 6373 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6374 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6375 temp = temp.trim(); 6376 if(temp != null && !temp.isEmpty()) 6377 mods.add(new Modifier("V AD AE", temp, x, y, centered)); 6378 } 6379 else if(!strict) 6380 { 6381 centered = false; 6382 } 6383 6384 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6385 { 6386 y = 1; 6387 temp = ""; 6388 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6389 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6390 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6391 temp += modifiers.get(Modifiers.Y_LOCATION); 6392 6393 temp = temp.trim(); 6394 mods.add(new Modifier("X Y", temp, x, y, centered)); 6395 } 6396 6397 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6398 { 6399 y = 2;//above center 6400 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6401 y--; 6402 6403 temp = modifiers.get(Modifiers.W_DTG_1); 6404 6405 if(temp != null && !temp.isEmpty()) 6406 mods.add(new Modifier("W", temp, x, y, centered)); 6407 } 6408 6409 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6410 { 6411 y = -1;//below center 6412 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6413 6414 temp = temp.trim(); 6415 if(temp != null && !temp.isEmpty()) 6416 mods.add(new Modifier("T", temp, x, y, centered)); 6417 } 6418 6419 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6420 { 6421 y = -2; 6422 if(!strict && !modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6423 y++; 6424 temp = modifiers.get(Modifiers.Z_SPEED); 6425 if(temp != null && !temp.isEmpty()) 6426 mods.add(new Modifier("Z", temp, x, y, centered)); 6427 } 6428 } 6429 else if(ss == SymbolID.SymbolSet_LandInstallation) 6430 { 6431 //No top center label 6432 6433 //Do right side labels 6434 x = 1;//on right 6435 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6436 { 6437 y = 0;//center 6438 centered = true;//vertically centered, only matters for labels on left and right side 6439 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6440 6441 if(temp != null && !temp.isEmpty()) 6442 mods.add(new Modifier("H", temp, x, y, centered)); 6443 } 6444 else if(!strict) 6445 { 6446 //if no "H', bring G and M closer to the center 6447 centered = false; 6448 } 6449 6450 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6451 { 6452 y = 1;//above center 6453 temp = ""; 6454 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6455 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6456 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6457 temp += modifiers.get(Modifiers.AQ_GUARDED_UNIT); 6458 temp = temp.trim(); 6459 if(temp != null && !temp.isEmpty()) 6460 mods.add(new Modifier("G AQ", temp, x, y, centered)); 6461 } 6462 6463 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6464 { 6465 y = 2; 6466 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))) 6467 y--; 6468 temp = modifiers.get(Modifiers.AS_COUNTRY); 6469 6470 if(temp != null && !temp.isEmpty()) 6471 mods.add(new Modifier("AS", temp, x, y, centered)); 6472 } 6473 6474 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6475 { 6476 y = -1;//below center 6477 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6478 if(temp != null && !temp.isEmpty()) 6479 mods.add(new Modifier("M", temp, x, y, centered)); 6480 } 6481 6482 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6483 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6484 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6485 { 6486 y = -2; 6487 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6488 y++; 6489 temp = ""; 6490 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6491 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 6492 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 6493 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 6494 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6495 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 6496 temp = temp.trim(); 6497 if(temp != null && !temp.isEmpty()) 6498 mods.add(new Modifier("J K P", temp, x, y, centered)); 6499 } 6500 6501 //Do left side labels 6502 x = -1;//on left 6503 centered = false; 6504 6505 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6506 { 6507 y = 1; 6508 temp = ""; 6509 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6510 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6511 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6512 temp += modifiers.get(Modifiers.Y_LOCATION); 6513 6514 temp = temp.trim(); 6515 mods.add(new Modifier("X Y", temp, x, y, centered)); 6516 } 6517 6518 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6519 { 6520 y = 2;//above center 6521 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6522 y--; 6523 6524 temp = modifiers.get(Modifiers.W_DTG_1); 6525 6526 if(temp != null && !temp.isEmpty()) 6527 mods.add(new Modifier("W", temp, x, y, centered)); 6528 } 6529 6530 if(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6531 { 6532 y = -1;//below center 6533 temp = ""; 6534 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6535 temp = modifiers.get(Modifiers.C_QUANTITY) + sep; 6536 if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)) 6537 temp += modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME); 6538 6539 temp = temp.trim(); 6540 if(temp != null && !temp.isEmpty()) 6541 mods.add(new Modifier("C AE", temp, x, y, centered)); 6542 } 6543 6544 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6545 { 6546 y = -2; 6547 if(!strict && !(modifiers.containsKey(Modifiers.C_QUANTITY) || modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))) 6548 y++; 6549 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6550 if(temp != null && !temp.isEmpty()) 6551 mods.add(new Modifier("T", temp, x, y, centered)); 6552 } 6553 } 6554 else if(ss == SymbolID.SymbolSet_Space || 6555 ss == SymbolID.SymbolSet_SpaceMissile || 6556 ss == SymbolID.SymbolSet_Air || 6557 ss == SymbolID.SymbolSet_AirMissile || 6558 (ss == SymbolID.SymbolSet_SignalsIntelligence && 6559 (fs == SymbolID.FrameShape_Space || fs == SymbolID.FrameShape_Air))) 6560 { 6561 //No top center label 6562 x = 0;//centered 6563 y = 9;//on top of symbol 6564 6565 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 6566 { 6567 temp = modifiers.get(Modifiers.C_QUANTITY); 6568 if(temp != null && !temp.isEmpty()) 6569 mods.add(new Modifier("C", temp, x, y, centered)); 6570 } 6571 else if(modifiers.containsKey(Modifiers.B_ECHELON)) 6572 { 6573 temp = modifiers.get(Modifiers.B_ECHELON); 6574 if(temp != null && !temp.isEmpty()) 6575 mods.add(new Modifier("B", temp, x, y, centered)); 6576 } 6577 6578 6579 //Do right side labels 6580 x = 1;//on right 6581 centered = true; 6582 6583 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6584 { 6585 y = 0;// 6586 temp = ""; 6587 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6588 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 6589 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 6590 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 6591 temp = temp.trim(); 6592 6593 if(temp != null && !temp.isEmpty()) 6594 mods.add(new Modifier("V AF", temp, x, y, centered)); 6595 } 6596 else 6597 { 6598 centered = false; 6599 } 6600 6601 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.Y_LOCATION)) 6602 { 6603 y = 1;//above center 6604 temp = ""; 6605 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6606 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1) + sep; 6607 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6608 temp += modifiers.get(Modifiers.Y_LOCATION); 6609 temp = temp.trim(); 6610 6611 if(temp != null && !temp.isEmpty()) 6612 mods.add(new Modifier("T Y", temp, x, y, centered)); 6613 } 6614 6615 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6616 { 6617 y = 2; 6618 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) || modifiers.containsKey(Modifiers.Y_LOCATION))) 6619 y--; 6620 temp = modifiers.get(Modifiers.AS_COUNTRY); 6621 6622 if(temp != null && !temp.isEmpty()) 6623 mods.add(new Modifier("AS", temp, x, y, centered)); 6624 } 6625 6626 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) || 6627 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || 6628 modifiers.containsKey(Modifiers.Z_SPEED)) 6629 { 6630 y = -1;//below center 6631 temp = ""; 6632 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6633 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS) + sep; 6634 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6635 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 6636 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6637 temp = modifiers.get(Modifiers.Z_SPEED); 6638 6639 temp = temp.trim(); 6640 6641 if(temp != null && !temp.isEmpty()) 6642 mods.add(new Modifier("P X Z", temp, x, y, centered)); 6643 } 6644 6645 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6646 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || 6647 modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6648 { 6649 y = -2;//below center 6650 if(!(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) || 6651 modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || 6652 modifiers.containsKey(Modifiers.Z_SPEED))) 6653 y++; 6654 6655 temp = ""; 6656 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6657 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6658 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6659 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1) + sep; 6660 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 6661 temp += modifiers.get(Modifiers.J_EVALUATION_RATING); 6662 temp = temp.trim(); 6663 6664 if(temp != null && !temp.isEmpty()) 6665 mods.add(new Modifier("G H J", temp, x, y, centered)); 6666 } 6667 6668 //No left side labels 6669 x = -1;//on right 6670 centered = true; 6671 6672 if(modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) 6673 { 6674 y = 0;// 6675 temp = temp += modifiers.get(Modifiers.AD_PLATFORM_TYPE); 6676 6677 if(temp != null && !temp.isEmpty()) 6678 mods.add(new Modifier("AD", temp, x, y, centered)); 6679 } 6680 else 6681 { 6682 centered = false; 6683 } 6684 6685 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6686 { 6687 y = 1;//above center 6688 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 6689 6690 if(temp != null && !temp.isEmpty()) 6691 mods.add(new Modifier("AR", temp, x, y, centered)); 6692 } 6693 6694 if(modifiers.containsKey(Modifiers.W_DTG_1)) 6695 { 6696 y = 2; 6697 if(!strict && !modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6698 y--; 6699 temp = modifiers.get(Modifiers.W_DTG_1); 6700 6701 if(temp != null && !temp.isEmpty()) 6702 mods.add(new Modifier("W", temp, x, y, centered)); 6703 } 6704 } 6705 else if(ss == SymbolID.SymbolSet_SeaSurface || 6706 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_SeaSurface)) 6707 { 6708 //No top center label 6709 6710 6711 //Do right side labels 6712 x = 1;//on right 6713 centered = false; 6714 6715 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6716 { 6717 y = 1;//above center 6718 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 6719 6720 if(temp != null && !temp.isEmpty()) 6721 mods.add(new Modifier("V", temp, x, y, centered)); 6722 } 6723 6724 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6725 { 6726 y = 2; 6727 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6728 y--; 6729 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6730 6731 if(temp != null && !temp.isEmpty()) 6732 mods.add(new Modifier("T", temp, x, y, centered)); 6733 } 6734 6735 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6736 { 6737 y = 3; 6738 if(!strict) 6739 { 6740 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6741 y--; 6742 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6743 y--; 6744 } 6745 6746 temp = modifiers.get(Modifiers.AS_COUNTRY ); 6747 6748 if(temp != null && !temp.isEmpty()) 6749 mods.add(new Modifier("AS", temp, x, y, centered)); 6750 } 6751 6752 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6753 { 6754 y = -1;//below center 6755 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 6756 6757 if(temp != null && !temp.isEmpty()) 6758 mods.add(new Modifier("P", temp, x, y, centered)); 6759 } 6760 6761 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6762 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6763 { 6764 y = -2;//below center 6765 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6766 y++; 6767 6768 temp = ""; 6769 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6770 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6771 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6772 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6773 temp = temp.trim(); 6774 6775 if(temp != null && !temp.isEmpty()) 6776 mods.add(new Modifier("G H", temp, x, y, centered)); 6777 } 6778 6779 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 6780 modifiers.containsKey(Modifiers.Z_SPEED)) 6781 { 6782 y = -3; 6783 if(!strict) 6784 { 6785 if(!(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6786 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 6787 y++; 6788 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6789 y++; 6790 } 6791 temp = ""; 6792 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6793 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 6794 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6795 temp += modifiers.get(Modifiers.Z_SPEED); 6796 temp = temp.trim(); 6797 if(temp != null && !temp.isEmpty()) 6798 mods.add(new Modifier("Y Z", temp, x, y, centered)); 6799 } 6800 6801 //No left side labels 6802 x = -1; 6803 centered = false; 6804 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) || 6805 modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6806 { 6807 y = 2; 6808 if(!strict) 6809 { 6810 y--; 6811 } 6812 temp = ""; 6813 if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT)) 6814 temp = modifiers.get(Modifiers.AQ_GUARDED_UNIT) + sep; 6815 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6816 temp += modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 6817 temp = temp.trim(); 6818 if(temp != null && !temp.isEmpty()) 6819 mods.add(new Modifier("AQ AR", temp, x, y, centered)); 6820 } 6821 } 6822 else if(ss == SymbolID.SymbolSet_SeaSubsurface || 6823 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_SeaSubsurface)) 6824 { 6825 //No top center label 6826 6827 6828 //Do right side labels 6829 x = 1;//on right 6830 centered = false; 6831 6832 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6833 { 6834 y = 1;//above center 6835 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 6836 6837 if(temp != null && !temp.isEmpty()) 6838 mods.add(new Modifier("V", temp, x, y, centered)); 6839 } 6840 6841 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6842 { 6843 y = 2; 6844 if(!strict && !modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6845 y--; 6846 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 6847 6848 if(temp != null && !temp.isEmpty()) 6849 mods.add(new Modifier("T", temp, x, y, centered)); 6850 } 6851 6852 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6853 { 6854 y = 3; 6855 if(!strict) 6856 { 6857 if(!modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 6858 y--; 6859 if(!modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 6860 y--; 6861 } 6862 6863 temp = modifiers.get(Modifiers.AS_COUNTRY ); 6864 6865 if(temp != null && !temp.isEmpty()) 6866 mods.add(new Modifier("AS", temp, x, y, centered)); 6867 } 6868 6869 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6870 { 6871 y = -1;//below center 6872 temp = modifiers.get(Modifiers.P_IFF_SIF_AIS); 6873 6874 if(temp != null && !temp.isEmpty()) 6875 mods.add(new Modifier("P", temp, x, y, centered)); 6876 } 6877 6878 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6879 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6880 { 6881 y = -2;//below center 6882 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6883 y++; 6884 6885 temp = ""; 6886 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6887 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS) + sep; 6888 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6889 temp += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6890 temp = temp.trim(); 6891 6892 if(temp != null && !temp.isEmpty()) 6893 mods.add(new Modifier("G H", temp, x, y, centered)); 6894 } 6895 6896 if(modifiers.containsKey(Modifiers.Y_LOCATION) || 6897 modifiers.containsKey(Modifiers.Z_SPEED)) 6898 { 6899 y = -3; 6900 if(!strict) 6901 { 6902 if(!(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || 6903 modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))) 6904 y++; 6905 if(!modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6906 y++; 6907 } 6908 temp = ""; 6909 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 6910 temp = modifiers.get(Modifiers.Y_LOCATION) + sep; 6911 if(modifiers.containsKey(Modifiers.Z_SPEED)) 6912 temp += modifiers.get(Modifiers.Z_SPEED); 6913 temp = temp.trim(); 6914 if(temp != null && !temp.isEmpty()) 6915 mods.add(new Modifier("Y Z", temp, x, y, centered)); 6916 } 6917 6918 //No left side labels 6919 x = -1; 6920 centered = false; 6921 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6922 { 6923 y = 1; 6924 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH); 6925 6926 if(temp != null && !temp.isEmpty()) 6927 mods.add(new Modifier("X", temp, x, y, centered)); 6928 } 6929 6930 if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) 6931 { 6932 y = 2; 6933 if(!strict && !modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 6934 { 6935 y--; 6936 } 6937 temp = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR); 6938 temp = temp.trim(); 6939 if(temp != null && !temp.isEmpty()) 6940 mods.add(new Modifier("AR", temp, x, y, centered)); 6941 } 6942 } 6943 else if(ss == SymbolID.SymbolSet_DismountedIndividuals) 6944 { 6945 //No top center label 6946 6947 6948 //Do right side labels 6949 x = 1;//on right 6950 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 6951 { 6952 y = 0;//center 6953 centered = true;//vertically centered, only matters for labels on left and right side 6954 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 6955 6956 if(temp != null && !temp.isEmpty()) 6957 mods.add(new Modifier("H", temp, x, y, centered)); 6958 } 6959 else if(!strict) 6960 { 6961 centered = false; 6962 } 6963 6964 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 6965 { 6966 y = 1;//above center 6967 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 6968 6969 if(temp != null && !temp.isEmpty()) 6970 mods.add(new Modifier("G", temp, x, y, centered)); 6971 } 6972 6973 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 6974 { 6975 y = 2; 6976 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))) 6977 y--; 6978 temp = modifiers.get(Modifiers.AS_COUNTRY); 6979 6980 if(temp != null && !temp.isEmpty()) 6981 mods.add(new Modifier("AS", temp, x, y, centered)); 6982 } 6983 6984 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6985 { 6986 y = -1;//below center 6987 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 6988 if(temp != null && !temp.isEmpty()) 6989 mods.add(new Modifier("M", temp, x, y, centered)); 6990 } 6991 6992 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING) || 6993 modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || 6994 modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 6995 { 6996 y = -2; 6997 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 6998 y++; 6999 temp = ""; 7000 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7001 temp = modifiers.get(Modifiers.J_EVALUATION_RATING) + sep; 7002 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7003 temp += modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 7004 if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS)) 7005 temp += modifiers.get(Modifiers.P_IFF_SIF_AIS); 7006 temp = temp.trim(); 7007 if(temp != null && !temp.isEmpty()) 7008 mods.add(new Modifier("J K P", temp, x, y, centered)); 7009 } 7010 7011 //Do left side labels 7012 x = -1;//on left 7013 7014 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || 7015 modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7016 { 7017 y = 0;//center 7018 centered = true;//vertically centered, only matters for labels on left and right side 7019 7020 temp = ""; 7021 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7022 temp = modifiers.get(Modifiers.V_EQUIP_TYPE) + sep; 7023 if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER)) 7024 temp += modifiers.get(Modifiers.AF_COMMON_IDENTIFIER); 7025 temp = temp.trim(); 7026 if(temp != null && !temp.isEmpty()) 7027 mods.add(new Modifier("V AF", temp, x, y, centered)); 7028 } 7029 else if(!strict) 7030 { 7031 centered = false; 7032 } 7033 7034 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION)) 7035 { 7036 y = 1; 7037 temp = ""; 7038 if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) 7039 temp = modifiers.get(Modifiers.X_ALTITUDE_DEPTH) + sep; 7040 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7041 temp += modifiers.get(Modifiers.Y_LOCATION); 7042 7043 temp = temp.trim(); 7044 mods.add(new Modifier("X Y", temp, x, y, centered)); 7045 } 7046 7047 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7048 { 7049 y = 2;//above center 7050 if(!strict && !(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))) 7051 y--; 7052 7053 temp = modifiers.get(Modifiers.W_DTG_1); 7054 7055 if(temp != null && !temp.isEmpty()) 7056 mods.add(new Modifier("W", temp, x, y, centered)); 7057 } 7058 7059 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7060 { 7061 y = -1;//below center 7062 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7063 7064 if(temp != null && !temp.isEmpty()) 7065 mods.add(new Modifier("T", temp, x, y, centered)); 7066 } 7067 7068 if(modifiers.containsKey(Modifiers.Z_SPEED)) 7069 { 7070 y = -2; 7071 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 7072 y++; 7073 temp = modifiers.get(Modifiers.Z_SPEED); 7074 if(temp != null && !temp.isEmpty()) 7075 mods.add(new Modifier("Z", temp, x, y, centered)); 7076 } 7077 } 7078 else if(ss == SymbolID.SymbolSet_Activities) 7079 { 7080 //No top center label 7081 7082 7083 //Do right side labels 7084 x = 1;//on right 7085 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7086 { 7087 y = 0;//center 7088 centered = true;//vertically centered, only matters for labels on left and right side 7089 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 7090 7091 if(temp != null && !temp.isEmpty()) 7092 mods.add(new Modifier("G", temp, x, y, centered)); 7093 } 7094 else if(!strict) 7095 { 7096 centered = false; 7097 } 7098 7099 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7100 { 7101 y = 1;//above center 7102 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7103 7104 if(temp != null && !temp.isEmpty()) 7105 mods.add(new Modifier("T", temp, x, y, centered)); 7106 } 7107 7108 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7109 { 7110 y = 2; 7111 if(!strict && !(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))) 7112 y--; 7113 temp = modifiers.get(Modifiers.AS_COUNTRY); 7114 7115 if(temp != null && !temp.isEmpty()) 7116 mods.add(new Modifier("AS", temp, x, y, centered)); 7117 } 7118 7119 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7120 { 7121 y = -1;//below center 7122 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7123 if(temp != null && !temp.isEmpty()) 7124 mods.add(new Modifier("H", temp, x, y, centered)); 7125 } 7126 7127 if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING)) 7128 { 7129 y = -2; 7130 if(!strict && !modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7131 y++; 7132 temp = modifiers.get(Modifiers.J_EVALUATION_RATING); 7133 7134 if(temp != null && !temp.isEmpty()) 7135 mods.add(new Modifier("J", temp, x, y, centered)); 7136 } 7137 7138 //Do left side labels 7139 x = -1;//on left 7140 7141 if(!strict) 7142 { 7143 centered = false; 7144 } 7145 7146 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7147 { 7148 y = 1; 7149 temp = modifiers.get(Modifiers.Y_LOCATION); 7150 7151 if(temp != null && !temp.isEmpty()) 7152 mods.add(new Modifier("Y", temp, x, y, centered)); 7153 } 7154 7155 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7156 { 7157 y = 2;//above center 7158 if(!strict && !(modifiers.containsKey(Modifiers.Y_LOCATION))) 7159 y--; 7160 7161 temp = modifiers.get(Modifiers.W_DTG_1); 7162 7163 if(temp != null && !temp.isEmpty()) 7164 mods.add(new Modifier("W", temp, x, y, centered)); 7165 } 7166 7167 if(modifiers.containsKey(Modifiers.C_QUANTITY)) 7168 { 7169 y = -1;//below center 7170 temp = modifiers.get(Modifiers.C_QUANTITY); 7171 7172 if(temp != null && !temp.isEmpty()) 7173 mods.add(new Modifier("C", temp, x, y, centered)); 7174 } 7175 7176 } 7177 else if(ss == SymbolID.SymbolSet_CyberSpace || 7178 (ss == SymbolID.SymbolSet_SignalsIntelligence && fs == SymbolID.FrameShape_Cyberspace)) 7179 { 7180 //Do top center label 7181 x = 0;//centered 7182 y = 9;//on top of symbol 7183 if(modifiers.containsKey(Modifiers.B_ECHELON)) 7184 { 7185 temp = modifiers.get(Modifiers.B_ECHELON); 7186 if(temp != null && !temp.isEmpty()) 7187 mods.add(new Modifier("B", temp, x, y, centered)); 7188 } 7189 7190 //Do right side labels 7191 x = 1;//on right 7192 if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) 7193 { 7194 y = 0;//center 7195 centered = true;//vertically centered, only matters for labels on left and right side 7196 temp = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1); 7197 7198 if(temp != null && !temp.isEmpty()) 7199 mods.add(new Modifier("H", temp, x, y, centered)); 7200 } 7201 else if(!strict) 7202 { 7203 centered = false; 7204 } 7205 7206 if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS)) 7207 { 7208 y = 1;//above center 7209 temp = modifiers.get(Modifiers.G_STAFF_COMMENTS); 7210 7211 if(temp != null && !temp.isEmpty()) 7212 mods.add(new Modifier("G", temp, x, y, centered)); 7213 } 7214 7215 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.AS_COUNTRY)) 7216 { 7217 y = 2; 7218 if(!strict && !(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))) 7219 y--; 7220 temp = ""; 7221 if(modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED)) 7222 temp = modifiers.get(Modifiers.F_REINFORCED_REDUCED) + sep; 7223 if(modifiers.containsKey(Modifiers.AS_COUNTRY)) 7224 temp += modifiers.get(Modifiers.AS_COUNTRY); 7225 temp = temp.trim(); 7226 if(temp != null && !temp.isEmpty()) 7227 mods.add(new Modifier("F AS", temp, x, y, centered)); 7228 } 7229 7230 if(modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7231 { 7232 y = -1;//below center 7233 temp = modifiers.get(Modifiers.M_HIGHER_FORMATION); 7234 if(temp != null && !temp.isEmpty()) 7235 mods.add(new Modifier("M", temp, x, y, centered)); 7236 } 7237 7238 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 7239 { 7240 y = -2; 7241 if(!strict && !modifiers.containsKey(Modifiers.M_HIGHER_FORMATION)) 7242 y++; 7243 temp = ""; 7244 if(modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)) 7245 temp = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS) + sep; 7246 if(modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)) 7247 temp += modifiers.get(Modifiers.L_SIGNATURE_EQUIP); 7248 temp = temp.trim(); 7249 if(temp != null && !temp.isEmpty()) 7250 mods.add(new Modifier("K L", temp, x, y, centered)); 7251 } 7252 7253 //Do left side labels 7254 x=-1; 7255 if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) 7256 { 7257 y = 0;//center 7258 centered = true;//vertically centered, only matters for labels on left and right side 7259 7260 temp = modifiers.get(Modifiers.V_EQUIP_TYPE); 7261 7262 if(temp != null && !temp.isEmpty()) 7263 mods.add(new Modifier("V", temp, x, y, centered)); 7264 } 7265 else if(!strict) 7266 { 7267 centered = false; 7268 } 7269 7270 if(modifiers.containsKey(Modifiers.Y_LOCATION)) 7271 { 7272 y = 1; 7273 temp = modifiers.get(Modifiers.Y_LOCATION); 7274 7275 if(temp != null && !temp.isEmpty()) 7276 mods.add(new Modifier("Y", temp, x, y, centered)); 7277 } 7278 7279 if(modifiers.containsKey(Modifiers.W_DTG_1)) 7280 { 7281 y = 2;//above center 7282 if(!strict && !(modifiers.containsKey(Modifiers.Y_LOCATION))) 7283 y--; 7284 7285 temp = modifiers.get(Modifiers.W_DTG_1); 7286 7287 if(temp != null && !temp.isEmpty()) 7288 mods.add(new Modifier("W", temp, x, y, centered)); 7289 } 7290 7291 if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) 7292 { 7293 y = -1;//below center 7294 temp = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1); 7295 7296 if(temp != null && !temp.isEmpty()) 7297 mods.add(new Modifier("T", temp, x, y, centered)); 7298 } 7299 } 7300 /*else if(ver == SymbolID.SymbolSet_MineWarfare) 7301 { 7302 //no modifiers 7303 }//*/ 7304 //else//SymbolSet Unknown 7305 //processUnknownTextModifiers 7306 } 7307 7308 return mods; 7309 } 7310 7311 7312 /** 7313 * 7314 * @param bounds bounds of the core icon 7315 * @param labelWidth height of the label to be placed 7316 * @param location if 1, label on right side of symbol. On left if -1, center if 0. 7317 * @returns 7318 */ 7319 private static double getLabelXPosition(Rect bounds, int labelWidth, int location, float modifierFontHeight) 7320 { 7321 int buffer = (int)modifierFontHeight/2; 7322 7323 double x = 0; 7324 if(location == 1)//on right 7325 { 7326 x = bounds.left + bounds.width() + buffer; 7327 } 7328 else if(location == -1)//left 7329 { 7330 x = bounds.left - labelWidth - buffer; 7331 } 7332 else if(location == 0) 7333 { 7334 x = (int)Math.round((bounds.left + (bounds.width() * 0.5f)) - (labelWidth * 0.5f)); 7335 } 7336 return x; 7337 } 7338 7339 /** 7340 * 7341 * @param bounds bounds of the core icon 7342 * @param labelHeight height of the label to be placed 7343 * @param descent descent of the label to be placed 7344 * @param bufferText spacing buffer if desired 7345 * @param centered if true, there will be a center label location identified by 0 7346 * @param location positive 1, 2, 3 to be above symbol mid-point or negative values to be below 7347 * @returns y position 7348 */ 7349 private static double getLabelYPosition(Rect bounds, int labelHeight, int descent, int bufferText, boolean centered, int location) { 7350 double y = 0; 7351 if (bounds != null && !bounds.isEmpty()) 7352 { 7353 if(centered) 7354 { 7355 switch (location) 7356 { 7357 case 3://3 above center 7358 y = (bounds.height()); 7359 y = ((y * 0.5) + (labelHeight * 0.5)); 7360 y = y - ((labelHeight + bufferText) * 3); 7361 y = bounds.top + y; 7362 break; 7363 case 2://2 above center 7364 y = (bounds.height()); 7365 y = ((y * 0.5) + (labelHeight * 0.5)); 7366 y = y - ((labelHeight + bufferText) * 2); 7367 y = bounds.top + y; 7368 break; 7369 case 1://1 above center 7370 y = (bounds.height()); 7371 y = ((y * 0.5) + (labelHeight * 0.5)); 7372 y = y - ((labelHeight + bufferText)); 7373 y = bounds.top + y; 7374 break; 7375 case 0: //centered 7376 y = (bounds.height()); 7377 y = ((y * 0.5) + ((labelHeight - descent) * 0.5)); 7378 y = bounds.top + y; 7379 break; 7380 case -1://1 below center 7381 y = (bounds.height()); 7382 y = ((y * 0.5) + (labelHeight * 0.5)); 7383 y = y + ((labelHeight + bufferText - descent)); 7384 y = bounds.top + y; 7385 break; 7386 case -2://2 below center 7387 y = (bounds.height()); 7388 y = ((y * 0.5) + (labelHeight * 0.5)); 7389 y = y + ((labelHeight + bufferText) * 2) - (descent); 7390 y = bounds.top + y; 7391 break; 7392 case -3://3 below center 7393 y = (bounds.height()); 7394 y = ((y * 0.5) + (labelHeight * 0.5)); 7395 y = y + ((labelHeight + bufferText) * 3) - (descent); 7396 y = bounds.top + y; 7397 break; 7398 } 7399 } 7400 else//split between top and bottom 7401 { 7402 switch (location) 7403 { 7404 case 3: 7405 y = (bounds.top + ((bounds.height() / 2) - descent - labelHeight*2 - bufferText)); 7406 break; 7407 case 2: 7408 y = (bounds.top + ((bounds.height() / 2) - descent - labelHeight - bufferText)); 7409 break; 7410 case 1: 7411 y = (bounds.top + ((bounds.height() / 2) - descent)); 7412 break; 7413 case -1: 7414 y = (bounds.top + (bounds.height() / 2) + (labelHeight - descent + bufferText)); 7415 break; 7416 case -2: 7417 y = (bounds.top + (bounds.height() / 2) + ((labelHeight*2 - descent + bufferText))); 7418 break; 7419 case -3: 7420 y = (bounds.top + (bounds.height() / 2) + ((labelHeight*3 - descent + bufferText))); 7421 break; 7422 } 7423 } 7424 } 7425 return y; 7426 } 7427 7428 private static boolean isCOnTop(String symbolID) 7429 { 7430 boolean onTop = false; 7431 7432 int version = SymbolID.getVersion(symbolID); 7433 int ss = SymbolID.getSymbolSet(symbolID); 7434 char frame = SymbolID.getFrameShape(symbolID); 7435 7436 if(SymbolUtilities.hasModifier(symbolID,Modifiers.C_QUANTITY)) { 7437 if (frame == SymbolID.FrameShape_Air || frame == SymbolID.FrameShape_Space) 7438 onTop = true; 7439 else if(frame == '0') 7440 { 7441 if (ss == SymbolID.SymbolSet_Air || 7442 ss == SymbolID.SymbolSet_AirMissile || 7443 ss == SymbolID.SymbolSet_Space || 7444 ss == SymbolID.SymbolSet_SpaceMissile || 7445 ss == SymbolID.SymbolSet_SignalsIntelligence_Air || 7446 (ss == SymbolID.SymbolSet_LandEquipment && version <= SymbolID.Version_2525Dch1)) { 7447 onTop = true; 7448 } 7449 } 7450 } 7451 return onTop; 7452 } 7453 public static boolean hasDisplayModifiers(String symbolID, Map<String,String> modifiers) 7454 { 7455 boolean hasModifiers = false; 7456 int ss = SymbolID.getSymbolSet(symbolID); 7457 int status = SymbolID.getStatus(symbolID); 7458 int context = SymbolID.getContext(symbolID); 7459 7460 if(ss == SymbolID.SymbolSet_ControlMeasure)//check control measure 7461 { 7462 if (SymbolUtilities.isCBRNEvent(symbolID) == true && modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT)) 7463 { 7464 hasModifiers = true; 7465 } 7466 else if(SymbolUtilities.hasFDI(symbolID)) 7467 hasModifiers = true; 7468 } 7469 else if(ss != SymbolID.SymbolSet_Atmospheric && 7470 ss != SymbolID.SymbolSet_Oceanographic && 7471 ss != SymbolID.SymbolSet_MeteorologicalSpace) 7472 {//checking units 7473 7474 if(context > 0) //Exercise or Simulation 7475 hasModifiers = true; 7476 7477 //echelon or mobility, 7478 if (SymbolID.getAmplifierDescriptor(symbolID) > 0 || modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT)) 7479 hasModifiers = true; 7480 7481 if(modifiers.containsKey(Modifiers.AJ_SPEED_LEADER)) 7482 hasModifiers = true; 7483 7484 if(modifiers.containsKey(Modifiers.AO_ENGAGEMENT_BAR)) 7485 hasModifiers = true; 7486 7487 //HQ/Taskforce 7488 if(SymbolID.getHQTFD(symbolID) > 0) 7489 hasModifiers = true; 7490 7491 if(status > 1)//Fully capable, damaged, destroyed 7492 hasModifiers = true; 7493 }//no display modifiers for single point weather 7494 7495 7496 7497 return hasModifiers; 7498 } 7499 7500 public static boolean hasTextModifiers(String symbolID, Map<String,String> modifiers) 7501 { 7502 7503 int ss = SymbolID.getSymbolSet(symbolID); 7504 int ec = SymbolID.getEntityCode(symbolID); 7505 if(ss == SymbolID.SymbolSet_Atmospheric) 7506 { 7507 switch(ec) 7508 { 7509 case 110102: //tropopause low 7510 case 110202: //tropopause high 7511 case 162200: //tropopause level ? 7512 case 162300: //freezing level ? 7513 return true; 7514 default: 7515 return false; 7516 } 7517 } 7518 else if(ss == SymbolID.SymbolSet_Oceanographic || ss == SymbolID.SymbolSet_MeteorologicalSpace) 7519 { 7520 return false; 7521 } 7522 else if (ss == SymbolID.SymbolSet_ControlMeasure) 7523 { 7524 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 7525 7526 if( msi.getModifiers().size() > 0 && modifiers != null && modifiers.size() > 0) 7527 return true; 7528 else 7529 return false; 7530 } 7531 else 7532 { 7533 7534 if (SymbolUtilities.getStandardIdentityModifier(symbolID) != null) 7535 { 7536 return true; 7537 } 7538 7539 int cc = SymbolID.getCountryCode(symbolID); 7540 if (cc > 0 && !GENCLookup.getInstance().get3CharCode(cc).isEmpty()) 7541 { 7542 return true; 7543 }//*/ 7544 7545 else if (modifiers.size() > 0) 7546 { 7547 return true; 7548 } 7549 } 7550 return false; 7551 } 7552 7553 /** 7554 * Rerturns either the default font from RendererSettings or font based on properties 7555 * set in MilStdAttributes. 7556 * @param attributes 7557 * @return 7558 */ 7559 private static Paint getFont(Map<String,String> attributes) 7560 { 7561 Paint p = null; 7562 Typeface tf = null; 7563 7564 p = RendererSettings.getInstance().getModiferFont(); 7565 7566 String[] props = RendererSettings.getInstance().getModiferFontProps(); 7567 7568 String ff = props[0]; 7569 int fstyle = Integer.parseInt(props[1]);// modifierFont.getTypeface().getStyle(); 7570 float fsize = Float.parseFloat(props[2]);// modifierFont.getTextSize(); 7571 String temp = null; 7572 7573 7574 if(attributes.containsKey(MilStdAttributes.FontFamily) || 7575 attributes.containsKey(MilStdAttributes.FontStyle) || 7576 attributes.containsKey(MilStdAttributes.FontSize)) 7577 { 7578 if(attributes.containsKey(MilStdAttributes.FontStyle)) 7579 { 7580 temp = attributes.get(MilStdAttributes.FontStyle); 7581 if (temp != null && !temp.isEmpty()) { 7582 fstyle = Integer.parseInt(temp); 7583 } 7584 } 7585 if(attributes.containsKey(MilStdAttributes.FontSize)) 7586 { 7587 temp = attributes.get(MilStdAttributes.FontSize); 7588 if (temp != null && !temp.isEmpty()) { 7589 fsize = Float.parseFloat(temp); 7590 } 7591 } 7592 if(attributes.containsKey(MilStdAttributes.FontFamily)) 7593 { 7594 temp = attributes.get(MilStdAttributes.FontFamily); 7595 if (temp != null && !temp.isEmpty()) { 7596 ff = temp;//Typeface.create(temp,fstyle); 7597 } 7598 } 7599 tf = Typeface.create(ff,fstyle); 7600 if(tf == null) 7601 tf = Typeface.create(props[0],fstyle); 7602 if(tf == null) 7603 return null; 7604 7605 p = new Paint(); 7606 p.setTextSize(fsize); 7607 p.setAntiAlias(true); 7608 p.setTypeface(tf); 7609 p.setStrokeCap(Cap.BUTT); 7610 p.setStrokeJoin(Join.MITER); 7611 p.setStrokeMiter(3f); 7612 7613 return p; 7614 } 7615 else 7616 return _modifierFont; 7617 7618 } 7619 7620 private static float[] getFontHeightandDescent(Paint font) 7621 { 7622 float[] hd = {0f,0f}; 7623 7624 if(font != null) { 7625 Paint.FontMetrics fm = font.getFontMetrics(); 7626 //_modifierFontHeight = fm.top + fm.bottom; 7627 hd[0] = fm.bottom - fm.top; 7628 hd[1] = fm.descent; 7629 } 7630 return hd; 7631 } 7632 7633}