001package armyc2.c2sd.renderer; 002 003import android.graphics.Bitmap; 004import android.graphics.Bitmap.Config; 005import android.graphics.Canvas; 006import android.graphics.DashPathEffect; 007import android.graphics.Paint; 008import android.graphics.Paint.Cap; 009import android.graphics.Paint.Join; 010import android.graphics.Paint.Style; 011import android.graphics.Path; 012import android.graphics.Path.Direction; 013import android.graphics.Point; 014import android.graphics.Rect; 015import android.graphics.RectF; 016import android.util.SparseArray; 017 018import java.util.ArrayList; 019import java.util.List; 020import java.util.Locale; 021import java.util.logging.Level; 022 023import armyc2.c2sd.renderer.utilities.Color; 024import armyc2.c2sd.renderer.utilities.ErrorLogger; 025import armyc2.c2sd.renderer.utilities.ImageInfo; 026import armyc2.c2sd.renderer.utilities.MilStdAttributes; 027import armyc2.c2sd.renderer.utilities.ModifiersTG; 028import armyc2.c2sd.renderer.utilities.ModifiersUnits; 029import armyc2.c2sd.renderer.utilities.PathUtilties; 030import armyc2.c2sd.renderer.utilities.RectUtilities; 031import armyc2.c2sd.renderer.utilities.RendererSettings; 032import armyc2.c2sd.renderer.utilities.RendererUtilities; 033import armyc2.c2sd.renderer.utilities.SymbolDef; 034import armyc2.c2sd.renderer.utilities.SymbolDefTable; 035import armyc2.c2sd.renderer.utilities.SymbolUtilities; 036import armyc2.c2sd.renderer.utilities.TextInfo; 037import armyc2.c2sd.renderer.utilities.UnitFontLookup; 038 039public class ModifierRenderer 040{ 041 042 private static Paint _modifierFont = null; 043 private static float _modifierFontHeight = 10f; 044 private static float _modifierFontDescent = 2f; 045 private static RendererSettings RS = RendererSettings.getInstance(); 046 private static int tgTextModifierKeys[] = {2,3,4,5,6,9,10,11,12,13,14,15}; 047 048 private static final Object _ModifierFontMutex = new Object(); 049 public static void setModifierFont(Paint font, float height, float descent) 050 { 051 synchronized (_ModifierFontMutex) { 052 _modifierFont = font; 053 _modifierFontHeight = height; 054 _modifierFontDescent = descent; 055 } 056 } 057 058 public static ImageInfo processUnitDisplayModifiers(ImageInfo ii, String symbolID, SparseArray<String> modifiers, Boolean hasTextModifiers, SparseArray<String> attributes) 059 { 060 061 ImageInfo newii = null; 062 Rect symbolBounds = new Rect(ii.getSymbolBounds()); 063 Rect imageBounds = new Rect(ii.getImageBounds()); 064 Point centerPoint = new Point(ii.getCenterPoint()); 065 Point symbolCenter = new Point(symbolBounds.centerX(), symbolBounds.centerY()); 066 TextInfo tiEchelon = null; 067 TextInfo tiAM = null; 068 Rect echelonBounds = null; 069 Rect amBounds = null; 070 Color textColor = Color.BLACK; 071 Color textBackgroundColor = null; 072 Color lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID); 073 int buffer = 0; 074 int alpha = -1; 075 //ctx = null; 076 int offsetX = 0; 077 int offsetY = 0; 078 int symStd = RS.getSymbologyStandard(); 079 if (attributes.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0) 080 { 081 symStd = Integer.parseInt(attributes.get(MilStdAttributes.SymbologyStandard)); 082 } 083 if (attributes.indexOfKey(MilStdAttributes.Alpha) >= 0) 084 { 085 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 086 textColor.setAlpha(alpha); 087 } 088 if (attributes.indexOfKey(MilStdAttributes.TextColor) >= 0) 089 { 090 textColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 091 if(alpha > -1) 092 textColor.setAlpha(alpha); 093 } 094 if (attributes.indexOfKey(MilStdAttributes.TextBackgroundColor) >= 0) 095 { 096 textBackgroundColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 097 if(alpha > -1) 098 textBackgroundColor.setAlpha(alpha); 099 } 100 if (attributes.indexOfKey(MilStdAttributes.LineColor) >= 0) 101 { 102 lineColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.LineColor)); 103 } 104 105 106 // <editor-fold defaultstate="collapsed" desc="Build Mobility Modifiers"> 107 RectF mobilityBounds = null; 108 109 List<Path> shapes = new ArrayList<Path>(); 110 Path mobilityPath = null; 111 Path mobilityPathFill = null; 112 if (symbolID.charAt(10) == ('M') && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.R_MOBILITY_INDICATOR) || 113 symbolID.charAt(10) == ('N') && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.AG_AUX_EQUIP_INDICATOR) ) 114 { 115 116 //Draw Mobility 117 int fifth = (int) ((symbolBounds.width() * 0.2) + 0.5f); 118 mobilityPath = new Path(); 119 int x = 0; 120 int y = 0; 121 int centerX = 0; 122 int bottomY = 0; 123 int height = 0; 124 int width = 0; 125 int middleY = 0; 126 int wheelOffset = 2; 127 int wheelSize = fifth;//10; 128 int rrHeight = fifth;//10; 129 int rrArcWidth = (int) ((fifth * 1.5) + 0.5f);//16; 130 131 String mobility = symbolID.substring(10, 12); 132 x = (int) symbolBounds.left + 1; 133 y = (int) symbolBounds.top; 134 height = Math.round(symbolBounds.height()); 135 width = Math.round(symbolBounds.width()) - 3; 136 bottomY = y + height + 2; 137 138 if (symbolID.charAt(10) == ('M')) 139 { 140 bottomY = y + height + 2; 141 142 //wheelSize = width / 7; 143 //rrHeight = width / 7; 144 //rrArcWidth = width / 7; 145 if (mobility.equals("MO")) 146 { 147 //line 148 PathUtilties.addLine(mobilityPath, x, bottomY, x + width, bottomY); 149 150 //left circle 151 PathUtilties.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 152 153 //right circle 154 PathUtilties.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 155 } 156 else if (mobility.equals("MP")) 157 { 158 //line 159 PathUtilties.addLine(mobilityPath, x, bottomY, x + width, bottomY); 160 161 //left circle 162 PathUtilties.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 163 164 //right circle 165 PathUtilties.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 166 167 //center wheel 168 PathUtilties.addEllipse(mobilityPath, x + (width / 2) - (wheelSize / 2), bottomY + wheelOffset, wheelSize, wheelSize); 169 } 170 else if (mobility.equals("MQ")) 171 { 172 //round rectangle 173 PathUtilties.addRoundedRect(mobilityPath, x, bottomY, width, rrHeight, rrHeight/2, rrHeight); 174 175 } 176 else if (mobility.equals("MR")) 177 { 178 //round rectangle 179 PathUtilties.addRoundedRect(mobilityPath, x, bottomY, width, rrHeight, wheelSize/2, rrHeight); 180 181 //left circle 182 PathUtilties.addEllipse(mobilityPath, x - wheelSize - wheelSize, bottomY, wheelSize, wheelSize); 183 } 184 else if (mobility.equals("MS")) 185 { 186 //line 187 PathUtilties.addLine(mobilityPath, x + wheelSize, bottomY + (wheelSize / 2), 188 x + width - wheelSize, bottomY + (wheelSize / 2)); 189 190 //left circle 191 PathUtilties.addEllipse(mobilityPath, x, bottomY, wheelSize, wheelSize); 192 193 //right circle 194 PathUtilties.addEllipse(mobilityPath, x + width - wheelSize, bottomY, wheelSize, wheelSize); 195 } 196 else if (mobility.equals("MT")) 197 { 198 199 //line 200 PathUtilties.addLine(mobilityPath, x, bottomY, x + width, bottomY); 201 202 //left circle 203 PathUtilties.addEllipse(mobilityPath, x + wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 204 205 //left circle2 206 PathUtilties.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize); 207 208 //right circle 209 PathUtilties.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 210 211 //right circle2 212 PathUtilties.addEllipse(mobilityPath, x + width - wheelSize - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize); 213 214 } 215 else if (mobility.equals("MU")) 216 { 217 float halfWidth = (rrArcWidth * 0.5f); 218 mobilityPath.moveTo(x, bottomY); 219 mobilityPath.lineTo(x + halfWidth, bottomY + halfWidth); 220 mobilityPath.lineTo(x + width, bottomY + halfWidth); 221 } 222 else if (mobility.equals("MV")) 223 { 224 mobilityPath.moveTo(x, bottomY); 225 226 mobilityPath.cubicTo(x, bottomY, x - rrHeight, bottomY + rrHeight/2, x, bottomY + rrHeight); 227 //mobilityPath.bezierCurveTo(x, bottomY, x-rrArcWidth, bottomY+3, x, bottomY+rrHeight); 228 229 mobilityPath.lineTo(x + width, bottomY + rrHeight); 230 231 mobilityPath.cubicTo(x + width, bottomY + rrHeight, x + width + rrHeight, bottomY + rrHeight/2, x + width, bottomY); 232 //shapeMobility.curveTo(x + width, bottomY + rrHeight, x+ width + rrArcWidth, bottomY+3, x + width, bottomY); 233 } 234 else if (mobility.equals("MW")) 235 { 236 centerX = Math.round(RectUtilities.getCenterX(symbolBounds)); 237 int angleWidth = rrHeight / 2; 238 mobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 239 mobilityPath.lineTo(centerX - angleWidth, bottomY); 240 mobilityPath.lineTo(centerX - angleWidth*2, bottomY + rrHeight + 2); 241 242 mobilityPath.moveTo(centerX, bottomY + rrHeight + 2); 243 mobilityPath.lineTo(centerX + angleWidth, bottomY); 244 mobilityPath.lineTo(centerX + angleWidth*2, bottomY + rrHeight + 2); 245 } 246 else if (mobility.equals("MX")) 247 { 248 centerX = Math.round(RectUtilities.getCenterX(symbolBounds)); 249 PathUtilties.addLine(mobilityPath, x + width, bottomY, x, bottomY); 250 //var line = new SO.Line(x + width, bottomY,x, bottomY); 251 252 float quarterX = (centerX - x) / 2; 253 //var quarterY = (((bottomY + rrHeight) - bottomY)/2); 254 255 mobilityPath.moveTo(x, bottomY); 256 mobilityPath.cubicTo(x + quarterX, bottomY + rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY); 257 //shapes.push(new SO.BCurve(x, bottomY,x+quarterX, bottomY+rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY)); 258 } 259 260 else if (mobility.equals("MY")) 261 { 262 float incrementX = width / 7; 263 middleY = (bottomY + (rrHeight / 2)); 264 265 x = Math.round(x + (incrementX / 2)); 266 float r = Math.round(incrementX / 2); 267 268 //mobilityPath.arcTo(oval, sAngle, sAngle, moveTo); 269 PathUtilties.arc(mobilityPath, x, middleY, r, 180, 180); 270 PathUtilties.arc(mobilityPath, x + incrementX, middleY, r, 180, -180, false); 271 PathUtilties.arc(mobilityPath, x + incrementX * 2, middleY, r, 180, 180, false); 272 PathUtilties.arc(mobilityPath, x + incrementX * 3, middleY, r, 180, -180, false); 273 PathUtilties.arc(mobilityPath, x + incrementX * 4, middleY, r, 180, 180, false); 274 PathUtilties.arc(mobilityPath, x + incrementX * 5, middleY, r, 180, -180, false); 275 PathUtilties.arc(mobilityPath, x + incrementX * 6, middleY, r, 180, 180, false); 276 277 } 278 279 } 280 //Draw Towed Array Sonar 281 else if (symbolID.charAt(10) == ('N')) 282 { 283 284 int boxHeight = (int) ((rrHeight * 0.8f) + 0.5f); 285 bottomY = y + height + (boxHeight / 7); 286 mobilityPathFill = new Path(); 287 offsetY = boxHeight / 7;//1; 288 centerX = Math.round(symbolBounds.left + (symbolBounds.right - symbolBounds.left) / 2); 289 int squareOffset = Math.round(boxHeight * 0.5f); 290 middleY = ((boxHeight / 2) + bottomY) + offsetY;//+1 for offset from symbol 291 if (symbolID.substring(10, 12).equals("NS")) 292 { 293 //subtract 0.5 becase lines 1 pixel thick get aliased into 294 //a line two pixels wide. 295 //line 296 PathUtilties.addLine(mobilityPath, centerX - 1, bottomY - 1, centerX - 1, bottomY + boxHeight + offsetY); 297 //shapes.push(new SO.Line(centerX-1,bottomY-1,centerX-1, bottomY + rrHeight + 3)); 298 //shapeLines.append(new Line2D.Double(centerX,bottomY - 2,centerX, bottomY + rrHeight + 1), false); 299 //line 300 PathUtilties.addLine(mobilityPath, x, middleY, x + width, middleY); 301 //shapes.push(new SO.Line(x,middleY,x + width, middleY)); 302 //shapeLines.append(new Line2D.Double(x,middleY,x + width, middleY), false); 303 //square 304 mobilityPathFill.addRect(PathUtilties.makeRectF(x - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 305 //shapes.push(new SO.Rectangle(x-squareOffset, bottomY+offsetY, 5, 5)); 306 //shapeSquares.append(new Rectangle2D.Double(x-squareOffset, bottomY, 5, 5), false); 307 //square 308 mobilityPathFill.addRect(PathUtilties.makeRectF(Math.round(centerX - squareOffset), bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 309 //shapes.push(new SO.Rectangle(Math.round(centerX-squareOffset), bottomY+offsetY, 5, 5)); 310 //shapeSquares.append(new Rectangle2D.Double(centerX-squareOffset, bottomY, 5, 5), false); 311 //square 312 mobilityPathFill.addRect(PathUtilties.makeRectF(x + width - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 313 //shapes.push(new SO.Rectangle(x + width - squareOffset, bottomY+offsetY, 5, 5)); 314 //shapeSquares.append(new Rectangle2D.Double(x + width - squareOffset, bottomY, 5, 5), false); 315 } 316 else if (symbolID.substring(10, 12).equals("NL")) 317 { 318 int leftX = x + (centerX - x) / 2, 319 rightX = centerX + (x + width - centerX) / 2; 320 321 //line vertical left 322 PathUtilties.addLine(mobilityPath, leftX, bottomY - 1, leftX, bottomY + offsetY + boxHeight + offsetY); 323 //shapes.push(new SO.Line(leftX,bottomY - 1,leftX, bottomY + rrHeight + 3)); 324 //shapeLines.append(new Line2D.Double(leftX,bottomY - 2,leftX, bottomY + rrHeight + 1), false); 325 //line vertical right 326 PathUtilties.addLine(mobilityPath, rightX, bottomY - 1, rightX, bottomY + offsetY + boxHeight + offsetY); 327 //shapes.push(new SO.Line(rightX,bottomY - 1,rightX, bottomY + rrHeight + 3)); 328 //shapeLines.append(new Line2D.Double(rightX,bottomY - 2,rightX, bottomY + rrHeight + 1), false); 329 //line horizontal 330 PathUtilties.addLine(mobilityPath, x, middleY, x + width, middleY); 331 //shapes.push(new SO.Line(x,middleY,x + width, middleY)); 332 //shapeLines.append(new Line2D.Double(x,middleY,x + width, middleY), false); 333 //square left 334 mobilityPathFill.addRect(PathUtilties.makeRectF(x - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 335 //shapes.push(new SO.Rectangle(x-squareOffset, bottomY+offsetY, 5, 5)); 336 //shapeSquares.append(new Rectangle2D.Double(x-squareOffset, bottomY, 5, 5), false); 337 //square middle 338 mobilityPathFill.addRect(PathUtilties.makeRectF(centerX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 339 //shapes.push(new SO.Rectangle(centerX-squareOffset, bottomY+offsetY, 5, 5)); 340 //shapeSquares.append(new Rectangle2D.Double(centerX-squareOffset, bottomY, 5, 5), false); 341 //square right 342 mobilityPathFill.addRect(PathUtilties.makeRectF(x + width - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 343 //shapes.push(new SO.Rectangle(x + width - squareOffset, bottomY+offsetY, 5, 5)); 344 //shapeSquares.append(new Rectangle2D.Double(x + width - squareOffset, bottomY, 5, 5), false); 345 //square middle left 346 mobilityPathFill.addRect(PathUtilties.makeRectF(leftX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 347 //shapes.push(new SO.Rectangle(leftX - squareOffset, bottomY+offsetY, 5, 5)); 348 //shapeSquares.append(new Rectangle2D.Double(leftX - squareOffset, bottomY, 5, 5), false); 349 //square middle right 350 mobilityPathFill.addRect(PathUtilties.makeRectF(rightX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW); 351 //shapes.push(new SO.Rectangle(rightX - squareOffset, bottomY+offsetY, 5, 5)); 352 //shapeSquares.append(new Rectangle2D.Double(rightX - squareOffset, bottomY, 5, 5), false); 353 354 } 355 } 356 357 //get mobility bounds 358 if (mobilityPath != null) 359 { 360 361 //build mobility bounds 362 mobilityBounds = new RectF(); 363 mobilityPath.computeBounds(mobilityBounds, true); 364 365 RectF mobilityFillBounds = new RectF(); 366 if (mobilityPathFill != null) 367 { 368 mobilityPathFill.computeBounds(mobilityFillBounds, true); 369 mobilityBounds.union(mobilityFillBounds); 370 } 371 372 //grow by one because we use a line thickness of 2. 373 mobilityBounds.set(mobilityBounds.left - 1, mobilityBounds.top - 1, mobilityBounds.right + 1, mobilityBounds.bottom + 1); 374 imageBounds.union(RectUtilities.makeRectFromRectF(mobilityBounds)); 375 } 376 } 377 // </editor-fold> 378 379 // <editor-fold defaultstate="collapsed" desc="Build Echelon"> 380 //Draw Echelon 381 String strEchelon = SymbolUtilities.getEchelon(symbolID);//symbolID.substring(11, 12); 382 if (strEchelon != null) 383 { 384 strEchelon = SymbolUtilities.getEchelonText(strEchelon); 385 } 386 if (strEchelon != null && SymbolUtilities.hasInstallationModifier(symbolID) == false 387 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.B_ECHELON)) 388 { 389 390 if (strEchelon != null) 391 { 392 int echelonOffset = 2, 393 outlineOffset = RS.getTextOutlineWidth(); 394 395 tiEchelon = new TextInfo(strEchelon, 0, 0, _modifierFont); 396 echelonBounds = tiEchelon.getTextBounds(); 397 398 int y = Math.round(symbolBounds.left - echelonOffset); 399 int x = Math.round(symbolBounds.left + (symbolBounds.width() / 2) 400 - (echelonBounds.width() / 2)); 401 tiEchelon.setLocation(x, y); 402 403 //There will never be lowercase characters in an echelon so trim that fat. 404 //Remove the descent from the bounding box. 405 tiEchelon.getTextOutlineBounds();//.shiftBR(0,Math.round(-(echelonBounds.height()*0.3))); 406 407 //make echelon bounds a little more spacious for things like nearby labels and Task Force. 408 RectUtilities.grow(echelonBounds, outlineOffset); 409 //tiEchelon.getTextOutlineBounds(); 410// RectUtilities.shift(echelonBounds, x, -outlineOffset); 411 //echelonBounds.shift(0,-outlineOffset);// - Math.round(echelonOffset/2)); 412 tiEchelon.setLocation(x, y - outlineOffset); 413 414 imageBounds.union(echelonBounds); 415 } 416 } 417 // </editor-fold> 418 419 // <editor-fold defaultstate="collapsed" desc="Build Affiliation Modifier"> 420 //Draw Echelon 421 String affiliationModifier = null; 422 if (RS.getDrawAffiliationModifierAsLabel() == false) 423 { 424 affiliationModifier = SymbolUtilities.getUnitAffiliationModifier(symbolID, symStd); 425 } 426 if (affiliationModifier != null) 427 { 428 429 int amOffset = 2; 430 int outlineOffset = RS.getTextOutlineWidth(); 431 432 tiAM = new TextInfo(affiliationModifier, 0, 0, _modifierFont); 433 amBounds = tiAM.getTextBounds(); 434 435 int x, y; 436 437 if (echelonBounds != null 438 && ((echelonBounds.left + echelonBounds.width() > symbolBounds.left + symbolBounds.width()))) 439 { 440 y = Math.round(symbolBounds.top - amOffset); 441 x = echelonBounds.left + echelonBounds.width(); 442 } 443 else 444 { 445 y = Math.round(symbolBounds.top - amOffset); 446 x = Math.round(symbolBounds.left + symbolBounds.width()); 447 } 448 tiAM.setLocation(x, y); 449 450 //adjust for outline. 451 RectUtilities.grow(amBounds, outlineOffset); 452 RectUtilities.shift(amBounds, 0, -outlineOffset); 453 tiAM.setLocation(x, y - outlineOffset); 454 455 imageBounds.union(amBounds); 456 } 457 // </editor-fold> 458 459 // <editor-fold defaultstate="collapsed" desc="Build Task Force"> 460 Rect tfBounds = null; 461 Rect tfRectangle = null; 462 if (SymbolUtilities.isTaskForce(symbolID) && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.D_TASK_FORCE_INDICATOR)) 463 { 464 if (echelonBounds != null) 465 { 466 tfRectangle = new Rect(echelonBounds.left, 467 echelonBounds.top,// + outlineOffset, 468 echelonBounds.right, 469 symbolBounds.top-1); 470 tfBounds = new Rect(tfRectangle); 471 } 472 else 473 { 474 int height = Math.round(symbolBounds.height() / 4); 475 int width = Math.round(symbolBounds.width() / 3); 476 477 tfRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 478 (int) symbolBounds.top - height, 479 width, 480 height); 481 482 tfBounds = RectUtilities.makeRect(tfRectangle.left + -1, 483 tfRectangle.top - 1, 484 tfRectangle.width() + 2, 485 tfRectangle.height() + 2); 486 487 } 488 imageBounds.union(tfBounds); 489 } 490 // </editor-fold> 491 492 // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator"> 493 Rect fdiBounds = null; 494 Point fdiTop = null; 495 Point fdiLeft = null; 496 Point fdiRight = null; 497 498 if ((SymbolUtilities.isFeintDummy(symbolID) 499 || SymbolUtilities.isFeintDummyInstallation(symbolID)) 500 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.AB_FEINT_DUMMY_INDICATOR)) 501 { 502 //create feint indicator /\ 503 fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top); 504 fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top); 505 506 char affiliation = symbolID.charAt(1); 507 if (affiliation == ('F') 508 || affiliation == ('A') 509 || affiliation == ('D') 510 || affiliation == ('M') 511 || affiliation == ('J') 512 || affiliation == ('K')) 513 { 514 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.height() * .75f))); 515 } 516 else 517 { 518 fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.height() * .54f))); 519 } 520 521 fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1); 522 fdiBounds.union(fdiTop.x, fdiTop.y); 523 fdiBounds.union(fdiRight.x, fdiRight.y); 524 525 if (echelonBounds != null) 526 { 527 int shiftY = Math.round(symbolBounds.top - echelonBounds.height() - 2); 528 fdiLeft.offset(0, shiftY); 529 fdiTop.offset(0, shiftY); 530 fdiRight.offset(0, shiftY); 531 fdiBounds.offset(0, shiftY); 532 } 533 534 imageBounds.union(fdiBounds); 535 536 } 537 // </editor-fold> 538 539 // <editor-fold defaultstate="collapsed" desc="Build Installation"> 540 Rect instRectangle = null; 541 Rect instBounds = null; 542 if (SymbolUtilities.hasInstallationModifier(symbolID) 543 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.AC_INSTALLATION)) 544 {//the actual installation symbols have the modifier 545 //built in. everything else, we have to draw it. 546 // 547 ////get indicator dimensions//////////////////////////////// 548 int width; 549 int height; 550 char affiliation = SymbolUtilities.getAffiliation(symbolID); 551 552 if (affiliation == 'F' 553 || affiliation == 'A' 554 || affiliation == 'D' 555 || affiliation == 'M' 556 || affiliation == 'J' 557 || affiliation == 'K') 558 { 559 //4th height, 3rd width 560 height = Math.round(symbolBounds.height() / 4); 561 width = Math.round(symbolBounds.width() / 3); 562 } 563 else if (affiliation == 'H' || affiliation == 'S')//hostile,suspect 564 { 565 //6th height, 3rd width 566 height = Math.round(symbolBounds.height() / 6); 567 width = Math.round(symbolBounds.width() / 3); 568 } 569 else if (affiliation == 'N' || affiliation == 'L')//neutral,exercise neutral 570 { 571 //6th height, 3rd width 572 height = Math.round(symbolBounds.height() / 6); 573 width = Math.round(symbolBounds.width() / 3); 574 } 575 else if (affiliation == 'P' 576 || affiliation == 'U' 577 || affiliation == 'G' 578 || affiliation == 'W') 579 { 580 //6th height, 3rd width 581 height = Math.round(symbolBounds.height() / 6); 582 width = Math.round(symbolBounds.width() / 3); 583 } 584 else 585 { 586 //6th height, 3rd width 587 height = Math.round(symbolBounds.height() / 6); 588 width = Math.round(symbolBounds.width() / 3); 589 } 590 591// if(width * 3 < symbolBounds.width()) 592// width++; 593 //set installation position///////////////////////////////// 594 //set position of indicator 595 if (affiliation == 'F' 596 || affiliation == 'A' 597 || affiliation == 'D' 598 || affiliation == 'M' 599 || affiliation == 'J' 600 || affiliation == 'K' 601 || affiliation == 'N' 602 || affiliation == 'L') 603 { 604 instRectangle = RectUtilities.makeRect((int) (symbolBounds.left + width), 605 (int) (symbolBounds.top - height), 606 width, 607 height); 608 } 609 else if (affiliation == 'H' || affiliation == 'S')//hostile,suspect 610 { 611 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 612 Math.round((int) symbolBounds.top - (height * 0.15f)), 613 width, 614 height); 615 } 616 else if (affiliation == 'P' 617 || affiliation == 'U' 618 || affiliation == 'G' 619 || affiliation == 'W') 620 { 621 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 622 Math.round(symbolBounds.top - (height * 0.3f)), 623 width, 624 height); 625 } 626 else 627 { 628 instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width, 629 Math.round(symbolBounds.top - (height * 0.3f)), 630 width, 631 height); 632 } 633 634 /*instRectangle = new SO.Rectangle(symbolBounds.left + width, 635 symbolBounds.top - height, 636 width, 637 height);//*/ 638 //generate installation bounds////////////////////////////// 639 instBounds = new Rect(instRectangle.left + -1, 640 instRectangle.top - 1, 641 instRectangle.width() + 2, 642 instRectangle.height() + 2); 643 644 imageBounds.union(instBounds); 645 646 } 647 // </editor-fold> 648 649 // <editor-fold defaultstate="collapsed" desc="Build HQ Staff"> 650 Point pt1HQ = null; 651 Point pt2HQ = null; 652 Rect hqBounds = null; 653 //Draw HQ Staff 654 if (SymbolUtilities.isHQ(symbolID) 655 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.S_HQ_STAFF_OR_OFFSET_INDICATOR)) 656 { 657 658 char affiliation = symbolID.charAt(1); 659 //get points for the HQ staff 660 if (affiliation == ('F') 661 || affiliation == ('A') 662 || affiliation == ('D') 663 || affiliation == ('M') 664 || affiliation == ('J') 665 || affiliation == ('K') 666 || affiliation == ('N') 667 || affiliation == ('L')) 668 { 669 pt1HQ = new Point((int) symbolBounds.left + 1, 670 (int) (symbolBounds.top + symbolBounds.height() - 1)); 671 pt2HQ = new Point((int) pt1HQ.x, (int) (pt1HQ.y + symbolBounds.height())); 672 } 673 else 674 { 675 pt1HQ = new Point((int) symbolBounds.left + 1, 676 (int) (symbolBounds.top + (symbolBounds.height() / 2))); 677 pt2HQ = new Point((int) pt1HQ.x, (int) (pt1HQ.y + symbolBounds.height())); 678 } 679 680 //create bounding rectangle for HQ staff. 681 hqBounds = new Rect(pt1HQ.x, pt1HQ.y, pt1HQ.x + 2, pt2HQ.y); 682 //adjust the image bounds accordingly. 683 imageBounds.union(hqBounds); 684 //imageBounds.shiftBR(0,pt2HQ.y-imageBounds.bottom); 685 //adjust symbol center 686 centerPoint.set(pt2HQ.x, pt2HQ.y); 687 } 688 689 // </editor-fold> 690 // <editor-fold defaultstate="collapsed" desc="Build DOM Arrow"> 691 Point[] domPoints = null; 692 Rect domBounds = null; 693 if (modifiers.indexOfKey(ModifiersUnits.Q_DIRECTION_OF_MOVEMENT) >= 0 694 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.Q_DIRECTION_OF_MOVEMENT)) 695 { 696 String strQ = modifiers.get(ModifiersUnits.Q_DIRECTION_OF_MOVEMENT); 697 698 if(strQ != null && SymbolUtilities.isNumber(strQ)) 699 { 700 float q = Float.valueOf(strQ); 701 702 boolean isY = (modifiers.indexOfKey(ModifiersUnits.Y_LOCATION) >= 0); 703 704 domPoints = createDOMArrowPoints(symbolID, symbolBounds, symbolCenter, q, isY); 705 706 domBounds = new Rect(domPoints[0].x, domPoints[0].y, 1, 1); 707 708 Point temp = null; 709 for (int i = 1; i < 6; i++) 710 { 711 temp = domPoints[i]; 712 if (temp != null) 713 { 714 domBounds.union(temp.x, temp.y); 715 } 716 } 717 imageBounds.union(domBounds); 718 } 719 } 720 721 // </editor-fold> 722 // <editor-fold defaultstate="collapsed" desc="Build Operational Condition Indicator"> 723 Rect ociBounds = null; 724 RectF ociBoundsF = null; 725 Rect ociShape = null; 726 Path ociSlashShape = null; 727 int ociOffset = 4; 728 if (mobilityBounds != null) 729 { 730 ociOffset = Math.round(mobilityBounds.bottom - symbolBounds.bottom) + 4; 731 } 732 if(RendererSettings.getInstance().getOperationalConditionModifierType() == RendererSettings.OperationalConditionModifierType_BAR) 733 { 734 ociShape = processOperationalConditionIndicator(symbolID, symbolBounds, ociOffset); 735 if (ociShape != null) 736 { 737 Rect temp = new Rect(ociShape); 738 RectUtilities.grow(temp, 2); 739 ociBounds = temp; 740 imageBounds.union(ociBounds); 741 } 742 } 743 else//slash 744 { 745 ociSlashShape = processOperationalConditionIndicatorSlash(symbolID, symbolBounds); 746 if (ociSlashShape != null) 747 { 748 //build mobility bounds 749 ociBoundsF = new RectF(); 750 ociBounds = new Rect(); 751 ociSlashShape.computeBounds(ociBoundsF, true); 752 ociBoundsF.roundOut(ociBounds); 753 imageBounds.union(ociBounds); 754 ociBounds = null; 755 } 756 } 757 758 759 // </editor-fold> 760 // 761 // <editor-fold defaultstate="collapsed" desc="Shift Modifiers"> 762 //adjust points if necessary 763 if (imageBounds.left < 0 || imageBounds.top < 0) 764 { 765 int shiftX = Math.abs(imageBounds.left); 766 int shiftY = Math.abs(imageBounds.top); 767 768 if (hqBounds != null) 769 { 770 pt1HQ.offset(shiftX, shiftY); 771 pt2HQ.offset(shiftX, shiftY); 772 } 773 if (echelonBounds != null) 774 { 775 tiEchelon.setLocation(tiEchelon.getLocation().x + shiftX, tiEchelon.getLocation().y + shiftY); 776 } 777 if (amBounds != null) 778 { 779 tiAM.setLocation(tiAM.getLocation().x + shiftX, tiAM.getLocation().y + shiftY); 780 } 781 if (tfBounds != null) 782 { 783 tfRectangle.offset(shiftX, shiftY); 784 tfBounds.offset(shiftX, shiftY); 785 } 786 if (instBounds != null) 787 { 788 instRectangle.offset(shiftX, shiftY); 789 instBounds.offset(shiftX, shiftY); 790 } 791 if (fdiBounds != null) 792 { 793 fdiBounds.offset(shiftX, shiftY); 794 fdiLeft.offset(shiftX, shiftY); 795 fdiTop.offset(shiftX, shiftY); 796 fdiRight.offset(shiftX, shiftY); 797 } 798 if (ociBounds != null) 799 { 800 ociBounds.offset(shiftX, shiftY); 801 ociShape.offset(shiftX, shiftY); 802 } 803 if(ociBoundsF != null) 804 { 805 ociBoundsF.offset(shiftX, shiftY); 806 ociSlashShape.offset(shiftX, shiftY); 807 } 808 if (domBounds != null) 809 { 810 for (int i = 0; i < 6; i++) 811 { 812 Point temp = domPoints[i]; 813 if (temp != null) 814 { 815 temp.offset(shiftX, shiftY); 816 } 817 } 818 domBounds.offset(shiftX, shiftY); 819 } 820 if (mobilityBounds != null) 821 { 822 //shift mobility points 823 mobilityPath.offset(shiftX, shiftY); 824 if (mobilityPathFill != null) 825 { 826 mobilityPathFill.offset(shiftX, shiftY); 827 } 828 829 mobilityBounds.offset(shiftX, shiftY); 830 } 831 832 centerPoint.offset(shiftX, shiftY); 833 symbolBounds.offset(shiftX, shiftY); 834 imageBounds.offset(shiftX, shiftY); 835 } 836 // </editor-fold> 837 838 // <editor-fold defaultstate="collapsed" desc="Draw Modifiers"> 839 /*if(useBuffer.equalstrue) 840 { 841 buffer = _bufferDisplayModifiers; 842 ctx = buffer.getContext('2d'); 843 ctx.clearRect(0,0,250,250); 844 } 845 else 846 { 847 buffer = this.createBuffer(imageBounds.getWidth(),imageBounds.getHeight()); 848 ctx = buffer.getContext('2d'); 849 //}*/ 850 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 851 Canvas ctx = new Canvas(bmp); 852 853 if (echelonBounds != null || amBounds != null) 854 { 855 // ctx.font = RendererSettings.getModifierFont(); 856 } 857 858 //render//////////////////////////////////////////////////////// 859 Paint paint = new Paint(); 860 paint.setStyle(Style.STROKE); 861 //paint.setColor(Color.black.toInt()); 862 paint.setColor(lineColor.toInt()); 863 if(alpha > -1) 864 paint.setAlpha(alpha); 865 paint.setStrokeWidth(2.0f); 866 867 if (hqBounds != null) 868 { 869 ctx.drawLine(pt1HQ.x, pt1HQ.y, pt2HQ.x, pt2HQ.y, paint); 870 } 871 872 if (tfBounds != null) 873 { 874 ctx.drawRect(tfRectangle, paint); 875 } 876 877 if (instBounds != null) 878 { 879 paint.setStyle(Style.FILL); 880 ctx.drawRect(instRectangle, paint); 881 } 882 883 if (echelonBounds != null) 884 { 885 TextInfo[] aTiEchelon = 886 { 887 tiEchelon 888 }; 889 renderText(ctx, aTiEchelon, textColor, textBackgroundColor); 890 891 echelonBounds = null; 892 tiEchelon = null; 893 } 894 895 if (amBounds != null) 896 { 897 TextInfo[] aTiAM = 898 { 899 tiAM 900 }; 901 renderText(ctx, aTiAM, textColor, textBackgroundColor); 902 amBounds = null; 903 tiAM = null; 904 } 905 906 if (fdiBounds != null) 907 { 908 909 Paint fdiPaint = new Paint(); 910 fdiPaint.setAntiAlias(true); 911 fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0); 912 if(alpha > -1) 913 fdiPaint.setAlpha(alpha); 914 fdiPaint.setStyle(Style.STROKE); 915 916 fdiPaint.setPathEffect(new DashPathEffect(new float[] 917 { 918 6, 4 919 }, 0)); 920 921 if (symbolBounds.width() > 19) 922 { 923 fdiPaint.setPathEffect(new DashPathEffect(new float[] 924 { 925 6, 4 926 }, 0)); 927 } 928 else 929 { 930 fdiPaint.setPathEffect(new DashPathEffect(new float[] 931 { 932 5, 3 933 }, 0)); 934 } 935 fdiPaint.setStrokeCap(Cap.BUTT); 936 fdiPaint.setStrokeJoin(Join.MITER); 937 fdiPaint.setStrokeWidth(2); 938 939 Path fdiPath = new Path(); 940 941 fdiPath.moveTo(fdiLeft.x, fdiLeft.y); 942 fdiPath.lineTo(fdiTop.x, fdiTop.y); 943 fdiPath.lineTo(fdiRight.x, fdiRight.y); 944 ctx.drawPath(fdiPath, fdiPaint); 945 946 fdiBounds = null; 947 948 } 949 950 if (mobilityBounds != null) 951 { 952 Paint mobilityPaint = new Paint(); 953 mobilityPaint.setStyle(Style.STROKE); 954 //mobilityPaint.setColor(Color.black.toInt()); 955 mobilityPaint.setColor(lineColor.toInt()); 956 if(alpha > -1) 957 mobilityPaint.setAlpha(alpha); 958 959 //ctx.lineCap = "butt"; 960 //ctx.lineJoin = "miter"; 961 if (symbolID.charAt(10) == ('M')) 962 { 963 mobilityPaint.setStrokeWidth(3f); 964 mobilityPaint.setAntiAlias(true); 965 } 966 else //NS or NL 967 { 968 mobilityPaint.setStrokeWidth(3f); 969 //mobilityPaint.setAntiAlias(true); 970 } 971 972 ctx.drawPath(mobilityPath, mobilityPaint); 973 974 if (mobilityPathFill != null) 975 { 976 mobilityPaint.setStyle(Style.FILL); 977 ctx.drawPath(mobilityPathFill, mobilityPaint); 978 } 979 980 mobilityBounds = null; 981 982 } 983 984 if (ociBounds != null) 985 { 986 Paint ociPaint = new Paint(); 987 988 int statusColor = 0; 989 char status = symbolID.charAt(3); 990 if (status == ('C'))//Fully Capable 991 { 992 statusColor = Color.green.toInt(); 993 } 994 else if (status == ('D'))//Damage 995 { 996 statusColor = Color.yellow.toInt(); 997 } 998 else if (status == ('X')) 999 { 1000 statusColor = Color.red.toInt(); 1001 } 1002 else if (status == ('F'))//full to capacity(hospital) 1003 { 1004 statusColor = Color.blue.toInt(); 1005 } 1006 1007 ociPaint.setColor(Color.black.toInt()); 1008 ociPaint.setStyle(Style.FILL); 1009 1010 if(alpha > -1) 1011 ociPaint.setAlpha(alpha); 1012 ctx.drawRect(ociBounds, ociPaint); 1013 ociPaint.setColor(statusColor); 1014 if(alpha > -1) 1015 ociPaint.setAlpha(alpha); 1016 ctx.drawRect(ociShape, ociPaint); 1017 1018 ociBounds = null; 1019 ociShape = null; 1020 } 1021 1022 //draw original icon. 1023 //ctx.drawImage(ii.getImage(),symbolBounds.left, symbolBounds.top); 1024 ctx.drawBitmap(ii.getImage(), null, symbolBounds, null); 1025 1026 if (domBounds != null) 1027 { 1028 drawDOMArrow(ctx, domPoints, alpha, lineColor); 1029 1030 domBounds = null; 1031 domPoints = null; 1032 } 1033 1034 if(ociBoundsF != null) 1035 { 1036 Paint ociPaint = new Paint(); 1037 int size = symbolBounds.width(); 1038 float ociStrokeWidth = 3f; 1039 1040 ociStrokeWidth = size/20f; 1041 if(ociStrokeWidth < 1f) 1042 ociStrokeWidth = 1f; 1043 /*if(size > 50 && size < 100) 1044 ociStrokeWidth = 5f; 1045 else if(size >= 100 && size < 200) 1046 ociStrokeWidth = 7f; 1047 else if(size >= 200) 1048 ociStrokeWidth = 10f;*/ 1049 //ociPaint.setColor(Color.black.toInt()); 1050 ociPaint.setColor(lineColor.toInt()); 1051 if(alpha > -1) 1052 ociPaint.setAlpha(alpha); 1053 ociPaint.setStrokeWidth(ociStrokeWidth); 1054 ociPaint.setStrokeCap(Cap.BUTT); 1055 ociPaint.setStyle(Style.STROKE); 1056 ociPaint.setAntiAlias(true); 1057 ctx.drawPath(ociSlashShape,ociPaint); 1058 1059 ociBoundsF = null; 1060 ociSlashShape = null; 1061 } 1062 1063 // </editor-fold> 1064 newii = new ImageInfo(bmp, centerPoint, symbolBounds); 1065 1066 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 1067 // </editor-fold> 1068 //return newii; 1069 if (newii != null) 1070 { 1071 return newii; 1072 } 1073 else 1074 { 1075 return null; 1076 } 1077 1078 } 1079 1080 private static double getYPositionForSCC(String symbolID) 1081 { 1082 double yPosition = 0.32; 1083 String temp = symbolID.substring(4, 10); 1084 char affiliation = symbolID.charAt(1); 1085 1086 if(temp.equals("WMGC--"))//GROUND (BOTTOM) MILCO 1087 { 1088 if(affiliation == 'H' || 1089 affiliation == 'S')//suspect 1090 yPosition = 0.29; 1091 else if(affiliation == 'N' || 1092 affiliation == 'L')//exercise neutral 1093 yPosition = 0.32; 1094 else if(affiliation == 'F' || 1095 affiliation == 'A' ||//assumed friend 1096 affiliation == 'D' ||//exercise friend 1097 affiliation == 'M' ||//exercise assumed friend 1098 affiliation == 'K' ||//faker 1099 affiliation == 'J')//joker 1100 yPosition = 0.32; 1101 else 1102 yPosition = 0.34; 1103 } 1104 else if(temp.equals("WMMC--"))//MOORED MILCO 1105 { 1106 if(affiliation == 'H' || 1107 affiliation == 'S')//suspect 1108 yPosition = 0.25; 1109 else if(affiliation == 'N' || 1110 affiliation == 'L')//exercise neutral 1111 yPosition = 0.25; 1112 else if(affiliation == 'F' || 1113 affiliation == 'A' ||//assumed friend 1114 affiliation == 'D' ||//exercise friend 1115 affiliation == 'M' ||//exercise assumed friend 1116 affiliation == 'K' ||//faker 1117 affiliation == 'J')//joker 1118 yPosition = 0.25; 1119 else 1120 yPosition = 0.28; 1121 } 1122 else if(temp.equals("WMFC--"))//FLOATING MILCO 1123 { 1124 if(affiliation == 'H' || 1125 affiliation == 'S')//suspect 1126 yPosition = 0.29; 1127 else if(affiliation == 'N' || 1128 affiliation == 'L')//exercise neutral 1129 yPosition = 0.32; 1130 else if(affiliation == 'F' || 1131 affiliation == 'A' ||//assumed friend 1132 affiliation == 'D' ||//exercise friend 1133 affiliation == 'M' ||//exercise assumed friend 1134 affiliation == 'K' ||//faker 1135 affiliation == 'J')//joker 1136 yPosition = 0.32; 1137 else 1138 yPosition = 0.34; 1139 } 1140 else if(temp.equals("WMC---"))//GENERAL MILCO 1141 { 1142 if(affiliation == 'H' || 1143 affiliation == 'S')//suspect 1144 yPosition = 0.33; 1145 else if(affiliation == 'N' || 1146 affiliation == 'L')//exercise neutral 1147 yPosition = 0.36; 1148 else if(affiliation == 'F' || 1149 affiliation == 'A' ||//assumed friend 1150 affiliation == 'D' ||//exercise friend 1151 affiliation == 'M' ||//exercise assumed friend 1152 affiliation == 'K' ||//faker 1153 affiliation == 'J')//joker 1154 yPosition = 0.36; 1155 else 1156 yPosition = 0.36; 1157 } 1158 1159 return yPosition; 1160 } 1161 1162 /** 1163 * 1164 * @param {type} symbolID 1165 * @param {type} bounds symbolBounds SO.Rectangle 1166 * @param {type} center SO.Point Location where symbol is centered. 1167 * @param {type} angle in degrees 1168 * @param {Boolean} isY Boolean. 1169 * @returns {Array} of SO.Point. First 3 items are the line. Last three are 1170 * the arrowhead. 1171 */ 1172 private static Point[] createDOMArrowPoints(String symbolID, Rect bounds, Point center, float angle, boolean isY) 1173 { 1174 Point[] arrowPoints = new Point[6]; 1175 Point pt1 = null; 1176 Point pt2 = null; 1177 Point pt3 = null; 1178 1179 char affiliation = symbolID.charAt(1); 1180 int length = 40; 1181 if (SymbolUtilities.isNBC(symbolID)) 1182 { 1183 length = Math.round(bounds.height() / 2); 1184 } 1185 else if((SymbolUtilities.isHQ(symbolID)) && 1186 (affiliation==('F') || 1187 affiliation==('A') || 1188 affiliation==('D') || 1189 affiliation==('M') || 1190 affiliation==('J') || 1191 affiliation==('K') || 1192 affiliation==('N') || 1193 affiliation==('L')) == false) 1194 { 1195 length = (int)Math.round(bounds.height() * 0.7); 1196 } 1197 else 1198 { 1199 length = bounds.height(); 1200 } 1201 1202 //get endpoint 1203 int dx2, dy2, 1204 x1, y1, 1205 x2, y2; 1206 1207 x1 = Math.round(center.x); 1208 y1 = Math.round(center.y); 1209 1210 pt1 = new Point(x1, y1); 1211 char scheme = symbolID.charAt(0); 1212 if (SymbolUtilities.isHQ(symbolID)==false && SymbolUtilities.isNBC(symbolID) 1213 || (scheme == 'S' && symbolID.charAt(2) == ('G')) || 1214 scheme == 'O' || scheme == 'E') 1215 { 1216 //drawStaff = true; 1217 if(SymbolUtilities.isHQ(symbolID)==false)//has HQ staff to start from 1218 { 1219 y1 = bounds.top + bounds.height(); 1220 pt1 = new Point(x1, y1); 1221 1222 if (isY == true && SymbolUtilities.isNBC(symbolID))//make room for y modifier 1223 { 1224 int yModifierOffset = (int) _modifierFontHeight; 1225 1226 yModifierOffset += RS.getTextOutlineWidth(); 1227 1228 pt1.offset(0, yModifierOffset); 1229 } 1230 1231 y1 = y1 + length; 1232 pt2 = new Point(x1, y1); 1233 } 1234 else 1235 { 1236 x1 = bounds.left+1; 1237 pt2 = new Point(x1, y1); 1238 if(affiliation == 'F' || 1239 affiliation == 'A' || 1240 affiliation == 'D' || 1241 affiliation == 'M' || 1242 affiliation == 'J' || 1243 affiliation == 'K' || 1244 affiliation == 'N' || 1245 affiliation == 'L') 1246 { 1247 /*y1 = bounds.top + bounds.height(); 1248 pt1 = new Point(x1, y1); 1249 y1 = y1 + length; 1250 pt2 = new Point(x1, y1);//*/ 1251 1252 pt1.x = x1; 1253 y1 = bounds.top + (bounds.height()); 1254 pt1.y = y1; 1255 x2 = x1; 1256 pt2.x = x2; 1257 y1 = pt1.y + bounds.height(); 1258 pt2.y = y1;//*/ 1259 1260 } 1261 else 1262 { 1263 pt1.x = x1; 1264 y1 = bounds.top + (bounds.height() / 2); 1265 pt1.y = y1; 1266 x2 = x1; 1267 pt2.x = x2; 1268 y1 = pt1.y + bounds.height(); 1269 pt2.y = y1; 1270 } 1271 } 1272 } 1273 1274 //get endpoint given start point and an angle 1275 //x2 = x1 + (length * Math.cos(radians))); 1276 //y2 = y1 + (length * Math.sin(radians))); 1277 angle = angle - 90;//in java, east is zero, we want north to be zero 1278 double radians = 0; 1279 radians = (angle * (Math.PI / 180));//convert degrees to radians 1280 1281 dx2 = x1 + (int) (length * Math.cos(radians)); 1282 dy2 = y1 + (int) (length * Math.sin(radians)); 1283 x2 = Math.round(dx2); 1284 y2 = Math.round(dy2); 1285 1286 //create arrowhead////////////////////////////////////////////////////// 1287 float arrowWidth = 16.0f,//8.0f,//6.5f;//7.0f;//6.5f;//10.0f//default 1288 theta = 0.423f;//higher value == shorter arrow head//*/ 1289 1290 if (length < 50) 1291 { 1292 theta = 0.55f; 1293 } 1294 /*float arrowWidth = length * .09f,// 16.0f,//8.0f,//6.5f;//7.0f;//6.5f;//10.0f//default 1295 theta = length * .0025f;//0.423f;//higher value == shorter arrow head 1296 if(arrowWidth < 8) 1297 arrowWidth = 8f;//*/ 1298 1299 int[] xPoints = new int[3];//3 1300 int[] yPoints = new int[3];//3 1301 int[] vecLine = new int[2];//2 1302 int[] vecLeft = new int[2];//2 1303 double fLength; 1304 double th; 1305 double ta; 1306 double baseX, baseY; 1307 1308 xPoints[0] = x2; 1309 yPoints[0] = y2; 1310 1311 //build the line vector 1312 vecLine[0] = (xPoints[0] - x1); 1313 vecLine[1] = (yPoints[0] - y1); 1314 1315 //build the arrow base vector - normal to the line 1316 vecLeft[0] = -vecLine[1]; 1317 vecLeft[1] = vecLine[0]; 1318 1319 //setup length parameters 1320 fLength = Math.sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]); 1321 th = arrowWidth / (2.0 * fLength); 1322 ta = arrowWidth / (2.0 * (Math.tan(theta) / 2.0) * fLength); 1323 1324 //find base of the arrow 1325 baseX = (xPoints[0] - ta * vecLine[0]); 1326 baseY = (yPoints[0] - ta * vecLine[1]); 1327 1328 //build the points on the sides of the arrow 1329 xPoints[1] = (int) Math.round(baseX + th * vecLeft[0]); 1330 yPoints[1] = (int) Math.round(baseY + th * vecLeft[1]); 1331 xPoints[2] = (int) Math.round(baseX - th * vecLeft[0]); 1332 yPoints[2] = (int) Math.round(baseY - th * vecLeft[1]); 1333 1334 //line.lineTo((int)baseX, (int)baseY); 1335 pt3 = new Point((int) Math.round(baseX), (int) Math.round(baseY)); 1336 1337 //arrowHead = new Polygon(xPoints, yPoints, 3); 1338 arrowPoints[0] = pt1; 1339 arrowPoints[1] = pt2; 1340 arrowPoints[2] = pt3; 1341 arrowPoints[3] = new Point(xPoints[0], yPoints[0]); 1342 arrowPoints[4] = new Point(xPoints[1], yPoints[1]); 1343 arrowPoints[5] = new Point(xPoints[2], yPoints[2]); 1344 1345 return arrowPoints; 1346 1347 } 1348 1349 private static void drawDOMArrow(Canvas ctx, Point[] domPoints, int alpha, Color lineColor) 1350 { 1351 Paint domPaint = new Paint(); 1352 domPaint.setStrokeCap(Cap.BUTT); 1353 domPaint.setStrokeJoin(Join.MITER); 1354 domPaint.setStrokeWidth(3); 1355 domPaint.setColor(lineColor.toInt()); 1356 domPaint.setStyle(Style.STROKE); 1357 if(alpha > -1) 1358 domPaint.setAlpha(alpha); 1359 1360 Path domPath = new Path(); 1361 domPath.moveTo(domPoints[0].x, domPoints[0].y); 1362 if (domPoints[1] != null) 1363 { 1364 domPath.lineTo(domPoints[1].x, domPoints[1].y); 1365 } 1366 if (domPoints[2] != null) 1367 { 1368 domPath.lineTo(domPoints[2].x, domPoints[2].y); 1369 } 1370 ctx.drawPath(domPath, domPaint); 1371 1372 domPath.reset(); 1373 domPaint.setStyle(Style.FILL); 1374 domPath.moveTo(domPoints[3].x, domPoints[3].y); 1375 domPath.lineTo(domPoints[4].x, domPoints[4].y); 1376 domPath.lineTo(domPoints[5].x, domPoints[5].y); 1377 ctx.drawPath(domPath, domPaint); 1378 } 1379 1380 private static Rect processOperationalConditionIndicator(String symbolID, Rect symbolBounds, int offsetY) 1381 { 1382 //create Operational Condition Indicator 1383 //set color 1384 Rect bar = null; 1385 char status; 1386 Color statusColor; 1387 int barSize = 0; 1388 int pixelSize = symbolBounds.height(); 1389 1390 status = symbolID.charAt(3); 1391 1392 if (status == 'C' || status == 'D' || status == 'X' || status == 'F') 1393 { 1394 if (pixelSize > 0) 1395 { 1396 barSize = Math.round(pixelSize / 5); 1397 } 1398 1399 if (barSize < 2) 1400 { 1401 barSize = 2; 1402 } 1403 1404 offsetY += Math.round(symbolBounds.top + symbolBounds.height()); 1405 1406 bar = RectUtilities.makeRect(symbolBounds.left + 2, offsetY, Math.round(symbolBounds.width()) - 4, barSize); 1407 } 1408 1409 return bar; 1410 } 1411 1412 private static Path processOperationalConditionIndicatorSlash(String symbolID, Rect symbolBounds) 1413 { 1414 //create Operational Condition Indicator 1415 Path path = null; 1416 char status; 1417 status = symbolID.charAt(3); 1418 1419 if (status == 'D' || status == 'X') 1420 { 1421 int fillCode = UnitFontLookup.getFillCode(symbolID,RendererSettings.Symbology_2525C); 1422 float widthRatio = UnitFontLookup.getUnitRatioWidth(fillCode); 1423 float heightRatio = UnitFontLookup.getUnitRatioHeight(fillCode); 1424 1425 float slashHeight = (symbolBounds.height() / heightRatio * 1.47f); 1426 float slashWidth = (symbolBounds.width() / widthRatio * 0.85f); 1427 float centerX = symbolBounds.exactCenterX(); 1428 float centerY = symbolBounds.exactCenterY(); 1429 path = new Path(); 1430 if(status == 'D')//Damaged / 1431 { 1432 path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2)); 1433 path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2)); 1434 } 1435 else if(status == 'X')//Destroyed X 1436 { 1437 path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2)); 1438 path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2)); 1439 path.moveTo(centerX - (slashWidth/2),centerY-(slashHeight/2)); 1440 path.lineTo(centerX + (slashWidth/2),centerY+(slashHeight/2)); 1441 } 1442 return path; 1443 1444 } 1445 1446 return path; 1447 } 1448 1449 public static ImageInfo processUnitTextModifiers(ImageInfo ii, String symbolID, SparseArray<String> modifiers, SparseArray<String> attributes) 1450 { 1451 1452 int bufferXL = 5; 1453 int bufferXR = 5; 1454 int bufferY = 2; 1455 int bufferText = 2; 1456 int x = 0; 1457 int y = 0;//best y 1458 int cpofNameX = 0; 1459 ImageInfo newii = null; 1460 int alpha = -1; 1461 1462 Color textColor = Color.BLACK; 1463 Color textBackgroundColor = null; 1464 1465 ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size()); 1466 1467 int descent = (int) (_modifierFontDescent + 0.5); 1468 1469 int symStd = RS.getSymbologyStandard(); 1470 if (attributes.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0) 1471 { 1472 symStd = Integer.parseInt(attributes.get(MilStdAttributes.SymbologyStandard)); 1473 } 1474 if (attributes.indexOfKey(MilStdAttributes.Alpha) >= 0) 1475 { 1476 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 1477 } 1478 1479 Rect labelBounds = null; 1480 int labelWidth, labelHeight; 1481 1482 Rect bounds = new Rect(ii.getSymbolBounds()); 1483 Rect symbolBounds = new Rect(ii.getSymbolBounds()); 1484 Point centerPoint = new Point(ii.getCenterPoint()); 1485 Rect imageBounds = new Rect(ii.getImageBounds()); 1486 Rect imageBoundsOld = new Rect(ii.getImageBounds()); 1487 1488 String echelon = SymbolUtilities.getEchelon(symbolID); 1489 String echelonText = SymbolUtilities.getEchelonText(echelon); 1490 String amText = SymbolUtilities.getUnitAffiliationModifier(symbolID, symStd); 1491 1492 //make room for echelon & mobility. 1493 if (modifiers.indexOfKey(ModifiersUnits.Q_DIRECTION_OF_MOVEMENT) < 0 || SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.Q_DIRECTION_OF_MOVEMENT)==false) 1494 { 1495 //if no DOM, we can just use the image bounds 1496 bounds = RectUtilities.makeRect(imageBounds.left, symbolBounds.top, 1497 imageBounds.width(), symbolBounds.height()); 1498 } 1499 else //dom exists so we need to change our math 1500 { 1501 if (echelonText != null || amText != null) 1502 { 1503 bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, 1504 imageBounds.width(), bounds.height()); 1505 } 1506 else if (symbolID.substring(10, 12).equals("MR")) 1507 { 1508 x = -(Math.round((symbolBounds.width() - 1) / 7) * 2); 1509 if (x < bounds.left) 1510 { 1511 bounds.set(x, 0, bounds.right, bounds.bottom); 1512 //bounds.shiftTL(x,0); 1513 } 1514 } 1515 } 1516 1517 cpofNameX = bounds.left + bounds.width() + bufferXR; 1518 1519 //check if text is too tall: 1520 boolean byLabelHeight = false; 1521 labelHeight = (int) (_modifierFontHeight + 0.5);/* RendererUtilities.measureTextHeight(RendererSettings.getModifierFontName(), 1522 RendererSettings.getModifierFontSize(), 1523 RendererSettings.getModifierFontStyle()).fullHeight;*/ 1524 1525 int maxHeight = (bounds.height()); 1526 if ((labelHeight * 3) > maxHeight) 1527 { 1528 byLabelHeight = true; 1529 } 1530 1531 //Affiliation Modifier being drawn as a display modifier 1532 String affiliationModifier = null; 1533 if (RS.getDrawAffiliationModifierAsLabel() == true) 1534 { 1535 affiliationModifier = SymbolUtilities.getUnitAffiliationModifier(symbolID, symStd); 1536 } 1537 if (affiliationModifier != null) 1538 { //Set affiliation modifier 1539 modifiers.put(ModifiersUnits.E_FRAME_SHAPE_MODIFIER, affiliationModifier); 1540 //modifiers[ModifiersUnits.E_FRAME_SHAPE_MODIFIER] = affiliationModifier; 1541 }//*/ 1542 1543 //Check for Valid Country Code 1544 if (SymbolUtilities.hasValidCountryCode(symbolID)) 1545 { 1546 modifiers.put(ModifiersUnits.CC_COUNTRY_CODE, symbolID.substring(12, 14)); 1547 //modifiers[ModifiersUnits.CC_COUNTRY_CODE] = symbolID.substring(12,14); 1548 } 1549 1550 // int y0 = 0;//W E/F 1551 // int y1 = 0;//X/Y G 1552 // int y2 = 0;//V/AD/AE H/AF 1553 // int y3 = 0;//T M CC 1554 // int y4 = 0;//Z J/K/L/N/P 1555 // 1556 // y0 = bounds.y - 0; 1557 // y1 = bounds.y - labelHeight; 1558 // y2 = bounds.y - (labelHeight + (int)bufferText) * 2; 1559 // y3 = bounds.y - (labelHeight + (int)bufferText) * 3; 1560 // y4 = bounds.y - (labelHeight + (int)bufferText) * 4; 1561 // <editor-fold defaultstate="collapsed" desc="Build Modifiers"> 1562 String modifierValue = null; 1563 TextInfo tiTemp = null; 1564 //if(ModifiersUnits.C_QUANTITY in modifiers 1565 if (modifiers.indexOfKey(ModifiersUnits.C_QUANTITY) >= 0 1566 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.C_QUANTITY)) 1567 { 1568 String text = modifiers.get(ModifiersUnits.C_QUANTITY); 1569 if(text != null) 1570 { 1571 //bounds = armyc2.c2sd.renderer.utilities.RendererUtilities.getTextOutlineBounds(_modifierFont, text, new SO.Point(0,0)); 1572 tiTemp = new TextInfo(text, 0, 0, _modifierFont); 1573 labelBounds = tiTemp.getTextBounds(); 1574 labelWidth = labelBounds.width(); 1575 x = Math.round((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f)); 1576 y = Math.round(symbolBounds.top - bufferY - descent); 1577 tiTemp.setLocation(x, y); 1578 tiArray.add(tiTemp); 1579 } 1580 } 1581 1582 //if(ModifiersUnits.X_ALTITUDE_DEPTH in modifiers || ModifiersUnits.Y_LOCATION in modifiers) 1583 if (modifiers.indexOfKey(ModifiersUnits.X_ALTITUDE_DEPTH) >= 0 || modifiers.indexOfKey(ModifiersUnits.Y_LOCATION) >= 0) 1584 { 1585 modifierValue = null; 1586 1587 String xm = null, 1588 ym = null; 1589 1590 if (modifiers.indexOfKey(ModifiersUnits.X_ALTITUDE_DEPTH) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.X_ALTITUDE_DEPTH)) 1591 { 1592 xm = modifiers.get(ModifiersUnits.X_ALTITUDE_DEPTH);// xm = modifiers.X; 1593 } 1594 if (modifiers.indexOfKey(ModifiersUnits.Y_LOCATION) >= 0) 1595 { 1596 ym = modifiers.get(ModifiersUnits.Y_LOCATION);// ym = modifiers.Y; 1597 } 1598 if (xm == null && ym != null) 1599 { 1600 modifierValue = ym; 1601 } 1602 else if (xm != null && ym == null) 1603 { 1604 modifierValue = xm; 1605 } 1606 else if (xm != null && ym != null) 1607 { 1608 modifierValue = xm + " " + ym; 1609 } 1610 1611 if(modifierValue != null) 1612 { 1613 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1614 labelBounds = tiTemp.getTextBounds(); 1615 labelWidth = labelBounds.width(); 1616 1617 if (!byLabelHeight) 1618 { 1619 x = bounds.left - labelBounds.width() - bufferXL; 1620 y = bounds.top + labelHeight - descent; 1621 } 1622 else 1623 { 1624 x = bounds.left - labelBounds.width() - bufferXL; 1625 1626 y = (bounds.height()); 1627 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 1628 1629 y = y - ((labelHeight + bufferText)); 1630 y = bounds.top + y; 1631 } 1632 1633 tiTemp.setLocation(x, y); 1634 tiArray.add(tiTemp); 1635 } 1636 } 1637 1638 if (modifiers.indexOfKey(ModifiersUnits.G_STAFF_COMMENTS) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.G_STAFF_COMMENTS)) 1639 { 1640 modifierValue = modifiers.get(ModifiersUnits.G_STAFF_COMMENTS); 1641 1642 if(modifierValue != null) 1643 { 1644 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1645 labelBounds = tiTemp.getTextBounds(); 1646 labelWidth = labelBounds.width(); 1647 1648 x = bounds.left + bounds.width() + bufferXR; 1649 if (!byLabelHeight) 1650 { 1651 y = bounds.top + labelHeight - descent; 1652 } 1653 else 1654 { 1655 y = (bounds.height()); 1656 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 1657 1658 y = y - ((labelHeight + bufferText)); 1659 y = bounds.top + y; 1660 } 1661 1662 tiTemp.setLocation(x, y); 1663 tiArray.add(tiTemp); 1664 1665 //Concession for cpof name label 1666 if ((x + labelWidth + 3) > cpofNameX) 1667 { 1668 cpofNameX = x + labelWidth + 3; 1669 } 1670 } 1671 } 1672 1673 if ((modifiers.indexOfKey(ModifiersUnits.V_EQUIP_TYPE) >= 0) || 1674 (modifiers.indexOfKey(ModifiersUnits.AD_PLATFORM_TYPE) >= 0) || 1675 (modifiers.indexOfKey(ModifiersUnits.AE_EQUIPMENT_TEARDOWN_TIME) >= 0)) 1676 { 1677 String vm = null, 1678 adm = null, 1679 aem = null; 1680 1681 if (modifiers.indexOfKey(ModifiersUnits.V_EQUIP_TYPE) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.V_EQUIP_TYPE)) 1682 { 1683 vm = modifiers.get(ModifiersUnits.V_EQUIP_TYPE); 1684 } 1685 if (modifiers.indexOfKey(ModifiersUnits.AD_PLATFORM_TYPE) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.AD_PLATFORM_TYPE)) 1686 { 1687 adm = modifiers.get(ModifiersUnits.AD_PLATFORM_TYPE); 1688 } 1689 if (modifiers.indexOfKey(ModifiersUnits.AE_EQUIPMENT_TEARDOWN_TIME) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.AE_EQUIPMENT_TEARDOWN_TIME)) 1690 { 1691 aem = modifiers.get(ModifiersUnits.AE_EQUIPMENT_TEARDOWN_TIME); 1692 } 1693 1694 modifierValue = ""; 1695 if(vm != null && vm.equals("") == false) 1696 modifierValue = vm; 1697 if(adm != null && adm.equals("") == false) 1698 modifierValue += " " + adm; 1699 if(aem != null && aem.equals("") == false) 1700 modifierValue += " " + aem; 1701 1702 if(modifierValue != null) 1703 modifierValue = modifierValue.trim(); 1704 if(modifierValue != null && modifierValue.equals("") == false) 1705 { 1706 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1707 labelBounds = tiTemp.getTextBounds(); 1708 labelWidth = labelBounds.width(); 1709 1710 x = bounds.left - labelBounds.width() - bufferXL; 1711 1712 y = (bounds.height()); 1713 y = (int) ((y * 0.5f) + ((labelHeight - descent) * 0.5f)); 1714 y = bounds.top + y; 1715 1716 tiTemp.setLocation(x, y); 1717 tiArray.add(tiTemp); 1718 } 1719 } 1720 1721 if (modifiers.indexOfKey(ModifiersUnits.H_ADDITIONAL_INFO_1) >= 0 || modifiers.indexOfKey(ModifiersUnits.AF_COMMON_IDENTIFIER) >= 0) 1722 { 1723 modifierValue = ""; 1724 String hm = "", 1725 afm = ""; 1726 1727 hm = modifiers.get(ModifiersUnits.H_ADDITIONAL_INFO_1); 1728 if (modifiers.indexOfKey(ModifiersUnits.H_ADDITIONAL_INFO_1) >= 0) 1729 { 1730 hm = modifiers.get(ModifiersUnits.H_ADDITIONAL_INFO_1); 1731 } 1732 if (modifiers.indexOfKey(ModifiersUnits.AF_COMMON_IDENTIFIER) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.AF_COMMON_IDENTIFIER)) 1733 { 1734 afm = modifiers.get(ModifiersUnits.AF_COMMON_IDENTIFIER); 1735 } 1736 1737 modifierValue = hm + " " + afm; 1738 modifierValue = modifierValue.trim(); 1739 1740 if(modifierValue != null && modifierValue.equals("") == false) 1741 { 1742 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1743 labelBounds = tiTemp.getTextBounds(); 1744 labelWidth = labelBounds.width(); 1745 1746 x = bounds.left + bounds.width() + bufferXR; 1747 1748 y = (bounds.height()); 1749 y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5)); 1750 y = bounds.top + y; 1751 1752 tiTemp.setLocation(x, y); 1753 tiArray.add(tiTemp); 1754 1755 //Concession for cpof name label 1756 if ((x + labelWidth + 3) > cpofNameX) 1757 { 1758 cpofNameX = x + labelWidth + 3; 1759 } 1760 } 1761 } 1762 1763 if (modifiers.indexOfKey(ModifiersUnits.T_UNIQUE_DESIGNATION_1) >= 0) 1764 { 1765 modifierValue = modifiers.get(ModifiersUnits.T_UNIQUE_DESIGNATION_1); 1766 1767 if(modifierValue != null) 1768 { 1769 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1770 labelBounds = tiTemp.getTextBounds(); 1771 labelWidth = labelBounds.width(); 1772 1773 if (!byLabelHeight) 1774 { 1775 x = bounds.left - labelWidth - bufferXL; 1776 y = bounds.top + bounds.height(); 1777 } 1778 else 1779 { 1780 x = bounds.left - labelWidth - bufferXL; 1781 1782 y = (bounds.height()); 1783 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 1784 1785 y = y + ((labelHeight + bufferText) - descent); 1786 y = bounds.top + y; 1787 } 1788 1789 tiTemp.setLocation(x, y); 1790 tiArray.add(tiTemp); 1791 } 1792 } 1793 1794 if (modifiers.indexOfKey(ModifiersUnits.M_HIGHER_FORMATION) >= 0 || modifiers.indexOfKey(ModifiersUnits.CC_COUNTRY_CODE) >= 0) 1795 { 1796 modifierValue = ""; 1797 1798 if (modifiers.indexOfKey(ModifiersUnits.M_HIGHER_FORMATION) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.M_HIGHER_FORMATION)) 1799 { 1800 modifierValue += modifiers.get(ModifiersUnits.M_HIGHER_FORMATION); 1801 } 1802 if (modifiers.indexOfKey(ModifiersUnits.CC_COUNTRY_CODE) >= 0) 1803 { 1804 if (modifierValue.length() > 0) 1805 { 1806 modifierValue += " "; 1807 } 1808 modifierValue += modifiers.get(ModifiersUnits.CC_COUNTRY_CODE); 1809 } 1810 1811 if(modifierValue.equals("")==false) 1812 { 1813 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1814 labelBounds = tiTemp.getTextBounds(); 1815 labelWidth = labelBounds.width(); 1816 1817 x = bounds.left + bounds.width() + bufferXR; 1818 if (!byLabelHeight) 1819 { 1820 y = bounds.top + bounds.height(); 1821 } 1822 else 1823 { 1824 y = (bounds.height()); 1825 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 1826 1827 y = y + ((labelHeight + bufferText - descent)); 1828 y = bounds.top + y; 1829 } 1830 1831 tiTemp.setLocation(x, y); 1832 tiArray.add(tiTemp); 1833 1834 //Concession for cpof name label 1835 if ((x + labelWidth + 3) > cpofNameX) 1836 { 1837 cpofNameX = x + labelWidth + 3; 1838 } 1839 } 1840 } 1841 1842 if (modifiers.indexOfKey(ModifiersUnits.Z_SPEED) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.Z_SPEED)) 1843 { 1844 modifierValue = modifiers.get(ModifiersUnits.Z_SPEED); 1845 1846 if(modifierValue != null) 1847 { 1848 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1849 labelBounds = tiTemp.getTextBounds(); 1850 labelWidth = labelBounds.width(); 1851 1852 x = bounds.left - labelWidth - bufferXL; 1853 if (!byLabelHeight) 1854 { 1855 y = Math.round(bounds.top + bounds.height() + labelHeight + bufferText); 1856 } 1857 else 1858 { 1859 y = (bounds.height()); 1860 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 1861 1862 y = y + ((labelHeight + bufferText) * 2) - (descent * 2); 1863 y = Math.round(bounds.top + y); 1864 } 1865 1866 tiTemp.setLocation(x, y); 1867 tiArray.add(tiTemp); 1868 } 1869 } 1870 1871 if (modifiers.indexOfKey(ModifiersUnits.J_EVALUATION_RATING) >= 0 1872 || modifiers.indexOfKey(ModifiersUnits.K_COMBAT_EFFECTIVENESS) >= 0// 1873 || modifiers.indexOfKey(ModifiersUnits.L_SIGNATURE_EQUIP) >= 0// 1874 || modifiers.indexOfKey(ModifiersUnits.N_HOSTILE) >= 0// 1875 || modifiers.indexOfKey(ModifiersUnits.P_IFF_SIF) >= 0)// 1876 { 1877 modifierValue = null; 1878 1879 String jm = null, 1880 km = null, 1881 lm = null, 1882 nm = null, 1883 pm = null; 1884 1885 if (modifiers.indexOfKey(ModifiersUnits.J_EVALUATION_RATING) >= 0) 1886 { 1887 jm = modifiers.get(ModifiersUnits.J_EVALUATION_RATING); 1888 } 1889 if (modifiers.indexOfKey(ModifiersUnits.K_COMBAT_EFFECTIVENESS) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.K_COMBAT_EFFECTIVENESS)) 1890 { 1891 km = modifiers.get(ModifiersUnits.K_COMBAT_EFFECTIVENESS); 1892 } 1893 if (modifiers.indexOfKey(ModifiersUnits.L_SIGNATURE_EQUIP) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.L_SIGNATURE_EQUIP)) 1894 { 1895 lm = modifiers.get(ModifiersUnits.L_SIGNATURE_EQUIP); 1896 } 1897 if (modifiers.indexOfKey(ModifiersUnits.N_HOSTILE) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.N_HOSTILE)) 1898 { 1899 nm = modifiers.get(ModifiersUnits.N_HOSTILE); 1900 } 1901 if (modifiers.indexOfKey(ModifiersUnits.P_IFF_SIF) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.P_IFF_SIF)) 1902 { 1903 pm = modifiers.get(ModifiersUnits.P_IFF_SIF); 1904 } 1905 1906 modifierValue = ""; 1907 if (jm != null && jm.equals("") == false) 1908 { 1909 modifierValue = modifierValue + jm; 1910 } 1911 if (km != null && km.equals("") == false) 1912 { 1913 modifierValue = modifierValue + " " + km; 1914 } 1915 if (lm != null && lm.equals("") == false) 1916 { 1917 modifierValue = modifierValue + " " + lm; 1918 } 1919 if (nm != null && nm.equals("") == false) 1920 { 1921 modifierValue = modifierValue + " " + nm; 1922 } 1923 if (pm != null && pm.equals("") == false) 1924 { 1925 modifierValue = modifierValue + " " + pm; 1926 } 1927 1928 if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ') 1929 { 1930 modifierValue = modifierValue.substring(1); 1931 } 1932 1933 modifierValue = modifierValue.trim(); 1934 1935 if(modifierValue.equals("")==false) 1936 { 1937 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1938 labelBounds = tiTemp.getTextBounds(); 1939 labelWidth = labelBounds.width(); 1940 1941 x = bounds.left + bounds.width() + bufferXR; 1942 if (!byLabelHeight) 1943 { 1944 y = Math.round(bounds.top + bounds.height() + labelHeight + bufferText); 1945 } 1946 else 1947 { 1948 y = (bounds.height()); 1949 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 1950 1951 y = y + ((labelHeight + bufferText) * 2) - (descent * 2); 1952 y = Math.round(bounds.top + y); 1953 } 1954 1955 tiTemp.setLocation(x, y); 1956 tiArray.add(tiTemp); 1957 1958 //Concession for cpof name label 1959 if ((x + labelWidth + 3) > cpofNameX) 1960 { 1961 cpofNameX = x + labelWidth + 3; 1962 } 1963 } 1964 1965 } 1966 1967 if (modifiers.indexOfKey(ModifiersUnits.W_DTG_1) >= 0) 1968 { 1969 modifierValue = modifiers.get(ModifiersUnits.W_DTG_1); 1970 1971 if(modifierValue != null) 1972 { 1973 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 1974 labelBounds = tiTemp.getTextBounds(); 1975 labelWidth = labelBounds.width(); 1976 1977 if (!byLabelHeight) 1978 { 1979 x = bounds.left - labelWidth - bufferXL; 1980 y = bounds.top - bufferY - descent; 1981 } 1982 else 1983 { 1984 x = bounds.left - labelWidth - bufferXL; 1985 1986 y = (bounds.height()); 1987 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 1988 1989 y = y - ((labelHeight + bufferText) * 2); 1990 y = bounds.top + y; 1991 } 1992 1993 tiTemp.setLocation(x, y); 1994 tiArray.add(tiTemp); 1995 } 1996 } 1997 1998 if (modifiers.indexOfKey(ModifiersUnits.F_REINFORCED_REDUCED) >= 0 || modifiers.indexOfKey(ModifiersUnits.E_FRAME_SHAPE_MODIFIER) >= 0) 1999 { 2000 modifierValue = null; 2001 String E = null, 2002 F = null; 2003 2004 if (modifiers.indexOfKey(ModifiersUnits.E_FRAME_SHAPE_MODIFIER) >= 0) 2005 { 2006 E = modifiers.get(ModifiersUnits.E_FRAME_SHAPE_MODIFIER); 2007 modifiers.delete(ModifiersUnits.E_FRAME_SHAPE_MODIFIER); 2008 } 2009 if (modifiers.indexOfKey(ModifiersUnits.F_REINFORCED_REDUCED) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.F_REINFORCED_REDUCED)) 2010 { 2011 F = modifiers.get(ModifiersUnits.F_REINFORCED_REDUCED); 2012 } 2013 2014 if (E != null && E.equals("") == false) 2015 { 2016 modifierValue = E; 2017 } 2018 2019 if (F != null && F.equals("") == false) 2020 { 2021 if (F.toUpperCase(Locale.US) == ("R")) 2022 { 2023 F = "(+)"; 2024 } 2025 else if (F.toUpperCase(Locale.US) == ("D")) 2026 { 2027 F = "(-)"; 2028 } 2029 else if (F.toUpperCase(Locale.US) == ("RD")) 2030 { 2031 F = "(" + (char) (177) + ")"; 2032 } 2033 } 2034 2035 if (F != null && F.equals("") == false) 2036 { 2037 if (modifierValue != null && modifierValue.equals("") == false) 2038 { 2039 modifierValue = modifierValue + " " + F; 2040 } 2041 else 2042 { 2043 modifierValue = F; 2044 } 2045 } 2046 2047 if(modifierValue != null) 2048 { 2049 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 2050 labelBounds = tiTemp.getTextBounds(); 2051 labelWidth = labelBounds.width(); 2052 2053 if (!byLabelHeight) 2054 { 2055 x = bounds.left + bounds.width() + bufferXR; 2056 y = bounds.top - bufferY - descent; 2057 } 2058 else 2059 { 2060 x = bounds.left + bounds.width() + bufferXR; 2061 2062 y = (bounds.height()); 2063 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2064 2065 y = y - ((labelHeight + bufferText) * 2); 2066 y = bounds.top + y; 2067 } 2068 2069 tiTemp.setLocation(x, y); 2070 tiArray.add(tiTemp); 2071 2072 //Concession for cpof name label 2073 if ((x + labelWidth + 3) > cpofNameX) 2074 { 2075 cpofNameX = x + labelWidth + 3; 2076 } 2077 } 2078 } 2079 2080 if (modifiers.indexOfKey(ModifiersUnits.AA_SPECIAL_C2_HQ) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.AA_SPECIAL_C2_HQ)) 2081 { 2082 modifierValue = modifiers.get(ModifiersUnits.AA_SPECIAL_C2_HQ); 2083 2084 if(modifierValue != null) 2085 { 2086 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 2087 labelBounds = tiTemp.getTextBounds(); 2088 labelWidth = labelBounds.width(); 2089 2090 x = (int) ((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f)); 2091 2092 y = (symbolBounds.height());//checkpoint, get box above the point 2093 y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5)); 2094 y = symbolBounds.top + y; 2095 2096 tiTemp.setLocation(x, y); 2097 tiArray.add(tiTemp); 2098 } 2099 } 2100 2101 if (modifiers.indexOfKey(ModifiersUnits.SCC_SONAR_CLASSIFICATION_CONFIDENCE) >= 0 && SymbolUtilities.canUnitHaveModifier(symbolID, ModifiersUnits.SCC_SONAR_CLASSIFICATION_CONFIDENCE)) 2102 { 2103 int scc = 0; 2104 modifierValue = modifiers.get(ModifiersUnits.SCC_SONAR_CLASSIFICATION_CONFIDENCE); 2105 2106 if(modifierValue != null && SymbolUtilities.isNumber(modifierValue) && SymbolUtilities.hasModifier(symbolID, ModifiersUnits.SCC_SONAR_CLASSIFICATION_CONFIDENCE)) 2107 { 2108 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 2109 labelBounds = tiTemp.getTextBounds(); 2110 labelWidth = labelBounds.width(); 2111 2112 x = (int) ((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f)); 2113 2114 double yPosition = getYPositionForSCC(symbolID); 2115 y = (bounds.height() );//checkpoint, get box above the point 2116 y = (int)(((y * yPosition) + ((labelHeight-descent) * 0.5))); 2117 y = bounds.top + y; 2118 2119 tiTemp.setLocation(x, y); 2120 tiArray.add(tiTemp); 2121 } 2122 } 2123 2124 if (modifiers.indexOfKey(ModifiersUnits.CN_CPOF_NAME_LABEL) >= 0) 2125 { 2126 modifierValue = modifiers.get(ModifiersUnits.CN_CPOF_NAME_LABEL); 2127 2128 if(modifierValue != null) 2129 { 2130 tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont); 2131 labelBounds = tiTemp.getTextBounds(); 2132 labelWidth = labelBounds.width(); 2133 2134 x = cpofNameX; 2135 2136 y = (bounds.height());//checkpoint, get box above the point 2137 y = (int) ((y * 0.5) + (labelHeight * 0.5)); 2138 y = bounds.top + y; 2139 2140 tiTemp.setLocation(x, y); 2141 tiArray.add(tiTemp); 2142 } 2143 } 2144 2145 // </editor-fold> 2146 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 2147 Rect modifierBounds = null; 2148 if (tiArray != null && tiArray.size() > 0) 2149 { 2150 2151 //build modifier bounds///////////////////////////////////////// 2152 modifierBounds = tiArray.get(0).getTextOutlineBounds(); 2153 int size = tiArray.size(); 2154 TextInfo tempShape = null; 2155 for (int i = 1; i < size; i++) 2156 { 2157 tempShape = tiArray.get(i); 2158 modifierBounds.union(tempShape.getTextOutlineBounds()); 2159 } 2160 2161 } 2162 2163 if (modifierBounds != null) 2164 { 2165 2166 imageBounds.union(modifierBounds); 2167 2168 //shift points if needed//////////////////////////////////////// 2169 if (imageBounds.left < 0 || imageBounds.top < 0) 2170 { 2171 int shiftX = Math.round(Math.abs(imageBounds.left)), 2172 shiftY = Math.round(Math.abs(imageBounds.top)); 2173 2174 //shift mobility points 2175 int size = tiArray.size(); 2176 TextInfo tempShape = null; 2177 for (int i = 0; i < size; i++) 2178 { 2179 tempShape = tiArray.get(i); 2180 tempShape.shift(shiftX, shiftY); 2181 } 2182 RectUtilities.shift(modifierBounds, shiftX, shiftY); 2183 //modifierBounds.shift(shiftX,shiftY); 2184 2185 //shift image points 2186 centerPoint.offset(shiftX, shiftY); 2187 RectUtilities.shift(symbolBounds, shiftX, shiftY); 2188 RectUtilities.shift(imageBounds, shiftX, shiftY); 2189 RectUtilities.shift(imageBoundsOld, shiftX, shiftY); 2190 /*centerPoint.shift(shiftX, shiftY); 2191 symbolBounds.shift(shiftX, shiftY); 2192 imageBounds.shift(shiftX, shiftY); 2193 imageBoundsOld.shift(shiftX, shiftY);//*/ 2194 } 2195 2196 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 2197 Canvas ctx = new Canvas(bmp); 2198 2199 //render//////////////////////////////////////////////////////// 2200 //draw original icon with potential modifiers. 2201 ctx.drawBitmap(ii.getImage(), imageBoundsOld.left, imageBoundsOld.top, null); 2202 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 2203 2204 2205 if (attributes.indexOfKey(MilStdAttributes.TextColor) >= 0) 2206 { 2207 textColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 2208 if(alpha > -1) 2209 textColor.setAlpha(alpha); 2210 } 2211 if (attributes.indexOfKey(MilStdAttributes.TextBackgroundColor) >= 0) 2212 { 2213 textBackgroundColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 2214 if(alpha > -1) 2215 textBackgroundColor.setAlpha(alpha); 2216 } 2217 2218 renderText(ctx, tiArray, textColor, textBackgroundColor); 2219 2220 newii = new ImageInfo(bmp, centerPoint, symbolBounds); 2221 2222 } 2223 // </editor-fold> 2224 2225 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 2226 tiArray = null; 2227 tiTemp = null; 2228 //tempShape = null; 2229 imageBoundsOld = null; 2230 //ctx = null; 2231 //buffer = null; 2232 // </editor-fold> 2233 2234 return newii; 2235 } 2236 2237 public static ImageInfo ProcessTGSPWithSpecialModifierLayout(ImageInfo ii, String symbolID, SparseArray<String> modifiers, SparseArray<String> attributes, Color lineColor) 2238 { 2239 int bufferXL = 6; 2240 int bufferXR = 4; 2241 int bufferY = 2; 2242 int bufferText = 2; 2243 int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel 2244 int x = 0; 2245 int y = 0; 2246 int x2 = 0; 2247 int y2 = 0; 2248 int symStd = RS.getSymbologyStandard(); 2249 int outlineOffset = RS.getTextOutlineWidth(); 2250 int labelHeight = 0; 2251 int labelWidth = 0; 2252 int alpha = -1; 2253 ImageInfo newii = null; 2254 Color textColor = lineColor; 2255 Color textBackgroundColor = null; 2256 2257 ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>(); 2258 boolean duplicate = false; 2259 2260 Rect bounds = new Rect(ii.getSymbolBounds()); 2261 Rect symbolBounds = new Rect(ii.getSymbolBounds()); 2262 Point centerPoint = new Point(ii.getCenterPoint()); 2263 Rect imageBounds = new Rect(ii.getImageBounds()); 2264 2265 if (attributes.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0) 2266 { 2267 symStd = Integer.parseInt(attributes.get(MilStdAttributes.SymbologyStandard)); 2268 } 2269 if (attributes.indexOfKey(MilStdAttributes.Alpha) >= 0) 2270 { 2271 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 2272 textColor.setAlpha(alpha); 2273 } 2274 2275 centerPoint = new Point(Math.round(ii.getCenterPoint().x), Math.round(ii.getCenterPoint().y)); 2276 2277 boolean byLabelHeight = false; 2278 labelHeight = (int) (_modifierFontHeight + 0.5f); 2279 2280 int maxHeight = (symbolBounds.height()); 2281 if ((labelHeight * 3) > maxHeight) 2282 { 2283 byLabelHeight = true; 2284 } 2285 2286 int descent = (int) (_modifierFontDescent + 0.5f); 2287 int yForY = -1; 2288 2289 Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0); 2290 Rect labelBounds2 = null; 2291 String strText = ""; 2292 String strText1 = ""; 2293 String strText2 = ""; 2294 TextInfo text1 = null; 2295 TextInfo text2 = null; 2296 2297 String basicID = SymbolUtilities.getBasicSymbolID(symbolID); 2298 2299 if (outlineOffset > 2) 2300 { 2301 outlineOffset = ((outlineOffset - 1) / 2); 2302 } 2303 else 2304 { 2305 outlineOffset = 0; 2306 } 2307 2308 // <editor-fold defaultstate="collapsed" desc="Process Integral Text"> 2309 if (basicID.equals("G*G*GPRD--****X"))//DLRP (D) 2310 { 2311 2312 strText1 = "D"; 2313 2314 text1 = new TextInfo(strText1, 0, 0, _modifierFont); 2315 2316 labelBounds1 = text1.getTextBounds(); 2317 if (symStd == RendererSettings.Symbology_2525B) 2318 { 2319 y = symbolBounds.top + symbolBounds.height(); 2320 x = symbolBounds.left - labelBounds1.width() - bufferXL; 2321 text1.setLocation(Math.round(x), Math.round(y)); 2322 } 2323 else//2525C built in 2324 { 2325 text1 = null; 2326 //y = symbolBounds.top + symbolBounds.getHeight() - bufferY; 2327 //x = symbolBounds.left + symbolBounds.width()/2 - labelBounds1.getWidth()/2; 2328 } 2329 2330 //ErrorLogger.LogMessage("D: " + String.valueOf(x)+ ", " + String.valueOf(y)); 2331 } 2332 else if (basicID.equals("G*G*APU---****X")) //pull-up point (PUP) 2333 { 2334 strText1 = "PUP"; 2335 text1 = new TextInfo(strText1, 0, 0, _modifierFont); 2336 2337 labelBounds1 = text1.getTextBounds(); 2338 y = RectUtilities.getCenterY(symbolBounds) + ((labelBounds1.height() - descent) / 2); 2339 x = symbolBounds.left + symbolBounds.width() + bufferXR; 2340 2341 text1.setLocation(Math.round(x), Math.round(y)); 2342 } 2343 else if (basicID.equals("G*M*NZ----****X")) //Nuclear Detonation Ground Zero (N) 2344 { 2345// strText1 = "N"; 2346// text1 = new TextLayout(strText1, labelFont, frc); 2347// labelBounds1 = text1.getPixelBounds(null, 0, 0); 2348// y = symbolBounds.top + (symbolBounds.getHeight() * 0.8) - centerOffset; 2349// x = symbolBounds.getCenterX() - centerOffset - (labelBounds1.getWidth()/2); 2350 } 2351 else if (basicID.equals("G*M*NF----****X"))//Fallout Producing (N) 2352 { 2353// strText1 = "N"; 2354// text1 = new TextLayout(strText1, labelFont, frc); 2355// descent = text1.getDescent(); 2356// labelBounds1 = text1.getPixelBounds(null, 0, 0); 2357// y = symbolBounds.top + (symbolBounds.getHeight() * 0.8) - centerOffset; 2358// x = symbolBounds.getCenterX() - centerOffset - (labelBounds1.getWidth()/2); 2359 } 2360 else if (basicID.equals("G*M*NEB---****X"))//Release Events Biological (BIO, B) 2361 { 2362 //strText1 = "B"; 2363 //text1 = new TextLayout(strText1, labelFont, frc); 2364 int offset = 1; 2365 strText2 = "BIO"; 2366 text2 = new TextInfo(strText2, 0, 0, _modifierFont); 2367 2368 labelBounds2 = text2.getTextBounds(); 2369 //y = symbolBounds.top + (symbolBounds.getHeight() * 0.9); 2370 //x = symbolBounds.getCenterX() - centerOffset - (labelBounds1.getWidth()/2); 2371 2372 y2 = (int) (RectUtilities.getCenterY(symbolBounds) + ((labelBounds2.height() - descent) * 0.5f)); 2373 2374 x2 = symbolBounds.left - labelBounds2.width() - bufferXL; 2375 2376 text2.setLocation(Math.round(x2), Math.round(y2 - offset)); 2377 //ErrorLogger.LogMessage("BIO: " + String.valueOf(x2)+ ", " + String.valueOf(y2)); 2378 } 2379 else if (basicID.equals("G*M*NEC---****X"))//Release Events Chemical (CML, C) 2380 { 2381 //strText1 = "C"; 2382 //text1 = new TextLayout(strText1, labelFont, frc); 2383 int offset = 1; 2384 strText2 = "CML"; 2385 text2 = new TextInfo(strText2, 0, 0, _modifierFont); 2386 2387 labelBounds2 = text2.getTextBounds(); 2388 //y = symbolBounds.top + (symbolBounds.getHeight() * 0.9); 2389 //x = symbolBounds.getCenterX() - centerOffset - (labelBounds1.getWidth()/2); 2390 2391 y2 = RectUtilities.getCenterY(symbolBounds) + ((labelBounds2.height() - descent) / 2); 2392 2393 x2 = symbolBounds.left - labelBounds2.width() - bufferXL; 2394 2395 text2.setLocation(Math.round(x2), Math.round(y2 - offset)); 2396 } 2397 if (text1 != null) 2398 { 2399 arrMods.add(text1); 2400 } 2401 if (text2 != null) 2402 { 2403 arrMods.add(text2); 2404 } 2405 2406 // </editor-fold> 2407 // <editor-fold defaultstate="collapsed" desc="Process Special Modifiers"> 2408 TextInfo ti = null; 2409 if (basicID.equals("G*M*NZ----****X") ||//ground zero 2410 basicID.equals("G*M*NEB---****X") ||//biological 2411 basicID.equals("G*M*NEC---****X"))//chemical 2412 { 2413 if ((labelHeight * 3) > bounds.height()) 2414 { 2415 byLabelHeight = true; 2416 } 2417 } 2418 2419 if (basicID.equals("G*G*GPPC--****X") 2420 || basicID.equals("G*G*GPPD--****X")) 2421 { 2422 if (modifiers.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0) 2423 { 2424 strText = modifiers.get(ModifiersTG.T_UNIQUE_DESIGNATION_1); 2425 if(strText != null) 2426 { 2427 ti = new TextInfo(strText, 0, 0, _modifierFont); 2428 labelWidth = Math.round(ti.getTextBounds().width()); 2429 //One modifier symbols and modifier goes in center 2430 x = bounds.left + (int) (bounds.width() * 0.5f); 2431 x = x - (int) (labelWidth * 0.5f); 2432 y = bounds.top + (int) (bounds.height() * 0.4f); 2433 y = y + (int) (labelHeight * 0.5f); 2434 2435 ti.setLocation(Math.round(x), Math.round(y)); 2436 arrMods.add(ti); 2437 } 2438 } 2439 } 2440 else if (basicID.equals("G*G*GPH---****X")) 2441 { 2442 if (modifiers.indexOfKey(ModifiersTG.H_ADDITIONAL_INFO_1) >= 0) 2443 { 2444 strText = modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1); 2445 if(strText != null) 2446 { 2447 ti = new TextInfo(strText, 0, 0, _modifierFont); 2448 labelWidth = Math.round(ti.getTextBounds().width()); 2449 //One modifier symbols and modifier goes in center 2450 x = bounds.left + (int) (bounds.width() * 0.5f); 2451 x = x - (int) (labelWidth * 0.5f); 2452 y = bounds.top + (int) (bounds.height() * 0.5f); 2453 y = y + (int) (labelHeight * 0.5f); 2454 2455 ti.setLocation(Math.round(x), Math.round(y)); 2456 arrMods.add(ti); 2457 } 2458 } 2459 } 2460 else if (basicID.equals("G*G*GPRI--****X")) 2461 { 2462 if (modifiers.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0) 2463 { 2464 strText = modifiers.get(ModifiersTG.T_UNIQUE_DESIGNATION_1); 2465 if(strText != null) 2466 { 2467 ti = new TextInfo(strText, 0, 0, _modifierFont); 2468 labelWidth = Math.round(ti.getTextBounds().width()); 2469 //One modifier symbols, top third & center 2470 x = bounds.left + (int) (bounds.width() * 0.5f); 2471 x = x - (int) (labelWidth * 0.5f); 2472 y = bounds.top + (int) (bounds.height() * 0.25f); 2473 y = y + (int) (labelHeight * 0.5f); 2474 2475 ti.setLocation(Math.round(x), Math.round(y)); 2476 arrMods.add(ti); 2477 } 2478 } 2479 } 2480 else if (basicID.equals("G*G*GPPW--****X") 2481 || basicID.equals("G*F*PCF---****X")) 2482 { 2483 if (modifiers.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0) 2484 { 2485 strText = modifiers.get(ModifiersTG.T_UNIQUE_DESIGNATION_1); 2486 if(strText != null) 2487 { 2488 ti = new TextInfo(strText, 0, 0, _modifierFont); 2489 2490 //One modifier symbols and modifier goes right of center 2491 x = bounds.left + (int) (bounds.width() * 0.75f); 2492 y = bounds.top + (int) (bounds.height() * 0.5f); 2493 y = y + (int) ((labelHeight - descent) * 0.5f); 2494 2495 ti.setLocation(Math.round(x), Math.round(y)); 2496 arrMods.add(ti); 2497 } 2498 } 2499 } 2500 else if (basicID.equals("G*G*APP---****X") 2501 || basicID.equals("G*G*APC---****X")) 2502 { 2503 if (modifiers.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0) 2504 { 2505 strText = modifiers.get(ModifiersTG.T_UNIQUE_DESIGNATION_1); 2506 if(strText != null) 2507 { 2508 ti = new TextInfo(strText, 0, 0, _modifierFont); 2509 labelWidth = ti.getTextBounds().width(); 2510 //One modifier symbols and modifier goes just below of center 2511 x = bounds.left + (int) (bounds.width() * 0.5); 2512 x = x - (int) (labelWidth * 0.5); 2513 y = bounds.top + (int) (bounds.height() * 0.5f); 2514 y = y + (int) (((bounds.height() * 0.5f) - labelHeight) / 2) + labelHeight - descent; 2515 2516 ti.setLocation(Math.round(x), Math.round(y)); 2517 arrMods.add(ti); 2518 } 2519 } 2520 } 2521 else if (basicID.equals("G*G*DPT---****X") || //T (target reference point) 2522 basicID.equals("G*F*PTS---****X") || //t,h,h1 (Point/Single Target) 2523 basicID.equals("G*F*PTN---****X")) //T (nuclear target) 2524 { //Targets with special modifier positions 2525 if (modifiers.indexOfKey(ModifiersTG.H_ADDITIONAL_INFO_1) >= 0 2526 && basicID.equals("G*F*PTS---****X"))//H 2527 { 2528 strText = modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1); 2529 if(strText != null) 2530 { 2531 ti = new TextInfo(strText, 0, 0, _modifierFont); 2532 2533 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 2534 y = bounds.top + (int) (bounds.height() * 0.75f); 2535 y = y + (int) (labelHeight * 0.5f); 2536 2537 ti.setLocation(Math.round(x), Math.round(y)); 2538 arrMods.add(ti); 2539 } 2540 } 2541 if (modifiers.indexOfKey(ModifiersTG.H1_ADDITIONAL_INFO_2) >= 0 2542 && basicID.equals("G*F*PTS---****X"))//H1 2543 { 2544 strText = modifiers.get(ModifiersTG.H1_ADDITIONAL_INFO_2); 2545 if(strText != null) 2546 { 2547 ti = new TextInfo(strText, 0, 0, _modifierFont); 2548 labelWidth = Math.round(ti.getTextBounds().width()); 2549 x = RectUtilities.getCenterX(bounds) - (int) (bounds.width() * 0.15f); 2550 x = x - (labelWidth); 2551 y = bounds.top + (int) (bounds.height() * 0.75f); 2552 y = y + (int) (labelHeight * 0.5f); 2553 2554 ti.setLocation(Math.round(x), Math.round(y)); 2555 arrMods.add(ti); 2556 } 2557 } 2558 if (modifiers.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0) 2559 { 2560 strText = modifiers.get(ModifiersTG.T_UNIQUE_DESIGNATION_1); 2561 if(strText != null) 2562 { 2563 ti = new TextInfo(strText, 0, 0, _modifierFont); 2564 2565 x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f); 2566// x = x - (labelBounds.width * 0.5); 2567 y = bounds.top + (int) (bounds.height() * 0.25f); 2568 y = y + (int) (labelHeight * 0.5f); 2569 2570 ti.setLocation(Math.round(x), Math.round(y)); 2571 arrMods.add(ti); 2572 } 2573 } 2574 2575 } 2576 else if (basicID.equals("G*M*NZ----****X") ||//ground zero 2577 basicID.equals("G*M*NEB---****X") ||//biological 2578 basicID.equals("G*M*NEC---****X"))//chemical 2579 {//NBC 2580 if (modifiers.indexOfKey(ModifiersTG.N_HOSTILE) >= 0) 2581 { 2582 strText = modifiers.get(ModifiersTG.N_HOSTILE); 2583 if(strText != null) 2584 { 2585 ti = new TextInfo(strText, 0, 0, _modifierFont); 2586 2587 x = bounds.left + bounds.width() + bufferXR; 2588 2589 if (!byLabelHeight) 2590 { 2591 y = bounds.top + bounds.height(); 2592 } 2593 else 2594 { 2595 y = bounds.top + (int) ((bounds.height() * 0.5f) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText)); 2596 } 2597 2598 ti.setLocation(Math.round(x), Math.round(y)); 2599 arrMods.add(ti); 2600 } 2601 2602 } 2603 if (modifiers.indexOfKey(ModifiersTG.H_ADDITIONAL_INFO_1) >= 0) 2604 { 2605 strText = modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1); 2606 if(strText != null) 2607 { 2608 ti = new TextInfo(strText, 0, 0, _modifierFont); 2609 2610 x = bounds.left + bounds.width() + bufferXR; 2611 if (!byLabelHeight) 2612 { 2613 y = bounds.top + labelHeight - descent; 2614 } 2615 else 2616 { 2617 //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 2618 y = bounds.top + (int) ((bounds.height() * 0.5f) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)); 2619 } 2620 2621 ti.setLocation(Math.round(x), Math.round(y)); 2622 arrMods.add(ti); 2623 } 2624 } 2625 if (modifiers.indexOfKey(ModifiersTG.W_DTG_1) >= 0) 2626 { 2627 strText = modifiers.get(ModifiersTG.W_DTG_1); 2628 if(strText != null) 2629 { 2630 ti = new TextInfo(strText, 0, 0, _modifierFont); 2631 labelWidth = Math.round(ti.getTextBounds().width()); 2632 2633 x = bounds.left - labelWidth - bufferXL; 2634 if (!byLabelHeight) 2635 { 2636 y = bounds.top + labelHeight - descent; 2637 } 2638 else 2639 { 2640 //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText)); 2641 y = bounds.top + (int) ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)); 2642 } 2643 2644 ti.setLocation(Math.round(x), Math.round(y)); 2645 arrMods.add(ti); 2646 } 2647 } 2648 if (basicID.equals("G*M*NZ----****X") == true && modifiers.indexOfKey(ModifiersTG.V_EQUIP_TYPE) >= 0) 2649 { 2650 strText = modifiers.get(ModifiersTG.V_EQUIP_TYPE); 2651 if(strText != null) 2652 { 2653 ti = new TextInfo(strText, 0, 0, _modifierFont); 2654 2655 //subset of nbc, just nuclear 2656 labelWidth = Math.round(ti.getTextBounds().width()); 2657 x = bounds.left - labelWidth - bufferXL; 2658 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5));//((bounds.height / 2) - (labelHeight/2)); 2659 2660 ti.setLocation(Math.round(x), Math.round(y)); 2661 arrMods.add(ti); 2662 } 2663 } 2664 if (modifiers.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0) 2665 { 2666 strText = modifiers.get(ModifiersTG.T_UNIQUE_DESIGNATION_1); 2667 if(strText != null) 2668 { 2669 ti = new TextInfo(strText, 0, 0, _modifierFont); 2670 labelWidth = Math.round(ti.getTextBounds().width()); 2671 x = bounds.left - labelWidth - bufferXL; 2672 if (!byLabelHeight) 2673 { 2674 y = bounds.top + bounds.height(); 2675 } 2676 else 2677 { 2678 //y = bounds.y + ((bounds.height * 0.5) + ((labelHeight-descent) * 0.5) + (labelHeight + bufferText)); 2679 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText)); 2680 } 2681 ti.setLocation(Math.round(x), Math.round(y)); 2682 arrMods.add(ti); 2683 } 2684 } 2685 if (modifiers.indexOfKey(ModifiersTG.Y_LOCATION) >= 0) 2686 { 2687 strText = modifiers.get(ModifiersTG.Y_LOCATION); 2688 if(strText != null) 2689 { 2690 ti = new TextInfo(strText, 0, 0, _modifierFont); 2691 labelWidth = Math.round(ti.getTextBounds().width()); 2692 //just NBC 2693 //x = bounds.getX() + (bounds.getWidth() * 0.5); 2694 //x = x - (labelWidth * 0.5); 2695 x = bounds.left + (int) (bounds.width() * 0.5f); 2696 x = x - (int) (labelWidth * 0.5f); 2697 2698 if (!byLabelHeight) 2699 { 2700 y = bounds.top + bounds.height() + labelHeight - descent + bufferY; 2701 } 2702 else 2703 { 2704 y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + ((labelHeight + bufferText) * 2) - descent); 2705 2706 } 2707 yForY = y + descent; //so we know where to start the DOM arrow. 2708 ti.setLocation(Math.round(x), Math.round(y)); 2709 arrMods.add(ti); 2710 } 2711 2712 } 2713 if (modifiers.indexOfKey(ModifiersTG.C_QUANTITY) >= 0) 2714 { 2715 strText = modifiers.get(ModifiersTG.C_QUANTITY); 2716 if(strText != null) 2717 { 2718 ti = new TextInfo(strText, 0, 0, _modifierFont); 2719 labelWidth = Math.round(ti.getTextBounds().width()); 2720 //subset of NBC, just nuclear 2721 x = bounds.left + (int) (bounds.width() * 0.5); 2722 x = x - (int) (labelWidth * 0.5); 2723 y = bounds.top - descent; 2724 ti.setLocation(Math.round(x), Math.round(y)); 2725 arrMods.add(ti); 2726 } 2727 2728 } 2729 } 2730 else if (basicID.equals("G*M*OFS---****X")) 2731 { 2732 if (modifiers.indexOfKey(ModifiersTG.H_ADDITIONAL_INFO_1) >= 0) 2733 { 2734 strText = modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1); 2735 if(strText != null) 2736 { 2737 ti = new TextInfo(strText, 0, 0, _modifierFont); 2738 labelWidth = Math.round(ti.getTextBounds().width()); 2739 x = bounds.left + (int) (bounds.width() * 0.5); 2740 x = x - (int) (labelWidth * 0.5); 2741 y = bounds.top - descent;// + (bounds.height * 0.5); 2742 //y = y + (labelHeight * 0.5); 2743 2744 ti.setLocation(Math.round(x), Math.round(y)); 2745 arrMods.add(ti); 2746 } 2747 2748 } 2749 if (modifiers.indexOfKey(ModifiersTG.W_DTG_1) >= 0) 2750 { 2751 strText = modifiers.get(ModifiersTG.W_DTG_1); 2752 if(strText != null) 2753 { 2754 ti = new TextInfo(strText, 0, 0, _modifierFont); 2755 labelWidth = Math.round(ti.getTextBounds().width()); 2756 x = bounds.left + (int) (bounds.width() * 0.5); 2757 x = x - (int) (labelWidth * 0.5); 2758 y = bounds.top + (bounds.height()); 2759 y = y + (labelHeight); 2760 2761 ti.setLocation(Math.round(x), Math.round(y)); 2762 arrMods.add(ti); 2763 } 2764 } 2765 if (modifiers.indexOfKey(ModifiersTG.N_HOSTILE) >= 0) 2766 { 2767 strText = modifiers.get(ModifiersTG.N_HOSTILE); 2768 if(strText != null) 2769 { 2770 ti = new TextInfo(strText, 0, 0, _modifierFont); 2771 TextInfo ti2 = new TextInfo(strText, 0, 0, _modifierFont); 2772 labelWidth = Math.round(ti.getTextBounds().width()); 2773 x = bounds.left + (bounds.width()) + bufferXR;//right 2774 //x = x + labelWidth;//- (labelBounds.width * 0.75); 2775 2776 duplicate = true; 2777 2778 x2 = bounds.left;//left 2779 x2 = x2 - labelWidth - bufferXL;// - (labelBounds.width * 0.25); 2780 2781 y = bounds.top + (int) (bounds.height() * 0.5);//center 2782 y = y + (int) ((labelHeight - descent) * 0.5); 2783 2784 y2 = y; 2785 2786 ti.setLocation(Math.round(x), Math.round(y)); 2787 ti2.setLocation(Math.round(x2), Math.round(y2)); 2788 arrMods.add(ti); 2789 arrMods.add(ti2); 2790 } 2791 } 2792 2793 } 2794 else if(basicID.charAt(0) == 'W') 2795 { 2796 String modX = null; 2797 if(modifiers.indexOfKey(ModifiersTG.X_ALTITUDE_DEPTH) > -1) 2798 modX = (modifiers.get(ModifiersTG.X_ALTITUDE_DEPTH)); 2799 2800 if(basicID.equals("WAS-WSF-LVP----"))//Freezing Level 2801 { 2802 strText = "0" + (char)(176) + ":"; 2803 if(modX != null) 2804 strText += modX; 2805 else 2806 strText += "?"; 2807 2808 ti = new TextInfo(strText, 0, 0, _modifierFont); 2809 labelWidth = Math.round(ti.getTextBounds().width()); 2810 //One modifier symbols and modifier goes in center 2811 x = bounds.left + (int) (bounds.width() * 0.5f); 2812 x = x - (int) (labelWidth * 0.5f); 2813 y = bounds.top + (int) (bounds.height() * 0.5f); 2814 y = y + (int) ((labelHeight - _modifierFontDescent) * 0.5f); 2815 2816 ti.setLocation(Math.round(x), Math.round(y)); 2817 arrMods.add(ti); 2818 } 2819 else if(basicID.equals("WAS-WST-LVP----"))//tropopause Level 2820 { 2821 strText = "X?"; 2822 if(modX != null) 2823 strText = modX; 2824 2825 ti = new TextInfo(strText, 0, 0, _modifierFont); 2826 labelWidth = Math.round(ti.getTextBounds().width()); 2827 //One modifier symbols and modifier goes in center 2828 x = bounds.left + (int) (bounds.width() * 0.5f); 2829 x = x - (int) (labelWidth * 0.5f); 2830 y = bounds.top + (int) (bounds.height() * 0.5f); 2831 y = y + (int) ((labelHeight - _modifierFontDescent) * 0.5f); 2832 2833 ti.setLocation(Math.round(x), Math.round(y)); 2834 arrMods.add(ti); 2835 } 2836 else if(basicID.equals("WAS-PLT---P----"))//tropopause Low 2837 { 2838 strText = "X?"; 2839 if(modX != null) 2840 strText = modX; 2841 2842 ti = new TextInfo(strText, 0, 0, _modifierFont); 2843 labelWidth = Math.round(ti.getTextBounds().width()); 2844 //One modifier symbols and modifier goes in center 2845 x = bounds.left + (int) (bounds.width() * 0.5f); 2846 x = x - (int) (labelWidth * 0.5f); 2847 y = bounds.top + (int) (bounds.height() * 0.5f); 2848 y = y - descent; 2849 2850 ti.setLocation(Math.round(x), Math.round(y)); 2851 arrMods.add(ti); 2852 } 2853 else if(basicID.equals("WAS-PHT---P----"))//tropopause High 2854 { 2855 strText = "X?"; 2856 if(modX != null) 2857 strText = modX; 2858 2859 ti = new TextInfo(strText, 0, 0, _modifierFont); 2860 labelWidth = Math.round(ti.getTextBounds().width()); 2861 //One modifier symbols and modifier goes in center 2862 x = bounds.left + (int) (bounds.width() * 0.5f); 2863 x = x - (int) (labelWidth * 0.5f); 2864 y = bounds.top + (int) (bounds.height() * 0.5f); 2865 //y = y + (int) ((labelHeight * 0.5f) + (labelHeight/2)); 2866 y = y + (int) (((labelHeight * 0.5f) - (labelHeight/2)) + labelHeight - descent); 2867 2868 ti.setLocation(Math.round(x), Math.round(y)); 2869 arrMods.add(ti); 2870 } 2871 } 2872 // </editor-fold> 2873 2874 // <editor-fold defaultstate="collapsed" desc="DOM Arrow"> 2875 Point[] domPoints = null; 2876 Rect domBounds = null; 2877 if (modifiers.indexOfKey(ModifiersTG.Q_DIRECTION_OF_MOVEMENT) >= 0 2878 && (basicID.equals("G*M*NZ----****X") ||//ground zero 2879 basicID.equals("G*M*NEB---****X") ||//biological 2880 basicID.equals("G*M*NEC---****X")))//chemical) 2881 { 2882 strText = modifiers.get(ModifiersTG.Q_DIRECTION_OF_MOVEMENT); 2883 if(strText != null && SymbolUtilities.isNumber(strText)) 2884 { 2885 float q = Float.parseFloat(strText); 2886 Rect tempBounds = new Rect(bounds); 2887 tempBounds.union(RectUtilities.getCenterX(bounds), yForY); 2888 2889 domPoints = createDOMArrowPoints(symbolID, tempBounds, ii.getCenterPoint(), q, false); 2890 2891 domBounds = RectUtilities.makeRect(domPoints[0].x, domPoints[0].y, 1, 1); 2892 2893 Point temp = null; 2894 for (int i = 1; i < 6; i++) 2895 { 2896 temp = domPoints[i]; 2897 if (temp != null) 2898 { 2899 domBounds.union(temp.x, temp.y); 2900 } 2901 } 2902 imageBounds.union(domBounds); 2903 } 2904 } 2905 // </editor-fold> 2906 2907 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 2908 Rect modifierBounds = null; 2909 if (arrMods != null && arrMods.size() > 0) 2910 { 2911 2912 //build modifier bounds///////////////////////////////////////// 2913 modifierBounds = arrMods.get(0).getTextOutlineBounds(); 2914 int size = arrMods.size(); 2915 TextInfo tempShape = null; 2916 for (int i = 1; i < size; i++) 2917 { 2918 tempShape = arrMods.get(i); 2919 modifierBounds.union(tempShape.getTextOutlineBounds()); 2920 } 2921 2922 } 2923 2924 if (modifierBounds != null || domBounds != null) 2925 { 2926 2927 if (modifierBounds != null) 2928 { 2929 imageBounds.union(modifierBounds); 2930 } 2931 if (domBounds != null) 2932 { 2933 imageBounds.union(domBounds); 2934 } 2935 2936 //shift points if needed//////////////////////////////////////// 2937 if (imageBounds.left < 0 || imageBounds.top < 0) 2938 { 2939 int shiftX = Math.abs(imageBounds.left); 2940 int shiftY = Math.abs(imageBounds.top); 2941 2942 //shift mobility points 2943 int size = arrMods.size(); 2944 TextInfo tempShape = null; 2945 for (int i = 0; i < size; i++) 2946 { 2947 tempShape = arrMods.get(i); 2948 tempShape.shift(shiftX, shiftY); 2949 } 2950 modifierBounds.offset(shiftX, shiftY); 2951 2952 if (domBounds != null) 2953 { 2954 for (int i = 0; i < 6; i++) 2955 { 2956 Point temp = domPoints[i]; 2957 if (temp != null) 2958 { 2959 temp.offset(shiftX, shiftY); 2960 } 2961 } 2962 domBounds.offset(shiftX, shiftY); 2963 } 2964 2965 //shift image points 2966 centerPoint.offset(shiftX, shiftY); 2967 symbolBounds.offset(shiftX, shiftY); 2968 imageBounds.offset(shiftX, shiftY); 2969 } 2970 2971 //Render modifiers////////////////////////////////////////////////// 2972 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 2973 Canvas ctx = new Canvas(bmp); 2974 2975 //render//////////////////////////////////////////////////////// 2976 //draw original icon with potential modifiers. 2977 ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null); 2978 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 2979 2980 if (attributes.indexOfKey(MilStdAttributes.TextColor) >= 0) 2981 { 2982 textColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 2983 if(alpha > -1) 2984 textColor.setAlpha(alpha); 2985 } 2986 if (attributes.indexOfKey(MilStdAttributes.TextBackgroundColor) >= 0) 2987 { 2988 textBackgroundColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 2989 if(alpha > -1) 2990 textBackgroundColor.setAlpha(alpha); 2991 } 2992 2993 2994 2995 renderText(ctx, arrMods, textColor, textBackgroundColor); 2996 2997 newii = new ImageInfo(bmp, centerPoint, symbolBounds); 2998 2999 //draw DOM arrow 3000 if (domBounds != null) 3001 { 3002 drawDOMArrow(ctx, domPoints, alpha, lineColor); 3003 } 3004 3005 newii = new ImageInfo(bmp, centerPoint, symbolBounds); 3006 3007 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 3008 ctx = null; 3009 // </editor-fold> 3010 3011 return newii; 3012 3013 } 3014 else 3015 { 3016 return null; 3017 } 3018 // </editor-fold> 3019 3020 } 3021 3022 public static ImageInfo ProcessTGSPModifiers(ImageInfo ii, String symbolID, SparseArray<String> modifiers, SparseArray<String> attributes, Color lineColor) 3023 { 3024 3025 // <editor-fold defaultstate="collapsed" desc="Variables"> 3026 int bufferXL = 6; 3027 int bufferXR = 4; 3028 int bufferY = 2; 3029 int bufferText = 2; 3030 int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel 3031 int x = 0; 3032 int y = 0; 3033 int x2 = 0; 3034 int y2 = 0; 3035 int symStd = RS.getSymbologyStandard(); 3036 int outlineOffset = RS.getTextOutlineWidth(); 3037 int labelHeight = 0; 3038 int labelWidth = 0; 3039 int alpha = -1; 3040 ImageInfo newii = null; 3041 3042 Color textColor = lineColor; 3043 Color textBackgroundColor = null; 3044 3045 ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>(); 3046 boolean duplicate = false; 3047 3048 if (attributes.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0) 3049 { 3050 symStd = Integer.parseInt(attributes.get(MilStdAttributes.SymbologyStandard)); 3051 } 3052 if (attributes.indexOfKey(MilStdAttributes.Alpha) >= 0) 3053 { 3054 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 3055 } 3056 3057 Rect bounds = new Rect(ii.getSymbolBounds()); 3058 Rect symbolBounds = new Rect(ii.getSymbolBounds()); 3059 Point centerPoint = new Point(ii.getCenterPoint()); 3060 Rect imageBounds = new Rect(ii.getImageBounds()); 3061 3062 centerPoint = new Point(Math.round(ii.getCenterPoint().x), Math.round(ii.getCenterPoint().y)); 3063 3064 boolean byLabelHeight = false; 3065 3066 labelHeight = Math.round(_modifierFontHeight + 0.5f); 3067 int maxHeight = (symbolBounds.height()); 3068 if ((labelHeight * 3) > maxHeight) 3069 { 3070 byLabelHeight = true; 3071 } 3072 3073 int descent = (int) (_modifierFontDescent + 0.5f); 3074 int yForY = -1; 3075 3076 Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0); 3077 Rect labelBounds2 = null; 3078 String strText = ""; 3079 String strText1 = ""; 3080 String strText2 = ""; 3081 TextInfo text1 = null; 3082 TextInfo text2 = null; 3083 3084 String basicID = SymbolUtilities.getBasicSymbolID(symbolID); 3085 3086 if (outlineOffset > 2) 3087 { 3088 outlineOffset = ((outlineOffset - 1) / 2); 3089 } 3090 else 3091 { 3092 outlineOffset = 0; 3093 } 3094 3095 /*bufferXL += outlineOffset; 3096 bufferXR += outlineOffset; 3097 bufferY += outlineOffset; 3098 bufferText += outlineOffset;*/ 3099 // </editor-fold> 3100 // <editor-fold defaultstate="collapsed" desc="Process Modifiers"> 3101 TextInfo ti = null; 3102 3103 { 3104 if (modifiers.indexOfKey(ModifiersTG.N_HOSTILE) >= 0) 3105 { 3106 strText = modifiers.get(ModifiersTG.N_HOSTILE); 3107 if(strText != null) 3108 { 3109 ti = new TextInfo(strText, 0, 0, _modifierFont); 3110 3111 x = bounds.left + bounds.width() + bufferXR; 3112 3113 if (!byLabelHeight) 3114 { 3115 y = ((bounds.height() / 3) * 2);//checkpoint, get box above the point 3116 y = bounds.top + y; 3117 } 3118 else 3119 { 3120 //y = ((labelHeight + bufferText) * 3); 3121 //y = bounds.y + y - descent; 3122 y = bounds.top + bounds.height(); 3123 } 3124 3125 ti.setLocation(x, y); 3126 arrMods.add(ti); 3127 } 3128 3129 } 3130 if (modifiers.indexOfKey(ModifiersTG.H_ADDITIONAL_INFO_1) >= 0) 3131 { 3132 strText = modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1); 3133 if(strText != null) 3134 { 3135 ti = new TextInfo(strText, 0, 0, _modifierFont); 3136 labelWidth = Math.round(ti.getTextBounds().width()); 3137 3138 x = bounds.left + (int) (bounds.width() * 0.5f); 3139 x = x - (int) (labelWidth * 0.5f); 3140 y = bounds.top - descent; 3141 3142 ti.setLocation(x, y); 3143 arrMods.add(ti); 3144 } 3145 } 3146 if (modifiers.indexOfKey(ModifiersTG.H1_ADDITIONAL_INFO_2) >= 0) 3147 { 3148 strText = modifiers.get(ModifiersTG.H1_ADDITIONAL_INFO_2); 3149 if(strText != null) 3150 { 3151 ti = new TextInfo(strText, 0, 0, _modifierFont); 3152 labelWidth = Math.round(ti.getTextBounds().width()); 3153 3154 x = bounds.left + (int) (bounds.width() * 0.5); 3155 x = x - (int) (labelWidth * 0.5); 3156 y = bounds.top + labelHeight + (int) (bounds.height() * 0.2); 3157 3158 ti.setLocation(x, y); 3159 arrMods.add(ti); 3160 } 3161 } 3162 if (modifiers.indexOfKey(ModifiersTG.W_DTG_1) >= 0) 3163 { 3164 strText = modifiers.get(ModifiersTG.W_DTG_1); 3165 if(strText != null) 3166 { 3167 ti = new TextInfo(strText, 0, 0, _modifierFont); 3168 labelWidth = Math.round(ti.getTextBounds().width()); 3169 3170 x = bounds.left - labelWidth - bufferXL; 3171 y = bounds.top + labelHeight - descent; 3172 3173 ti.setLocation(x, y); 3174 arrMods.add(ti); 3175 } 3176 } 3177 if (modifiers.indexOfKey(ModifiersTG.W1_DTG_2) >= 0) 3178 { 3179 strText = modifiers.get(ModifiersTG.W1_DTG_2); 3180 if(strText != null) 3181 { 3182 ti = new TextInfo(strText, 0, 0, _modifierFont); 3183 labelWidth = Math.round(ti.getTextBounds().width()); 3184 3185 x = bounds.left - labelWidth - bufferXL; 3186 3187 y = ((labelHeight - descent + bufferText) * 2); 3188 y = bounds.top + y; 3189 3190 ti.setLocation(x, y); 3191 arrMods.add(ti); 3192 } 3193 } 3194 if (modifiers.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0) 3195 { 3196 strText = modifiers.get(ModifiersTG.T_UNIQUE_DESIGNATION_1); 3197 if(strText != null) 3198 { 3199 ti = new TextInfo(strText, 0, 0, _modifierFont); 3200 3201 x = bounds.left + bounds.width() + bufferXR; 3202 y = bounds.top + labelHeight - descent; 3203 3204 ti.setLocation(x, y); 3205 arrMods.add(ti); 3206 } 3207 } 3208 if ((modifiers.indexOfKey(ModifiersTG.T1_UNIQUE_DESIGNATION_2) >= 0) &&//T1 3209 (basicID.equals("G*O*ES----****X") || //emergency distress call 3210 basicID.equals("G*S*PP----****X") || //medevac pick-up point 3211 basicID.equals("G*S*PX----****X")))//ambulance exchange point 3212 { 3213 strText = modifiers.get(ModifiersTG.T1_UNIQUE_DESIGNATION_2); 3214 if(strText != null) 3215 { 3216 ti = new TextInfo(strText, 0, 0, _modifierFont); 3217 labelWidth = Math.round(ti.getTextBounds().width()); 3218 3219 //points 3220 x = bounds.left + (int) (bounds.width() * 0.5); 3221 x = x - (int) (labelWidth * 0.5); 3222 //y = bounds.y + (bounds.height * 0.5); 3223 3224 y = (int) ((bounds.height() * 0.60));//633333333 3225 y = bounds.top + y; 3226 3227 ti.setLocation(x, y); 3228 arrMods.add(ti); 3229 } 3230 } 3231 3232 } 3233 3234 // </editor-fold> 3235 // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw"> 3236 Rect modifierBounds = null; 3237 if (arrMods != null && arrMods.size() > 0) 3238 { 3239 3240 //build modifier bounds///////////////////////////////////////// 3241 modifierBounds = arrMods.get(0).getTextOutlineBounds(); 3242 int size = arrMods.size(); 3243 TextInfo tempShape = null; 3244 for (int i = 1; i < size; i++) 3245 { 3246 tempShape = arrMods.get(i); 3247 modifierBounds.union(tempShape.getTextOutlineBounds()); 3248 } 3249 3250 } 3251 3252 if (modifierBounds != null) 3253 { 3254 3255 imageBounds.union(modifierBounds); 3256 3257 //shift points if needed//////////////////////////////////////// 3258 if (imageBounds.left < 0 || imageBounds.top < 0) 3259 { 3260 int shiftX = Math.abs(imageBounds.left); 3261 int shiftY = Math.abs(imageBounds.top); 3262 3263 //shift mobility points 3264 int size = arrMods.size(); 3265 TextInfo tempShape = null; 3266 for (int i = 0; i < size; i++) 3267 { 3268 tempShape = arrMods.get(i); 3269 tempShape.shift(shiftX, shiftY); 3270 } 3271 modifierBounds.offset(shiftX, shiftY); 3272 3273 //shift image points 3274 centerPoint.offset(shiftX, shiftY); 3275 symbolBounds.offset(shiftX, shiftY); 3276 imageBounds.offset(shiftX, shiftY); 3277 } 3278 3279 //Render modifiers////////////////////////////////////////////////// 3280 Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888); 3281 Canvas ctx = new Canvas(bmp); 3282 3283 //draw original icon with potential modifiers. 3284 ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null); 3285 //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top); 3286 3287 if (attributes.indexOfKey(MilStdAttributes.TextColor) >= 0) 3288 { 3289 textColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor)); 3290 if(alpha > -1) 3291 textColor.setAlpha(alpha); 3292 } 3293 if (attributes.indexOfKey(MilStdAttributes.TextBackgroundColor) >= 0) 3294 { 3295 textBackgroundColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor)); 3296 if(alpha > -1) 3297 textBackgroundColor.setAlpha(alpha); 3298 } 3299 3300 3301 renderText(ctx, arrMods, textColor, textBackgroundColor); 3302 3303 newii = new ImageInfo(bmp, centerPoint, symbolBounds); 3304 3305 // <editor-fold defaultstate="collapsed" desc="Cleanup"> 3306 ctx = null; 3307 3308 // </editor-fold> 3309 } 3310 // </editor-fold> 3311 return newii; 3312 3313 } 3314 3315 private static void renderText(Canvas ctx, ArrayList<TextInfo> tiArray, Color color, Color backgroundColor) 3316 { 3317 ModifierRenderer.renderText(ctx, (TextInfo[]) tiArray.toArray(new TextInfo[0]), color, backgroundColor); 3318 } 3319 3320 /** 3321 * 3322 * @param ctx 3323 * @param tiArray 3324 * @param color 3325 * @param backgroundColor 3326 */ 3327 public static void renderText(Canvas ctx, TextInfo[] tiArray, Color color, Color backgroundColor) 3328 { 3329 /*for (TextInfo textInfo : tiArray) 3330 { 3331 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont); 3332 }*/ 3333 3334 int size = tiArray.length; 3335 3336 int tbm = RS.getTextBackgroundMethod(); 3337 int outlineWidth = RS.getTextOutlineWidth(); 3338 3339 if (color == null) 3340 { 3341 color = Color.BLACK; 3342 } 3343 3344 Color outlineColor = null; 3345 3346 if(backgroundColor != null) 3347 outlineColor = backgroundColor; 3348 else 3349 outlineColor = RendererUtilities.getIdealOutlineColor(color); 3350 3351 try { 3352 3353 if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE_QUICK) 3354 { 3355 //draw text outline 3356 synchronized (_ModifierFontMutex) { 3357 _modifierFont.setStyle(Style.FILL); 3358 _modifierFont.setStrokeWidth(RS.getTextOutlineWidth()); 3359 _modifierFont.setColor(outlineColor.toInt()); 3360 if (outlineWidth > 0) { 3361 for (int i = 0; i < size; i++) { 3362 TextInfo textInfo = tiArray[i]; 3363 if (outlineWidth > 0) { 3364 for (int j = 1; j <= outlineWidth; j++) { 3365 if (j % 2 == 1) { 3366 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, _modifierFont); 3367 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, _modifierFont); 3368 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, _modifierFont); 3369 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, _modifierFont); 3370 } else { 3371 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, _modifierFont); 3372 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, _modifierFont); 3373 ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, _modifierFont); 3374 ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, _modifierFont); 3375 } 3376 3377 } 3378 3379 } 3380 3381 } 3382 } 3383 //draw text 3384 _modifierFont.setColor(color.toInt()); 3385 3386 for (int j = 0; j < size; j++) { 3387 TextInfo textInfo = tiArray[j]; 3388 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont); 3389 /*Paint outline = new Paint(); 3390 outline.setStyle(Style.STROKE); 3391 outline.setColor(Color.red.toInt()); 3392 outline.setAlpha(155); 3393 outline.setStrokeWidth(1f); 3394 ctx.drawRect(textInfo.getTextBounds(), outline); 3395 outline.setColor(Color.blue.toInt()); 3396 ctx.drawRect(textInfo.getTextOutlineBounds(), outline);//*/ 3397 } 3398 } 3399 } else if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE) { 3400 synchronized (_ModifierFontMutex) { 3401 //draw text outline 3402 //draw text outline 3403 _modifierFont.setStyle(Style.STROKE); 3404 _modifierFont.setStrokeWidth(RS.getTextOutlineWidth()); 3405 _modifierFont.setColor(outlineColor.toInt()); 3406 int i = 0; 3407 3408 if (outlineWidth > 0) { 3409 for (i = 0; i < size; i++) { 3410 TextInfo textInfo = tiArray[i]; 3411 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont); 3412 //ErrorLogger.LogMessage("Draw outline " + textInfo.getText() + ", " + String.valueOf(i + 1) + " of " + String.valueOf(size) + "\n ", Level.WARNING, false); 3413 } 3414 } 3415 3416 //draw text 3417 _modifierFont.setColor(color.toInt()); 3418 _modifierFont.setStyle(Style.FILL); 3419 3420 for (int j = 0; j < size; j++) { 3421 TextInfo textInfo = tiArray[j]; 3422 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont); 3423 } 3424 } 3425 3426 } else if (tbm == RendererSettings.TextBackgroundMethod_COLORFILL) { 3427 synchronized (_ModifierFontMutex) { 3428 Paint rectFill = new Paint(); 3429 rectFill.setStyle(Paint.Style.FILL); 3430 rectFill.setColor(outlineColor.toARGB()); 3431 3432 3433 //draw rectangle 3434 for (int k = 0; k < size; k++) { 3435 TextInfo textInfo = tiArray[k]; 3436 ctx.drawRect(textInfo.getTextOutlineBounds(), rectFill); 3437 } 3438 //draw text 3439 _modifierFont.setColor(color.toInt()); 3440 _modifierFont.setStyle(Style.FILL); 3441 for (int j = 0; j < size; j++) { 3442 TextInfo textInfo = tiArray[j]; 3443 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont); 3444 } 3445 } 3446 } else if (tbm == RendererSettings.TextBackgroundMethod_NONE) 3447 { 3448 synchronized (_ModifierFontMutex) { 3449 _modifierFont.setColor(color.toInt()); 3450 _modifierFont.setStyle(Style.FILL); 3451 for (int j = 0; j < size; j++) { 3452 TextInfo textInfo = tiArray[j]; 3453 ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont); 3454 } 3455 } 3456 } 3457 } 3458 catch(Exception exc) 3459 { 3460 ErrorLogger.LogException("ModifierRenderer","RenderText",exc); 3461 } 3462 } 3463 3464 public static boolean hasDisplayModifiers(String symbolID, SparseArray<String> modifiers) 3465 { 3466 boolean hasModifiers = false; 3467 char scheme = symbolID.charAt(0); 3468 char status = symbolID.charAt(3); 3469 char affiliation = symbolID.charAt(1); 3470 if (scheme != 'W') 3471 { 3472 if (scheme != 'G' && (SymbolUtilities.isEMSNaturalEvent(symbolID) == false)) 3473 { 3474 switch (status) 3475 { 3476 case 'C': 3477 case 'D': 3478 case 'X': 3479 case 'F': 3480 hasModifiers = true; 3481 3482 default: 3483 break; 3484 } 3485 3486 if ((symbolID.substring(10, 12).equals("--") == false && symbolID.substring(10, 12).equals("**") == false) || modifiers.indexOfKey(ModifiersUnits.Q_DIRECTION_OF_MOVEMENT) >= 0) 3487 { 3488 hasModifiers = true; 3489 } 3490 3491 if(SymbolUtilities.isHQ(symbolID)) 3492 hasModifiers = true; 3493 } 3494 else 3495 { 3496 if (SymbolUtilities.isNBC(symbolID) == true && modifiers.indexOfKey(ModifiersTG.Q_DIRECTION_OF_MOVEMENT) >= 0) 3497 { 3498 hasModifiers = true; 3499 } 3500 } 3501 3502 } 3503 3504 return hasModifiers; 3505 } 3506 3507 public static boolean hasTextModifiers(String symbolID, SparseArray<String> modifiers, SparseArray<String> attributes) 3508 { 3509 3510 int symStd = RS.getSymbologyStandard(); 3511 if (attributes.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0) 3512 { 3513 symStd = Integer.parseInt(attributes.get(MilStdAttributes.SymbologyStandard)); 3514 } 3515 char scheme = symbolID.charAt(0); 3516 if(scheme == 'W') 3517 { 3518 if(symbolID.equals("WAS-WSF-LVP----") || //freezing level 3519 symbolID.equals("WAS-PHT---P----") || //tropopause high 3520 symbolID.equals("WAS-PLT---P----") || //tropopause low 3521 symbolID.equals("WAS-WST-LVP----")) ////tropopause level 3522 return true; 3523 else 3524 return false; 3525 } 3526 if (scheme == 'G') 3527 { 3528 String basic = SymbolUtilities.getBasicSymbolIDStrict(symbolID); 3529 SymbolDef sd = SymbolDefTable.getInstance().getSymbolDef(basic, symStd); 3530 String expr = "\\."; 3531 String mods[] = sd.getModifiers().split(expr); 3532 3533 for(int lcv = 0; lcv < mods.length; lcv++) 3534 { 3535 if(modifiers.indexOfKey(ModifiersTG.getModifierKey(mods[lcv])) >= 0) 3536 return true; 3537 } 3538 return false; 3539 } 3540 else if (SymbolUtilities.isEMSNaturalEvent(symbolID) == false) 3541 { 3542 3543 if (SymbolUtilities.getUnitAffiliationModifier(symbolID, symStd) != null) 3544 { 3545 return true; 3546 } 3547 3548 if (SymbolUtilities.hasValidCountryCode(symbolID)) 3549 { 3550 return true; 3551 } 3552 3553 if (SymbolUtilities.isEMSNaturalEvent(symbolID)) 3554 { 3555 return false; 3556 } 3557 3558 if (modifiers.indexOfKey(ModifiersUnits.Q_DIRECTION_OF_MOVEMENT) >= 0) 3559 { 3560 if (modifiers.size() > 1) 3561 { 3562 return true; 3563 } 3564 } 3565 else if (modifiers.size() > 0) 3566 { 3567 return true; 3568 } 3569 } 3570 return false; 3571 } 3572 3573}