001package armyc2.c5isr.renderer;
002
003import java.util.ArrayList;
004import java.util.List;
005import java.util.Locale;
006import java.util.Map;
007
008import android.graphics.Bitmap;
009import android.graphics.Canvas;
010import android.graphics.DashPathEffect;
011import android.graphics.Paint;
012import android.graphics.Path;
013import android.graphics.Point;
014import android.graphics.PointF;
015import android.graphics.Rect;
016import android.graphics.RectF;
017import android.graphics.Bitmap.Config;
018import android.graphics.Paint.Cap;
019import android.graphics.Paint.Join;
020import android.graphics.Paint.Style;
021import android.graphics.Path.Direction;
022import armyc2.c5isr.renderer.utilities.Color;
023import armyc2.c5isr.renderer.utilities.ErrorLogger;
024import armyc2.c5isr.renderer.utilities.GENCLookup;
025import armyc2.c5isr.renderer.utilities.ImageInfo;
026import armyc2.c5isr.renderer.utilities.MSInfo;
027import armyc2.c5isr.renderer.utilities.MSLookup;
028import armyc2.c5isr.renderer.utilities.MilStdAttributes;
029import armyc2.c5isr.renderer.utilities.Modifiers;
030import armyc2.c5isr.renderer.utilities.PathUtilities;
031import armyc2.c5isr.renderer.utilities.RectUtilities;
032import armyc2.c5isr.renderer.utilities.RendererSettings;
033import armyc2.c5isr.renderer.utilities.RendererUtilities;
034import armyc2.c5isr.renderer.utilities.SVGInfo;
035import armyc2.c5isr.renderer.utilities.SVGLookup;
036import armyc2.c5isr.renderer.utilities.SVGPath;
037import armyc2.c5isr.renderer.utilities.SVGSymbolInfo;
038import armyc2.c5isr.renderer.utilities.Shape2SVG;
039import armyc2.c5isr.renderer.utilities.SymbolDimensionInfo;
040import armyc2.c5isr.renderer.utilities.SymbolID;
041import armyc2.c5isr.renderer.utilities.SymbolUtilities;
042import armyc2.c5isr.renderer.utilities.TextInfo;
043
044/**
045 * This class is used for rendering the labels/amplifiers/modifiers around the single point symbol.
046 */
047public class ModifierRenderer
048{
049
050    private static Paint _modifierFont = null;
051    private static float _modifierFontHeight = 10f;
052    private static float _modifierFontDescent = 2f;
053    private static RendererSettings RS = RendererSettings.getInstance();
054
055    private static final Object _ModifierFontMutex = new Object();
056    public static void setModifierFont(Paint font, float height, float descent)
057    {
058        synchronized (_ModifierFontMutex) {
059            _modifierFont = font;
060            _modifierFontHeight = height;
061            _modifierFontDescent = descent;
062        }
063    }
064
065    public static SymbolDimensionInfo processUnitDisplayModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Boolean hasTextModifiers, Map<String,String> attributes)
066    {
067
068        ImageInfo ii = null;
069        ImageInfo newii = null;
070        SVGSymbolInfo ssi = null;
071        SymbolDimensionInfo newsdi = null;
072        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
073        Rect imageBounds = new Rect(sdi.getImageBounds());
074        Point centerPoint = new Point(sdi.getCenterPoint());
075        Point symbolCenter = new Point(symbolBounds.centerX(), symbolBounds.centerY());
076        TextInfo tiEchelon = null;
077        TextInfo tiAM = null;
078        Rect echelonBounds = null;
079        Rect amBounds = null;
080        Color textColor = Color.BLACK;
081        Color textBackgroundColor = null;
082        float strokeWidth = 3.0f;
083        float strokeWidthNL = 3.0f;
084        Color lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID);
085        Color fillColor = SymbolUtilities.getFillColorOfAffiliation(symbolID);
086        int buffer = 0;
087        int alpha = 255;
088        //ctx = null;
089        int offsetX = 0;
090        int offsetY = 0;
091        int pixelSize = RendererSettings.getInstance().getDefaultPixelSize();
092        SVGPath svgMobilityPath = null;
093        String svgMobilityGroup = null;
094
095        int ss = SymbolID.getSymbolSet(symbolID);
096
097        if (attributes.containsKey(MilStdAttributes.Alpha))
098        {
099            alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha));
100            textColor.setAlpha(alpha);
101        }
102        if (attributes.containsKey(MilStdAttributes.TextColor))
103        {
104            textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor));
105            if(alpha > -1)
106                textColor.setAlpha(alpha);
107        }
108        if (attributes.containsKey(MilStdAttributes.TextBackgroundColor))
109        {
110            textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor));
111            if(alpha > -1)
112                textBackgroundColor.setAlpha(alpha);
113        }
114        if (attributes.containsKey(MilStdAttributes.LineColor))
115        {
116            lineColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.LineColor));
117        }
118        if (attributes.containsKey(MilStdAttributes.FillColor))
119        {
120            fillColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.FillColor));
121        }
122        if(attributes.containsKey(MilStdAttributes.PixelSize))
123        {
124            pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize));
125        }
126
127        //float fontsize = RendererSettings.getInstance().getModiferFont().getTextSize();
128
129        // <editor-fold defaultstate="collapsed" desc="Build Mobility Modifiers">
130        float strokeWidthBasedOnDPI = 1;//min//Math.max(RendererSettings.getInstance().getDeviceDPI()/210,1);//min DPI
131        strokeWidthBasedOnDPI = Math.max(pixelSize / 25f,strokeWidthBasedOnDPI);//dpi base on symbol size
132        strokeWidthBasedOnDPI = Math.min(strokeWidthBasedOnDPI,RendererSettings.getInstance().getDeviceDPI()/32f);//max dpi
133
134        RectF mobilityBounds = null;
135        int ad = SymbolID.getAmplifierDescriptor(symbolID);//echelon/mobility
136        List<Path> shapes = new ArrayList<Path>();
137        Path mobilityPath = null;
138        Path mobilityPathFill = null;
139        if (ad >= SymbolID.Mobility_WheeledLimitedCrossCountry &&
140                (SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.R_MOBILITY_INDICATOR) ||
141                 SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AG_AUX_EQUIP_INDICATOR)))
142        {
143
144            //Draw Mobility
145            int fifth = (int) ((symbolBounds.width() * 0.2) + 0.5f);
146            mobilityPath = new Path();
147            svgMobilityPath = null;
148            svgMobilityGroup = null;
149
150            int x = 0;
151            int y = 0;
152            int centerX = 0;
153            int bottomY = 0;
154            int height = 0;
155            int width = 0;
156            int middleY = 0;
157            int wheelOffset = 2;
158            int wheelSize = fifth;//10;
159            int rrHeight = fifth;//10;
160            int rrArcWidth = (int) ((fifth * 1.5) + 0.5f);//16;
161            float rad = wheelSize/2;
162
163
164            x = (int) symbolBounds.left + 1;
165            y = (int) symbolBounds.top;
166            height = Math.round(symbolBounds.height());
167            width = Math.round(symbolBounds.width()) - 3;
168            bottomY = y + height + 2;
169
170
171
172            if (ad >= SymbolID.Mobility_WheeledLimitedCrossCountry && //31, mobility starts above 30
173                    SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.R_MOBILITY_INDICATOR))
174            {
175                bottomY = y + height + 2;
176
177                //wheelSize = width / 7;
178                //rrHeight = width / 7;
179                //rrArcWidth = width / 7;
180                if (ad == SymbolID.Mobility_WheeledLimitedCrossCountry)
181                {
182                    //line
183                    PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY);
184
185                    //left circle
186                    PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize);
187
188                    //right circle
189                    PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize);
190
191                    //SVG
192                    svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n";
193                    svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\"  ></circle>\n";
194                    svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\"  ></circle>\n";
195                }
196                else if (ad == SymbolID.Mobility_WheeledCrossCountry)
197                {
198                    //line
199                    PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY);
200
201                    //left circle
202                    PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize);
203
204                    //right circle
205                    PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize);
206
207                    //center wheel
208                    PathUtilities.addEllipse(mobilityPath, x + (width / 2) - (wheelSize / 2), bottomY + wheelOffset, wheelSize, wheelSize);
209
210                    //SVG
211                    svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n";
212                    svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n";
213                    svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n";
214                    svgMobilityGroup += "<circle cx=\"" + (x + (width/2)) + "\" cy=\"" + (bottomY + wheelOffset + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" stroke=\"black\" ></circle>\n";
215                }
216                else if (ad == SymbolID.Mobility_Tracked)
217                {
218                    //round rectangle
219                    PathUtilities.addRoundedRect(mobilityPath, x, bottomY, width, rrHeight, rrHeight/2, rrHeight);
220                    svgMobilityGroup = "<rect width=\"" + width + "\" height=\"" + rrHeight + "\" x=\"" + x + "\" y=\"" + bottomY + "\" rx=\"" + rrHeight/2 + "\" ry=\"" + rrHeight + "\" />\n";
221
222                }
223                else if (ad == SymbolID.Mobility_Wheeled_Tracked)
224                {
225                    //round rectangle
226                    PathUtilities.addRoundedRect(mobilityPath, x, bottomY, width, rrHeight, wheelSize/2, rrHeight);
227                    svgMobilityGroup = "<rect width=\"" + width + "\" height=\"" + rrHeight + "\" x=\"" + x + "\" y=\"" + bottomY + "\" rx=\"" + rrHeight/2 + "\" ry=\"" + rrHeight + "\" />\n";
228
229                    //left circle
230                    PathUtilities.addEllipse(mobilityPath, x - wheelSize - wheelSize, bottomY, wheelSize, wheelSize);
231                    svgMobilityGroup += "<circle cx=\"" + (x - wheelSize - wheelSize/2) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\"  stroke=\"black\" ></circle>\n";
232                }
233                else if (ad == SymbolID.Mobility_Towed)
234                {
235                    //line
236                    PathUtilities.addLine(mobilityPath, x + wheelSize, bottomY + (wheelSize / 2),
237                            x + width - wheelSize, bottomY + (wheelSize / 2));
238
239                    //left circle
240                    PathUtilities.addEllipse(mobilityPath, x, bottomY, wheelSize, wheelSize);
241
242                    //right circle
243                    PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY, wheelSize, wheelSize);
244
245                    //SVG
246                    svgMobilityGroup = "<line x1=\"" + (x + wheelSize) + "\" y1=\"" + (bottomY + (wheelSize/2) + "\" x2=\"" + (x + width - wheelSize) + "\" y2=\"" + (bottomY + (wheelSize/2))) + "\" />\n";
247                    svgMobilityGroup += "<circle cx=\"" + (x + (wheelSize/2)) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" fill=\"none\" stroke=\"black\" ></circle>\n";
248                    svgMobilityGroup += "<circle cx=\"" + (x + width - (wheelSize/2)) + "\" cy=\"" + (bottomY + (wheelSize/2)) + "\" r=\"" + (wheelSize/2) + "\" fill=\"none\" stroke=\"black\" ></circle>\n";
249                }
250                else if (ad == SymbolID.Mobility_Rail)
251                {
252                    //line
253                    PathUtilities.addLine(mobilityPath, x, bottomY, x + width, bottomY);
254
255                    //left circle
256                    PathUtilities.addEllipse(mobilityPath, x + wheelSize, bottomY + wheelOffset, wheelSize, wheelSize);
257
258                    //left circle2
259                    PathUtilities.addEllipse(mobilityPath, x, bottomY + wheelOffset, wheelSize, wheelSize);
260
261                    //right circle
262                    PathUtilities.addEllipse(mobilityPath, x + width - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize);
263
264                    //right circle2
265                    PathUtilities.addEllipse(mobilityPath, x + width - wheelSize - wheelSize, bottomY + wheelOffset, wheelSize, wheelSize);
266
267                    //SVG
268                    svgMobilityGroup = "<line x1=\"" + x + "\" y1=\"" + bottomY + "\" x2=\"" + (x + width) + "\" y2=\"" + bottomY + "\" />\n";
269
270                    svgMobilityGroup += "<circle cx=\"" + (x + rad) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n";
271                    svgMobilityGroup += "<circle cx=\"" + (x + rad + wheelSize) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n";
272
273                    svgMobilityGroup += "<circle cx=\"" + (x + width - rad) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n";
274                    svgMobilityGroup += "<circle cx=\"" + (x + width - rad - wheelSize) + "\" cy=\"" + (bottomY + wheelOffset + rad) + "\" r=\"" + rad + "\" ></circle>\n";
275
276                }
277                else if (ad == SymbolID.Mobility_OverSnow)
278                {
279                        float halfWidth = (rrArcWidth * 0.5f);
280                    mobilityPath.moveTo(x, bottomY);
281                    mobilityPath.lineTo(x + halfWidth, bottomY + halfWidth);
282                    mobilityPath.lineTo(x + width, bottomY + halfWidth);
283
284                    //SVG
285                    svgMobilityPath = new SVGPath();
286                    svgMobilityPath.moveTo(x,bottomY);
287                    svgMobilityPath.lineTo(x + halfWidth, bottomY + halfWidth);
288                    svgMobilityPath.lineTo(x + width, bottomY + halfWidth);
289
290                }
291                else if (ad == SymbolID.Mobility_Sled)
292                {
293                    mobilityPath.moveTo(x, bottomY);
294
295                    mobilityPath.cubicTo(x, bottomY, x - rrHeight, bottomY + rrHeight/2, x, bottomY + rrHeight);
296                    //mobilityPath.bezierCurveTo(x, bottomY, x-rrArcWidth, bottomY+3, x, bottomY+rrHeight);
297
298                    mobilityPath.lineTo(x + width, bottomY + rrHeight);
299
300                    mobilityPath.cubicTo(x + width, bottomY + rrHeight, x + width + rrHeight, bottomY + rrHeight/2, x + width, bottomY);
301                    //shapeMobility.curveTo(x + width, bottomY + rrHeight, x+ width + rrArcWidth, bottomY+3, x + width, bottomY);
302
303                    //SVG
304                    svgMobilityPath = new SVGPath();
305                    svgMobilityPath.moveTo(x, bottomY);
306                    svgMobilityPath.bezierCurveTo(x, bottomY, x - rrHeight, bottomY + rrHeight/2, x, bottomY + rrHeight);
307                    svgMobilityPath.lineTo(x + width, bottomY + rrHeight);
308                    svgMobilityPath.bezierCurveTo(x + width, bottomY + rrHeight, x + width + rrHeight, bottomY + rrHeight/2, x + width, bottomY);
309
310                }
311                else if (ad == SymbolID.Mobility_PackAnimals)
312                {
313                    centerX = Math.round(RectUtilities.getCenterX(symbolBounds));
314                    int angleWidth = rrHeight / 2;
315                    mobilityPath.moveTo(centerX, bottomY + rrHeight + 2);
316                    mobilityPath.lineTo(centerX - angleWidth, bottomY);
317                    mobilityPath.lineTo(centerX - angleWidth*2, bottomY + rrHeight + 2);
318
319                    mobilityPath.moveTo(centerX, bottomY + rrHeight + 2);
320                    mobilityPath.lineTo(centerX + angleWidth, bottomY);
321                    mobilityPath.lineTo(centerX + angleWidth*2, bottomY + rrHeight + 2);
322
323                    //SVG
324                    svgMobilityPath = new SVGPath();
325                    svgMobilityPath.moveTo(centerX, bottomY + rrHeight + 2);
326                    svgMobilityPath.lineTo(centerX - angleWidth, bottomY);
327                    svgMobilityPath.lineTo(centerX - angleWidth*2, bottomY + rrHeight + 2);
328
329                    svgMobilityPath.moveTo(centerX, bottomY + rrHeight + 2);
330                    svgMobilityPath.lineTo(centerX + angleWidth, bottomY);
331                    svgMobilityPath.lineTo(centerX + angleWidth*2, bottomY + rrHeight + 2);
332                }
333                else if (ad == SymbolID.Mobility_Barge)
334                {
335                    centerX = Math.round(RectUtilities.getCenterX(symbolBounds));
336                    PathUtilities.addLine(mobilityPath, x + width, bottomY, x, bottomY);
337                    //var line = new SO.Line(x + width, bottomY,x, bottomY);
338
339                    float quarterX = (centerX - x) / 2;
340                    //var quarterY = (((bottomY + rrHeight) - bottomY)/2);
341
342                    mobilityPath.moveTo(x, bottomY);
343                    mobilityPath.cubicTo(x + quarterX, bottomY + rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY);
344                    //shapes.push(new SO.BCurve(x, bottomY,x+quarterX, bottomY+rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY));
345
346                    //SVG
347                    svgMobilityPath = new SVGPath();
348                    svgMobilityPath.moveTo(x + width, bottomY);
349                    svgMobilityPath.lineTo(x, bottomY);
350                    svgMobilityPath.moveTo(x, bottomY);
351                    svgMobilityPath.bezierCurveTo(x + quarterX, bottomY + rrHeight, centerX + quarterX, bottomY + rrHeight, x + width, bottomY);
352                }
353
354                else if (ad == SymbolID.Mobility_Amphibious)
355                {
356                    float incrementX = width / 7;
357                    middleY = (bottomY + (rrHeight / 2));
358
359                    x = Math.round(x + (incrementX / 2));
360                    float r = Math.round(incrementX / 2);
361
362                    //mobilityPath.arcTo(oval, sAngle, sAngle, moveTo);
363                    PathUtilities.arc(mobilityPath, x, middleY, r, 180, 180);
364                    PathUtilities.arc(mobilityPath, x + incrementX, middleY, r, 180, -180, false);
365                    PathUtilities.arc(mobilityPath, x + incrementX * 2, middleY, r, 180, 180, false);
366                    PathUtilities.arc(mobilityPath, x + incrementX * 3, middleY, r, 180, -180, false);
367                    PathUtilities.arc(mobilityPath, x + incrementX * 4, middleY, r, 180, 180, false);
368                    PathUtilities.arc(mobilityPath, x + incrementX * 5, middleY, r, 180, -180, false);
369                    PathUtilities.arc(mobilityPath, x + incrementX * 6, middleY, r, 180, 180, false);
370
371                    //SVG
372                    x = symbolBounds.left + 1;
373                    svgMobilityGroup = "<path d=\"M" + x + " " + middleY + " ";
374                    svgMobilityGroup += "C " + x + " " + bottomY + " " + (x + incrementX) + " " + bottomY + " " + (x + incrementX) + " " + middleY + " ";
375                    svgMobilityGroup += "C " + (x + incrementX) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 2)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*2)) + " " + middleY + " ";
376                    svgMobilityGroup += "C " + (x + (incrementX*2))  + " " + bottomY + " " + (x + (incrementX*3)) + " " + bottomY + " " + (x + incrementX*3) + " " + middleY + " ";
377                    svgMobilityGroup += "C " + (x + (incrementX*3)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 4)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*4)) + " " + middleY + " ";
378                    svgMobilityGroup += "C " + (x + (incrementX*4))  + " " + bottomY + " " + (x + (incrementX*5)) + " " + bottomY + " " + (x + incrementX*5) + " " + middleY + " ";
379                    svgMobilityGroup += "C " + (x + (incrementX*5)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX * 6)) + " " + (bottomY + rrHeight) + " " + (x + (incrementX*6)) + " " + middleY + " ";
380                    svgMobilityGroup += "C " + (x + (incrementX*6))  + " " + bottomY + " " + (x + (incrementX*7)) + " " + bottomY + " " + (x + incrementX*7) + " " + middleY + " ";
381                    svgMobilityGroup += "\"/>";
382
383
384                }
385
386                if(svgMobilityGroup != null)
387                    svgMobilityGroup = "<g stroke-width=\"" + strokeWidthBasedOnDPI + "\" fill=\"none\"" + " stroke=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" + ">\n" + svgMobilityGroup + "</g>\n";
388
389            }
390            //Draw Towed Array Sonar
391            if ((ad == SymbolID.Mobility_ShortTowedArray || ad == SymbolID.Mobility_LongTowedArray) &&
392                    SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AG_AUX_EQUIP_INDICATOR)) {
393                int boxHeight = (int) ((rrHeight * 0.8f) + 0.5f);
394                bottomY = y + height + (boxHeight / 7);
395                mobilityPathFill = new Path();
396                offsetY = boxHeight / 7;//1;
397                centerX = Math.round(symbolBounds.left + (symbolBounds.right - symbolBounds.left) / 2);
398                int squareOffset = Math.round(boxHeight * 0.5f);
399                middleY = ((boxHeight / 2) + bottomY) + offsetY;//+1 for offset from symbol
400                if (ad == SymbolID.Mobility_ShortTowedArray) {
401                    //subtract 0.5 because lines 1 pixel thick get aliased into
402                    //a line two pixels wide.
403                    //line
404                    PathUtilities.addLine(mobilityPath, centerX - 1, bottomY - 1, centerX - 1, bottomY + offsetY + boxHeight + offsetY);
405                    //shapes.push(new SO.Line(centerX-1,bottomY-1,centerX-1, bottomY + rrHeight + 3));
406                    //shapeLines.append(new Line2D.Double(centerX,bottomY - 2,centerX, bottomY + rrHeight + 1), false);
407                    //line
408                    PathUtilities.addLine(mobilityPath, x, middleY, x + width, middleY);
409                    //shapes.push(new SO.Line(x,middleY,x + width, middleY));
410                    //shapeLines.append(new Line2D.Double(x,middleY,x + width, middleY), false);
411                    //square
412                    mobilityPathFill.addRect(PathUtilities.makeRectF(x - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW);
413                    //shapes.push(new SO.Rectangle(x-squareOffset, bottomY+offsetY, 5, 5));
414                    //shapeSquares.append(new Rectangle2D.Double(x-squareOffset, bottomY, 5, 5), false);
415                    //square
416                    mobilityPathFill.addRect(PathUtilities.makeRectF(Math.round(centerX - squareOffset), bottomY + offsetY, boxHeight, boxHeight), Direction.CW);
417                    //shapes.push(new SO.Rectangle(Math.round(centerX-squareOffset), bottomY+offsetY, 5, 5));
418                    //shapeSquares.append(new Rectangle2D.Double(centerX-squareOffset, bottomY, 5, 5), false);
419                    //square
420                    mobilityPathFill.addRect(PathUtilities.makeRectF(x + width - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW);
421                    //shapes.push(new SO.Rectangle(x + width - squareOffset, bottomY+offsetY, 5, 5));
422                    //shapeSquares.append(new Rectangle2D.Double(x + width - squareOffset, bottomY, 5, 5), false);
423
424                    //SVG
425                    String svgColor = RendererUtilities.colorToHexString(lineColor,false);
426                    svgMobilityGroup = "<line x1=\"" + (centerX - 1) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (centerX - 1) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n";
427                    svgMobilityGroup += "<line x1=\"" + (x) + "\" y1=\"" + (middleY) + "\" x2=\"" + (x + width) + "\" y2=\"" + (middleY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n";
428                    svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n";
429                    svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (centerX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n";
430                    svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x + width - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n";
431
432
433                } else if (ad == SymbolID.Mobility_LongTowedArray) {
434                    int leftX = x + (centerX - x) / 2,
435                            rightX = centerX + (x + width - centerX) / 2;
436
437                    //line vertical left
438                    PathUtilities.addLine(mobilityPath, leftX, bottomY - 1, leftX, bottomY + offsetY + boxHeight + offsetY);
439                    //shapes.push(new SO.Line(leftX,bottomY - 1,leftX, bottomY + rrHeight + 3));
440                    //shapeLines.append(new Line2D.Double(leftX,bottomY - 2,leftX, bottomY + rrHeight + 1), false);
441                    //line vertical right
442                    PathUtilities.addLine(mobilityPath, rightX, bottomY - 1, rightX, bottomY + offsetY + boxHeight + offsetY);
443                    //shapes.push(new SO.Line(rightX,bottomY - 1,rightX, bottomY + rrHeight + 3));
444                    //shapeLines.append(new Line2D.Double(rightX,bottomY - 2,rightX, bottomY + rrHeight + 1), false);
445                    //line horizontal
446                    PathUtilities.addLine(mobilityPath, x, middleY, x + width, middleY);
447                    //shapes.push(new SO.Line(x,middleY,x + width, middleY));
448                    //shapeLines.append(new Line2D.Double(x,middleY,x + width, middleY), false);
449                    //square left
450                    mobilityPathFill.addRect(PathUtilities.makeRectF(x - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW);
451                    //shapes.push(new SO.Rectangle(x-squareOffset, bottomY+offsetY, 5, 5));
452                    //shapeSquares.append(new Rectangle2D.Double(x-squareOffset, bottomY, 5, 5), false);
453                    //square middle
454                    mobilityPathFill.addRect(PathUtilities.makeRectF(centerX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW);
455                    //shapes.push(new SO.Rectangle(centerX-squareOffset, bottomY+offsetY, 5, 5));
456                    //shapeSquares.append(new Rectangle2D.Double(centerX-squareOffset, bottomY, 5, 5), false);
457                    //square right
458                    mobilityPathFill.addRect(PathUtilities.makeRectF(x + width - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW);
459                    //shapes.push(new SO.Rectangle(x + width - squareOffset, bottomY+offsetY, 5, 5));
460                    //shapeSquares.append(new Rectangle2D.Double(x + width - squareOffset, bottomY, 5, 5), false);
461                    //square middle left
462                    mobilityPathFill.addRect(PathUtilities.makeRectF(leftX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW);
463                    //shapes.push(new SO.Rectangle(leftX - squareOffset, bottomY+offsetY, 5, 5));
464                    //shapeSquares.append(new Rectangle2D.Double(leftX - squareOffset, bottomY, 5, 5), false);
465                    //square middle right
466                    mobilityPathFill.addRect(PathUtilities.makeRectF(rightX - squareOffset, bottomY + offsetY, boxHeight, boxHeight), Direction.CW);
467                    //shapes.push(new SO.Rectangle(rightX - squareOffset, bottomY+offsetY, 5, 5));
468                    //shapeSquares.append(new Rectangle2D.Double(rightX - squareOffset, bottomY, 5, 5), false);
469
470                    //SVG
471                    String svgColor = RendererUtilities.colorToHexString(lineColor,false);
472                    svgMobilityGroup = "<line x1=\"" + (leftX) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (leftX) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n";
473                    svgMobilityGroup += "<line x1=\"" + (rightX) + "\" y1=\"" + (bottomY - 1) + "\" x2=\"" + (rightX) + "\" y2=\"" + (bottomY + offsetY + boxHeight + offsetY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n";
474                    svgMobilityGroup += "<line x1=\"" + (x) + "\" y1=\"" + (middleY) + "\" x2=\"" + (x + width) + "\" y2=\"" + (middleY) + "\" stroke=\"" + svgColor + "\" stroke-width=\"" + strokeWidthBasedOnDPI + "\" />\n";
475                    svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n";
476                    svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (centerX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n";
477                    svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (x + width - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n";
478                    svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (leftX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n";
479                    svgMobilityGroup += "<rect width=\"" + (boxHeight) + "\" height=\"" + (boxHeight) + "\" x=\"" + (rightX - squareOffset) + "\" y=\"" + (bottomY + offsetY) + "\" fill=\"" + svgColor + "\" stroke-width=\"0\"/>\n";
480
481                }
482                if(svgMobilityGroup != null)
483                    svgMobilityGroup = "<g stroke-width=\"" + strokeWidthBasedOnDPI + "\" fill=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" + " stroke=\"" + RendererUtilities.colorToHexString(lineColor,false) + "\"" +  ">\n" + svgMobilityGroup + "\n</g>";
484            }
485
486            //get mobility bounds
487            if (mobilityPath != null)
488            {
489
490                //build mobility bounds
491                mobilityBounds = new RectF();
492                mobilityPath.computeBounds(mobilityBounds, true);
493
494                RectF mobilityFillBounds = new RectF();
495                if (mobilityPathFill != null)
496                {
497                    mobilityPathFill.computeBounds(mobilityFillBounds, true);
498                    mobilityBounds.union(mobilityFillBounds);
499                }
500
501                //grow by one because we use a line thickness of 2.
502                RectUtilities.grow(mobilityBounds,Math.round(strokeWidthBasedOnDPI/2));
503                //mobilityBounds.set(mobilityBounds.left - 1, mobilityBounds.top - 1, mobilityBounds.right + 1, mobilityBounds.bottom + 1);
504                imageBounds.union(RectUtilities.makeRectFromRectF(mobilityBounds));
505            }
506        }
507        // </editor-fold>
508
509        // <editor-fold defaultstate="collapsed" desc="Leadership Indicator Modifier">
510        RectF liBounds = null;
511        Path liPath = null;
512        PointF liTop = null;
513        PointF liLeft = null;
514        PointF liRight = null;
515        if(ad == SymbolID.Leadership_Individual && ss == SymbolID.SymbolSet_DismountedIndividuals &&
516                (SymbolID.getFrameShape(symbolID)==SymbolID.FrameShape_DismountedIndividuals ||
517                        SymbolID.getFrameShape(symbolID)==SymbolID.FrameShape_Unknown))
518        {
519            liPath = new Path();
520
521            int si = SymbolID.getStandardIdentity(symbolID);
522            int af = SymbolID.getAffiliation(symbolID);
523            int c = SymbolID.getContext(symbolID);
524            //int fs = SymbolID.getFrameShape(symbolID);
525            double centerOffset = 0;
526            double sideOffset = 0;
527            double left = symbolBounds.left;
528            double right = symbolBounds.left + symbolBounds.width();
529
530            if(af == SymbolID.StandardIdentity_Affiliation_Unknown || af == SymbolID.StandardIdentity_Affiliation_Pending)
531            {
532                centerOffset = (symbolBounds.height()*0.1012528735632184);
533                sideOffset = (right - left)*0.3583513488109785;
534                //left = symbolBounds.getCenterX() - ((symbolBounds.getWidth() / 2) * 0.66420458);
535                //right = symbolBounds.getCenterX() + ((symbolBounds.getWidth() / 2) * 0.66420458);
536            }
537            if(af == SymbolID.StandardIdentity_Affiliation_Neutral)
538            {
539                centerOffset = (symbolBounds.height()*0.25378787878787878);
540                sideOffset = (right - left)*0.2051402812352822;
541            }
542            if(SymbolUtilities.isReality(symbolID) || SymbolUtilities.isSimulation(symbolID))
543            {
544                if(af==SymbolID.StandardIdentity_Affiliation_Friend || af==SymbolID.StandardIdentity_Affiliation_AssumedFriend)
545                {//hexagon friend/assumed friend
546                    centerOffset = (symbolBounds.height()*0.08);
547                    sideOffset = (right - left)*0.282714524168219;//(symbolBounds.getHeight()*0.29);
548                }
549                else if(af==SymbolID.StandardIdentity_Affiliation_Hostile_Faker || af==SymbolID.StandardIdentity_Affiliation_Suspect_Joker)
550                {//diamond hostile/suspect
551
552                    left = symbolBounds.centerX() - ((symbolBounds.width() / 2) * 1.0653694149);//1.07);//1.0653694149);
553                    right = symbolBounds.centerX() + ((symbolBounds.width() / 2) * 1.0653694149);//1.07);//1.0653694149);
554
555                    centerOffset = (symbolBounds.height()*0.08);//0.0751139601139601
556                    sideOffset = (right - left)*0.4923255424955992;
557                }
558            }
559            else//Exercise
560            {
561                //hexagon
562                if(af!=SymbolID.StandardIdentity_Affiliation_Unknown ||
563                        af==SymbolID.StandardIdentity_Affiliation_Neutral)
564                {
565                    centerOffset = (symbolBounds.height()*0.08);
566                    sideOffset = (right - left)*0.282714524168219;
567                }
568            }
569
570            //create leadership indicator /\
571            liTop = new PointF(symbolBounds.centerX(), (float)(symbolBounds.top - centerOffset));
572            liLeft = new PointF((float)left, (float)(liTop.y + sideOffset));
573            liRight = new PointF((float)right, (float)(liTop.y + sideOffset));
574
575
576            liPath.moveTo(liTop.x, liTop.y);
577            liPath.lineTo(liLeft.x, liLeft.y);
578            liPath.moveTo(liTop.x, liTop.y);
579            liPath.lineTo(liRight.x, liRight.y);//*/
580
581
582            liBounds = new RectF(liLeft.x, liTop.y, liRight.x - liLeft.x, liLeft.y - liTop.y);
583
584            RectUtilities.grow(liBounds,2);
585
586            imageBounds.union(RectUtilities.makeRectFromRectF(liBounds));
587        }
588
589        // </editor-fold>
590
591        // <editor-fold defaultstate="collapsed" desc="Build Echelon">
592        //Draw Echelon
593        int intEchelon = SymbolID.getAmplifierDescriptor(symbolID);
594        String strEchelon = SymbolUtilities.getEchelonText(intEchelon);
595
596        if (strEchelon != null
597                && SymbolUtilities.hasModifier(symbolID, Modifiers.B_ECHELON))
598        {
599
600            int echelonOffset = 2,
601                    outlineOffset = RS.getTextOutlineWidth();
602
603            tiEchelon = new TextInfo(strEchelon, 0, 0, _modifierFont);
604            echelonBounds = tiEchelon.getTextBounds();
605
606            int y = Math.round(symbolBounds.left - echelonOffset);
607            int x = Math.round(symbolBounds.left + (symbolBounds.width() / 2)
608                    - (echelonBounds.width() / 2));
609            tiEchelon.setLocation(x, y);
610
611            //There will never be lowercase characters in an echelon so trim that fat.
612            //Remove the descent from the bounding box.
613            tiEchelon.getTextOutlineBounds();//.shiftBR(0,Math.round(-(echelonBounds.height()*0.3)));
614
615            //make echelon bounds a little more spacious for things like nearby labels and Task Force.
616            RectUtilities.grow(echelonBounds, outlineOffset);
617            //tiEchelon.getTextOutlineBounds();
618//                RectUtilities.shift(echelonBounds, x, -outlineOffset);
619            //echelonBounds.shift(0,-outlineOffset);// - Math.round(echelonOffset/2));
620            tiEchelon.setLocation(x, y - outlineOffset);
621
622            imageBounds.union(echelonBounds);
623
624        }
625        // </editor-fold>
626
627        // <editor-fold defaultstate="collapsed" desc="Build Affiliation Modifier">
628        //Draw Echelon
629        String affiliationModifier = null;
630        if (RS.getDrawAffiliationModifierAsLabel() == false)
631        {
632            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
633        }
634        if (affiliationModifier != null)
635        {
636
637            int amOffset = 2;
638            int outlineOffset = RS.getTextOutlineWidth();
639
640            tiAM = new TextInfo(affiliationModifier, 0, 0, _modifierFont);
641            amBounds = tiAM.getTextBounds();
642
643            int x, y;
644
645            if (echelonBounds != null
646                    && ((echelonBounds.left + echelonBounds.width() > symbolBounds.left + symbolBounds.width())))
647            {
648                y = Math.round(symbolBounds.top - amOffset);
649                x = echelonBounds.left + echelonBounds.width();
650            }
651            else
652            {
653                y = Math.round(symbolBounds.top - amOffset);
654                x = Math.round(symbolBounds.left + symbolBounds.width());
655            }
656            tiAM.setLocation(x, y);
657
658            //adjust for outline.
659            RectUtilities.grow(amBounds, outlineOffset);
660            RectUtilities.shift(amBounds, 0, -outlineOffset);
661            tiAM.setLocation(x, y - outlineOffset);
662
663            imageBounds.union(amBounds);
664        }
665        // </editor-fold>
666
667        // <editor-fold defaultstate="collapsed" desc="Build Task Force">
668        Rect tfBounds = null;
669        Rect tfRectangle = null;
670        if (SymbolUtilities.isTaskForce(symbolID) && SymbolUtilities.hasModifier(symbolID, Modifiers.D_TASK_FORCE_INDICATOR))
671        {
672
673            int height = Math.round(symbolBounds.height() / 4.0f);
674            int width = Math.round(symbolBounds.width() / 3.0f);
675
676            if(!SymbolUtilities.hasRectangleFrame(symbolID))
677            {
678                height = (int)Math.round(symbolBounds.height() / 6.0f);
679            }
680
681            tfRectangle = RectUtilities.makeRect((int) symbolBounds.left + width,
682                    (int) symbolBounds.top - height,
683                    width,
684                    height);
685
686            tfBounds = RectUtilities.makeRect(tfRectangle.left + -1,
687                    tfRectangle.top - 1,
688                    tfRectangle.width() + 2,
689                    tfRectangle.height() + 2);
690
691            if (echelonBounds != null)
692            {
693                /*tfRectangle = new Rect(echelonBounds.left,
694                        echelonBounds.top,// + outlineOffset,
695                        echelonBounds.right,
696                        symbolBounds.top-1);
697                tfBounds = new Rect(tfRectangle);*/
698
699                int tfx = tfRectangle.left;
700                int tfw = tfRectangle.width();
701                int tfy = tfRectangle.top;
702                int tfh = tfRectangle.height();
703
704                if(echelonBounds.width() > tfRectangle.width())
705                {
706                    tfx = symbolBounds.left + symbolBounds.width()/2 - (echelonBounds.width()/2) - 1;
707                    tfw = echelonBounds.width()+2;
708                }
709                if(echelonBounds.height() > tfRectangle.height())
710                {
711                    tfy = echelonBounds.top-1;
712                    tfh = echelonBounds.height()+2;
713
714                }
715                tfRectangle = RectUtilities.makeRect((int)tfx,
716                        tfy,// + outlineOffset,
717                        tfw,
718                        tfh);
719
720
721                tfBounds = RectUtilities.makeRect((tfRectangle.left - 1),
722                        (tfRectangle.top - 1),
723                        (tfRectangle.width() + 2),
724                        (tfRectangle.height() + 2));
725            }
726
727            imageBounds.union(tfBounds);
728        }
729        // </editor-fold>
730
731        // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator">
732        Rect fdiBounds = null;
733        Point fdiTop = null;
734        Point fdiLeft = null;
735        Point fdiRight = null;
736
737
738        if (SymbolUtilities.hasFDI(symbolID)
739                && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AB_FEINT_DUMMY_INDICATOR))
740        {
741            //create feint indicator /\
742            fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top);
743            fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top);
744            fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f)));
745
746
747            fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1);
748            fdiBounds.union(fdiTop.x, fdiTop.y);
749            fdiBounds.union(fdiRight.x, fdiRight.y);
750
751            float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f);
752            RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2));
753
754            if (echelonBounds != null)
755            {
756                int shiftY = Math.round(symbolBounds.top - echelonBounds.height() - 2);
757                fdiLeft.offset(0, shiftY);
758                fdiTop.offset(0, shiftY);
759                fdiRight.offset(0, shiftY);
760                fdiBounds.offset(0, shiftY);
761            }
762
763            imageBounds.union(fdiBounds);
764
765        }
766        // </editor-fold>
767
768        //Using SVG files for installation indicator now
769        // <editor-fold defaultstate="collapsed" desc="Build Installation">
770        /*//Using SVG files for the installation indicator
771        Rect instRectangle = null;
772        Rect instBounds = null;
773        if (SymbolUtilities.hasInstallationModifier(symbolID)
774                && SymbolUtilitiesD.canSymbolHaveModifier(symbolID, Modifiers.AC_INSTALLATION))
775        {//the actual installation symbols have the modifier
776            //built in.  everything else, we have to draw it.
777            //
778            ////get indicator dimensions////////////////////////////////
779            int width;
780            int height;
781            char affiliation = SymbolUtilities.getAffiliation(symbolID);
782
783            if (affiliation == 'F'
784                    || affiliation == 'A'
785                    || affiliation == 'D'
786                    || affiliation == 'M'
787                    || affiliation == 'J'
788                    || affiliation == 'K')
789            {
790                //4th height, 3rd width
791                height = Math.round(symbolBounds.height() / 4);
792                width = Math.round(symbolBounds.width() / 3);
793            }
794            else if (affiliation == 'H' || affiliation == 'S')//hostile,suspect
795            {
796                //6th height, 3rd width
797                height = Math.round(symbolBounds.height() / 6);
798                width = Math.round(symbolBounds.width() / 3);
799            }
800            else if (affiliation == 'N' || affiliation == 'L')//neutral,exercise neutral
801            {
802                //6th height, 3rd width
803                height = Math.round(symbolBounds.height() / 6);
804                width = Math.round(symbolBounds.width() / 3);
805            }
806            else if (affiliation == 'P'
807                    || affiliation == 'U'
808                    || affiliation == 'G'
809                    || affiliation == 'W')
810            {
811                //6th height, 3rd width
812                height = Math.round(symbolBounds.height() / 6);
813                width = Math.round(symbolBounds.width() / 3);
814            }
815            else
816            {
817                //6th height, 3rd width
818                height = Math.round(symbolBounds.height() / 6);
819                width = Math.round(symbolBounds.width() / 3);
820            }
821
822//                    if(width * 3 < symbolBounds.width())
823//                        width++;
824            //set installation position/////////////////////////////////
825            //set position of indicator
826            if (affiliation == 'F'
827                    || affiliation == 'A'
828                    || affiliation == 'D'
829                    || affiliation == 'M'
830                    || affiliation == 'J'
831                    || affiliation == 'K'
832                    || affiliation == 'N'
833                    || affiliation == 'L')
834            {
835                instRectangle = RectUtilities.makeRect((int) (symbolBounds.left + width),
836                        (int) (symbolBounds.top - height),
837                        width,
838                        height);
839            }
840            else if (affiliation == 'H' || affiliation == 'S')//hostile,suspect
841            {
842                instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width,
843                        Math.round((int) symbolBounds.top - (height * 0.15f)),
844                        width,
845                        height);
846            }
847            else if (affiliation == 'P'
848                    || affiliation == 'U'
849                    || affiliation == 'G'
850                    || affiliation == 'W')
851            {
852                instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width,
853                        Math.round(symbolBounds.top - (height * 0.3f)),
854                        width,
855                        height);
856            }
857            else
858            {
859                instRectangle = RectUtilities.makeRect((int) symbolBounds.left + width,
860                        Math.round(symbolBounds.top - (height * 0.3f)),
861                        width,
862                        height);
863            }
864
865            //generate installation bounds//////////////////////////////
866            instBounds = new Rect(instRectangle.left + -1,
867                    instRectangle.top - 1,
868                    instRectangle.width() + 2,
869                    instRectangle.height() + 2);
870
871            imageBounds.union(instBounds);
872
873        }//*/
874        // </editor-fold>
875
876        // <editor-fold defaultstate="collapsed" desc="Build Engagement Bar (AO)">
877        //A:BBB-CC
878        String strAO = null;
879        Rect ebRectangle = null;
880        Rect ebBounds = null;
881        Rect ebTextBounds = null;
882        TextInfo ebText = null;
883
884        int ebTop = 0;
885        int ebLeft = 0;
886        int ebWidth = 0;
887        int ebHeight = 0;
888        Color ebColor = null;//SymbolUtilities.getFillColorOfAffiliation(symbolID);
889
890        if(attributes.containsKey(MilStdAttributes.EngagementBarColor))
891            ebColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.EngagementBarColor));
892        else
893            ebColor = fillColor;
894
895        if(SymbolUtilities.hasModifier(symbolID, Modifiers.AO_ENGAGEMENT_BAR) &&
896                modifiers.containsKey(Modifiers.AO_ENGAGEMENT_BAR))
897            strAO = modifiers.get(Modifiers.AO_ENGAGEMENT_BAR);
898        if(strAO != null)
899        {
900            ebText = new TextInfo(strAO, 0, 0, _modifierFont);
901            ebTextBounds = ebText.getTextBounds();
902            ebHeight = ebTextBounds.height() + 4;
903
904            int barOffset = Math.max(RendererSettings.getInstance().getDeviceDPI()/32, 4);
905
906            if(fdiBounds != null)//set bar above FDI if present
907            {
908                ebTop = fdiBounds.top - ebHeight - barOffset;
909            }
910            else if(tfBounds != null)//set bar above TF if present
911            {
912                ebTop = tfBounds.top - ebHeight - barOffset;
913            }
914            else if(echelonBounds != null)//set bar above echelon if present
915            {
916                ebTop = echelonBounds.top - ebHeight - barOffset;
917            }
918            else if(isCOnTop(symbolID) && modifiers.containsKey(Modifiers.C_QUANTITY))//OR frame in air/space
919            {
920                ebTop = symbolBounds.top - (int)(ebHeight*2.5f);
921            }
922            else if(ss == SymbolID.SymbolSet_LandInstallation)
923            {
924                ebTop = symbolBounds.top - ebHeight - (barOffset * 2);
925            }
926            else//position above symbol
927            {
928                ebTop = symbolBounds.top - ebHeight - barOffset;
929            }
930
931            //if text wider than symbol, extend the bar.
932            if(ebTextBounds.width() > symbolBounds.width())
933            {
934                ebWidth = ebTextBounds.width() + 4;
935                ebLeft = symbolCenter.x - (ebWidth/2);
936            }
937            else
938            {
939                ebLeft = symbolBounds.left + (int)Math.ceil(strokeWidthBasedOnDPI/2f);//1;//leave room for outline
940                ebWidth = symbolBounds.width() - (int)Math.ceil(strokeWidthBasedOnDPI);//2;//leave room for outline
941            }
942
943            //set text location within the bar
944            ebText.setLocation(symbolCenter.x - (ebTextBounds.width()/2), ebTop + ebHeight - ((ebHeight - ebTextBounds.height()) / 2));
945
946            ebRectangle = RectUtilities.makeRect(ebLeft,ebTop,ebWidth,ebHeight);
947            ebBounds = new Rect(ebRectangle);
948            RectUtilities.grow(ebBounds,(int)Math.ceil(strokeWidthBasedOnDPI/2f));
949
950            imageBounds.union(ebBounds);
951        }
952
953
954        // </editor-fold>
955
956        // <editor-fold defaultstate="collapsed" desc="Build HQ Staff">
957        Point pt1HQ = null;
958        Point pt2HQ = null;
959        Rect hqBounds = null;
960        //Draw HQ Staff
961        if (SymbolUtilities.isHQ(symbolID))
962        {
963            int affiliation = SymbolID.getAffiliation(symbolID);
964            int context = SymbolID.getContext(symbolID);
965            //get points for the HQ staff
966            if (SymbolUtilities.hasRectangleFrame(symbolID))
967            {
968                pt1HQ = new Point((int) symbolBounds.left + 1,
969                        (int) (symbolBounds.top + symbolBounds.height() - 1));
970            }
971            else
972            {
973                pt1HQ = new Point((int) symbolBounds.left + 1,
974                        (int) (symbolBounds.top + (symbolBounds.height() / 2)));
975            }
976            pt2HQ = new Point((int) pt1HQ.x, (int) (pt1HQ.y + symbolBounds.height()));
977
978            //create bounding rectangle for HQ staff.
979            hqBounds = new Rect(pt1HQ.x, pt1HQ.y, pt1HQ.x + 2, pt2HQ.y);
980            //adjust the image bounds accordingly.
981            imageBounds.union(hqBounds);
982            //imageBounds.shiftBR(0,pt2HQ.y-imageBounds.bottom);
983            //adjust symbol center
984            centerPoint.set(pt2HQ.x, pt2HQ.y);
985        }
986
987        // </editor-fold>
988
989        // <editor-fold defaultstate="collapsed" desc="Build DOM Arrow">
990        Point[] domPoints = null;
991        Rect domBounds = null;
992        if (modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT)
993                && SymbolUtilities.hasModifier(symbolID, Modifiers.Q_DIRECTION_OF_MOVEMENT))
994        {
995                String strQ = modifiers.get(Modifiers.Q_DIRECTION_OF_MOVEMENT);
996                
997                if(strQ != null && SymbolUtilities.isNumber(strQ))
998                {
999                    float q = Float.valueOf(strQ);
1000        
1001                    boolean isY = (modifiers.containsKey(Modifiers.Y_LOCATION));
1002        
1003                    domPoints = createDOMArrowPoints(symbolID, symbolBounds, symbolCenter, q, isY);
1004        
1005                    domBounds = new Rect(domPoints[0].x, domPoints[0].y, 1, 1);
1006        
1007                    Point temp = null;
1008                    for (int i = 1; i < 6; i++)
1009                    {
1010                        temp = domPoints[i];
1011                        if (temp != null)
1012                        {
1013                            domBounds.union(temp.x, temp.y);
1014                        }
1015                    }
1016                    imageBounds.union(domBounds);
1017                }
1018        }
1019
1020        // </editor-fold>
1021
1022        // <editor-fold defaultstate="collapsed" desc="Build Operational Condition Indicator">
1023        Rect ociBounds = null;
1024        RectF ociBoundsF = null;
1025        Rect ociShape = null;
1026        Path ociSlashShape = null;
1027        int ociOffset = Math.max(RendererSettings.getInstance().getDeviceDPI()/32, 4);
1028        if (SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AL_OPERATIONAL_CONDITION)) {
1029            if (mobilityBounds != null)
1030            {
1031                ociOffset = Math.round(mobilityBounds.bottom - symbolBounds.bottom) + 4;
1032            }
1033            if(RendererSettings.getInstance().getOperationalConditionModifierType() == RendererSettings.OperationalConditionModifierType_BAR)
1034            {
1035                ociShape = processOperationalConditionIndicator(symbolID, symbolBounds, ociOffset);
1036                if (ociShape != null)
1037                {
1038                    Rect temp = new Rect(ociShape);
1039                    RectUtilities.grow(temp, 2);
1040                    ociBounds = temp;
1041                    imageBounds.union(ociBounds);
1042                }
1043            }
1044            else//slash
1045            {
1046                ociSlashShape = processOperationalConditionIndicatorSlash(symbolID, symbolBounds);
1047                if (ociSlashShape != null)
1048                {
1049                    //build mobility bounds
1050                    ociBoundsF = new RectF();
1051                    ociBounds = new Rect();
1052                    ociSlashShape.computeBounds(ociBoundsF, true);
1053                    ociBoundsF.roundOut(ociBounds);
1054                    imageBounds.union(ociBounds);
1055                    ociBounds = null;
1056                }
1057            }
1058        }
1059
1060        // </editor-fold>
1061
1062        // <editor-fold defaultstate="collapsed" desc="Build Restricted Indicator">
1063        RectF rBounds = null;
1064        Path rPath = null;
1065        Path rPath2 = null;
1066        SVGPath rsvgPath = null;
1067        SVGPath rsvgPath2 = null;
1068        PointF rcirclePt = null;
1069        PointF rdotPt = null;
1070        float rdotRadius = 0;
1071        float rStrokeWidth = 3;
1072        if(SymbolID.getContext(symbolID) == SymbolID.StandardIdentity_Context_Restricted_Target_Reality)
1073        {
1074            // <path id="primary" d="M380,320l38,-67l40,67h-78m38,-11v-1m0,-10l0,-20" fill="yellow" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="7" />
1075            float nsTx = 0;
1076            float nsTy = 0;
1077            float ratio = 1;
1078            SVGInfo si = SVGLookup.getInstance().getSVGLInfo(SVGLookup.getFrameID(symbolID),SymbolID.getVersion(symbolID));
1079            if(symbolBounds.height() > symbolBounds.width())
1080            {
1081                double sHeight = si.getBbox().height();
1082                ratio = (float)(symbolBounds.height() / sHeight);
1083            }
1084            else
1085            {
1086                double sWidth = si.getBbox().width();
1087                ratio = (float)(symbolBounds.width() / sWidth);
1088            }
1089
1090            nsTx = (float)(si.getBbox().left * ratio) * -1;
1091            nsTy = (float)(si.getBbox().top * ratio) * -1;
1092
1093            //<path d="m373,313l53,-97l57,97l-110,0" fill="yellow" id="triangle" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="6"/>
1094            //<path d="m373,313L426,216L483,313L373,313" fill="yellow" id="triangle" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="6"/>
1095            rPath = new Path();//triangle
1096            rPath.moveTo(373f * ratio, 313f * ratio);
1097            rPath.lineTo(426f * ratio, 216f * ratio);
1098            rPath.lineTo(483f * ratio, 313f * ratio);
1099            rPath.lineTo(373f * ratio, 313f * ratio);
1100            rsvgPath = new SVGPath();//triangle
1101            rsvgPath.moveTo(373f * ratio, 313f * ratio);
1102            rsvgPath.lineTo(426f * ratio, 216f * ratio);
1103            rsvgPath.lineTo(483f * ratio, 313f * ratio);
1104            rsvgPath.lineTo(373f * ratio, 313f * ratio);
1105
1106            //<path d="M426.5,276L426.5,244" fill="none" id="line" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"/>
1107            rPath2 = new Path();//line
1108            rPath2.moveTo(426.5f * ratio, 276f * ratio);
1109            rPath2.lineTo(426.5f * ratio, 248f * ratio);
1110            rsvgPath2 = new SVGPath();//line
1111            rsvgPath2.moveTo(426.5f * ratio, 276f * ratio);
1112            rsvgPath2.lineTo(426.5f * ratio, 248f * ratio);
1113
1114            //<circle cx="426.5" cy="293" r="6" id="dot"/>//DOT
1115            rdotPt = new PointF(426.5f * ratio, 293 * ratio);
1116            rdotRadius = 5f * ratio;
1117
1118            //need to shift like we do the frame and main icons since it's based in that space
1119            rPath.offset(nsTx, nsTy);
1120            rPath2.offset(nsTx, nsTy);
1121            rsvgPath.shift(nsTx,nsTy);
1122            rsvgPath2.shift(nsTx,nsTy);
1123            rdotPt.offset(nsTx,nsTy);
1124            //rCircle = (Ellipse2D) txfm.createTransformedShape(rCircle);
1125
1126
1127            //RectF bounds = new RectF();
1128            //bounds = rPath.computeBounds(bounds);  //getBounds();//triangle bounds
1129            Rect bounds = rsvgPath.getBounds();
1130            rBounds = RectUtilities.makeRectF(bounds.left,bounds.top,bounds.width(), bounds.height());
1131            rStrokeWidth = (2/66.666667f) * ((float)symbolBounds.height() / SymbolUtilities.getUnitRatioHeight(symbolID));
1132            RectUtilities.grow(rBounds,(int)Math.ceil(rStrokeWidth/2));
1133            RectUtilities.grow(bounds,(int)Math.ceil(rStrokeWidth/2));
1134            imageBounds.union(bounds);
1135        }
1136        // </editor-fold>
1137
1138        // <editor-fold defaultstate="collapsed" desc="Build No Strike Indicator">
1139        RectF nsBounds = null;
1140        PointF nsCirclePt = null;
1141        float nsRadius = 0;
1142        Path nsLine = null;
1143        SVGPath nssvgLine = null;
1144        double nsStrokeWidth = 3;
1145        if(SymbolID.getContext(symbolID) == SymbolID.StandardIdentity_Context_No_Strike_Entity_Reality)
1146        {
1147            //octagon~182.08058166503906~272.0794677734375~245.8407440185547~244.85235595703125
1148            //restricted~375.44801678047673~248.63298320770264~85.1039714496415~79.36734275822477
1149            //no-strike~378.0~248.0~80.0~80.0
1150            //<circle cx="418" cy="288" fill="yellow" r="36" stroke="black" stroke-width="8"/>
1151            //<line fill="none" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" x1="390" x2="446" y1="265" y2="310"/>
1152            //nsCircle = new Ellipse(x,y,radius * 2, radius * 2);
1153            //nsLine = new Line(390 * ratio, 265 * ratio, 446 * ratio, 310 * ratio);
1154            float nsTx = 0;
1155            float nsTy = 0;
1156            float ratio = 1;
1157            SVGInfo si = SVGLookup.getInstance().getSVGLInfo(SVGLookup.getFrameID(symbolID),SymbolID.getVersion(symbolID));
1158            if(symbolBounds.height() > symbolBounds.width())
1159            {
1160                float sHeight = si.getBbox().height();
1161                ratio = symbolBounds.height() / sHeight;
1162            }
1163            else
1164            {
1165                float sWidth = si.getBbox().width();
1166                ratio = symbolBounds.width() / sWidth;
1167            }
1168
1169            nsTx = (si.getBbox().left * ratio) * -1;
1170            nsTy = (si.getBbox().top * ratio) * -1;
1171
1172            float radius = 50f * ratio;
1173            float x = 426f * ratio;
1174            float y = 267f * ratio;
1175            nsCirclePt = new PointF(x,y);
1176            nsRadius = radius;
1177            nsLine = new Path();
1178            nsLine.moveTo(390 * ratio, 235 * ratio);
1179            nsLine.lineTo(463 * ratio, 298 * ratio);
1180            nssvgLine = new SVGPath();
1181            nssvgLine.moveTo(390 * ratio, 235 * ratio);
1182            nssvgLine.lineTo(463 * ratio, 298 * ratio);
1183
1184            //need to shift like we do the frame and main icons since it's based in that space
1185            nsCirclePt.offset(nsTx,nsTy);
1186            nsLine.offset(nsTx,nsTy);
1187            nssvgLine.shift(nsTx,nsTy);
1188
1189            nsBounds = RectUtilities.makeRectF(nsCirclePt.x - radius, nsCirclePt.y - radius, radius * 2, radius * 2);
1190
1191            nsStrokeWidth = (2/66.666667) * (symbolBounds.height() / SymbolUtilities.getUnitRatioHeight(symbolID));
1192            RectUtilities.grow(nsBounds,(int)Math.ceil(nsStrokeWidth/2));
1193            imageBounds.union(RectUtilities.makeRectFromRectF(nsBounds));
1194        }
1195        // </editor-fold>
1196
1197        // <editor-fold defaultstate="collapsed" desc="Shift Modifiers">
1198        //adjust points if necessary
1199        if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0))
1200        {
1201            int shiftX = Math.abs(imageBounds.left);
1202            int shiftY = Math.abs(imageBounds.top);
1203
1204            if (hqBounds != null)
1205            {
1206                pt1HQ.offset(shiftX, shiftY);
1207                pt2HQ.offset(shiftX, shiftY);
1208            }
1209            if (echelonBounds != null)
1210            {
1211                tiEchelon.setLocation(tiEchelon.getLocation().x + shiftX, tiEchelon.getLocation().y + shiftY);
1212            }
1213            if (amBounds != null)
1214            {
1215                tiAM.setLocation(tiAM.getLocation().x + shiftX, tiAM.getLocation().y + shiftY);
1216            }
1217            if (tfBounds != null)
1218            {
1219                tfRectangle.offset(shiftX, shiftY);
1220                tfBounds.offset(shiftX, shiftY);
1221            }
1222            if(ebBounds != null)
1223            {
1224                ebRectangle.offset(shiftX, shiftY);
1225                ebBounds.offset(shiftX, shiftY);
1226                ebText.shift(shiftX, shiftY);
1227                ebTextBounds.offset(shiftX, shiftY);
1228            }
1229            /*if (instBounds != null)//part of symbol bounds now
1230            {
1231                instRectangle.offset(shiftX, shiftY);
1232                instBounds.offset(shiftX, shiftY);
1233            }//*/
1234            if (fdiBounds != null)
1235            {
1236                fdiBounds.offset(shiftX, shiftY);
1237                fdiLeft.offset(shiftX, shiftY);
1238                fdiTop.offset(shiftX, shiftY);
1239                fdiRight.offset(shiftX, shiftY);
1240            }
1241            if (liBounds != null)
1242            {
1243                liBounds.offset(shiftX, shiftY);
1244                liLeft.offset(shiftX, shiftY);
1245                liTop.offset(shiftX, shiftY);
1246                liRight.offset(shiftX, shiftY);
1247                if(liPath != null)
1248                {
1249                    liPath.offset(shiftX,shiftY);
1250                }
1251            }
1252            if (ociBounds != null)
1253            {
1254                ociBounds.offset(shiftX, shiftY);
1255                ociShape.offset(shiftX, shiftY);
1256            }
1257            if(ociBoundsF != null)
1258            {
1259                ociBoundsF.offset(shiftX, shiftY);
1260                ociSlashShape.offset(shiftX, shiftY);
1261            }
1262            if(rBounds != null)
1263            {
1264                rBounds.offset(shiftX, shiftY);//bounds
1265                rPath.offset(shiftX, shiftY);//triangle
1266                rPath2.offset(shiftX, shiftY);//exclamation
1267                rdotPt.offset(shiftX, shiftY);//dot
1268            }
1269            if(nsBounds != null)
1270            {
1271                nsBounds.offset(shiftX, shiftY);//bounds
1272                nsCirclePt.offset(shiftX, shiftY);//circle
1273                nsLine.offset(shiftX, shiftY);//line
1274            }
1275            if (domBounds != null)
1276            {
1277                for (int i = 0; i < 6; i++)
1278                {
1279                    Point temp = domPoints[i];
1280                    if (temp != null)
1281                    {
1282                        temp.offset(shiftX, shiftY);
1283                    }
1284                }
1285                domBounds.offset(shiftX, shiftY);
1286            }
1287            if (mobilityBounds != null)
1288            {
1289                //shift mobility points
1290                mobilityPath.offset(shiftX, shiftY);
1291                if (mobilityPathFill != null)
1292                {
1293                    mobilityPathFill.offset(shiftX, shiftY);
1294                }
1295
1296                mobilityBounds.offset(shiftX, shiftY);
1297            }
1298
1299            centerPoint.offset(shiftX, shiftY);
1300            symbolBounds.offset(shiftX, shiftY);
1301            imageBounds.offset(shiftX, shiftY);
1302        }
1303        // </editor-fold>
1304
1305        // <editor-fold defaultstate="collapsed" desc="Convert to SVG (SVGSymbolInfo)">
1306        if(sdi instanceof SVGSymbolInfo)
1307        {
1308            StringBuilder sbSVG = new StringBuilder();
1309            Path temp = null;
1310            SVGPath svgtemp = null;
1311            String svgStroke = RendererUtilities.colorToHexString(lineColor,false);
1312            String svgFill = RendererUtilities.colorToHexString(fillColor,false);
1313            String svgTextColor = RendererUtilities.colorToHexString(textColor,false);
1314            String svgTextBGColor = RendererUtilities.colorToHexString(textBackgroundColor,false);
1315            String svgStrokeWidth = String.valueOf(strokeWidthBasedOnDPI);
1316            String svgTextOutlineWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth());
1317            String svgAlpha = "1";
1318            if(alpha >= 0 && alpha <= 1)
1319                svgAlpha = String.valueOf(alpha);
1320            String svgDashArray = null;
1321
1322            if(hqBounds != null)
1323            {
1324                /*Line2D hqStaff = new Line2D.Double(pt1HQ,pt2HQ);
1325                temp = new Path2D.Double();
1326                temp.append(hqStaff,false);
1327                sbSVG.append(Shape2SVG.Convert(temp, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, null));//*/
1328
1329                svgtemp = new SVGPath();
1330                svgtemp.moveTo(pt1HQ.x, pt1HQ.y);
1331                svgtemp.lineTo(pt2HQ.x, pt2HQ.y);
1332                svgtemp.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,Float.parseFloat(svgAlpha),Float.parseFloat(svgAlpha),null);
1333            }
1334            if (echelonBounds != null)
1335            {
1336                sbSVG.append(Shape2SVG.Convert(tiEchelon, svgTextBGColor, svgTextColor, svgTextOutlineWidth, svgAlpha, svgAlpha, null));
1337            }
1338            if (amBounds != null)
1339            {
1340                sbSVG.append(Shape2SVG.Convert(tiAM, svgTextBGColor, svgTextColor, svgTextOutlineWidth, svgAlpha, svgAlpha, null));
1341            }
1342            if (tfBounds != null)
1343            {
1344                sbSVG.append(Shape2SVG.Convert(tfRectangle, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, null,null));
1345            }
1346            if(ebBounds != null)
1347            {
1348                String svgEBFill = RendererUtilities.colorToHexString(ebColor,false);
1349                //create fill and outline
1350                sbSVG.append(Shape2SVG.Convert(ebRectangle, svgStroke, svgEBFill, svgStrokeWidth, svgAlpha, svgAlpha, null,null));
1351                //create internal text
1352                sbSVG.append(Shape2SVG.Convert(ebText, null, "#000000", null, svgAlpha, svgAlpha, null));
1353            }
1354            if (fdiBounds != null)
1355            {
1356                /*int dpi = RendererSettings.getInstance().getDeviceDPI();
1357                int lineLength = dpi / 96 * 6;
1358                int lineGap = dpi / 96 * 4;
1359                String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/
1360
1361                /// ///////////////////////////////////
1362                //Divide line in 14 parts. line is 3 parts to 2 parts gap
1363                float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft);
1364                //distance = distance / 14f;
1365                int lineGap = (int)((distance / 14f) * 2);
1366                int lineLength = (int)((distance / 14f) * 3);
1367                String svgFDIDashArray = "" + lineLength + " " + lineGap;
1368                /// //////////////////////////////////
1369
1370                SVGPath fdiPath = new SVGPath();
1371
1372                fdiPath.moveTo(fdiTop.x, fdiTop.y);
1373                fdiPath.lineTo(fdiLeft.x, fdiLeft.y);
1374                fdiPath.moveTo(fdiTop.x, fdiTop.y);
1375                fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/
1376
1377                sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray,"round"));
1378
1379            }
1380            if (liBounds != null)
1381            {
1382                SVGPath svgliPath = new SVGPath();
1383                svgliPath.moveTo(liTop.x, liTop.y);
1384                svgliPath.lineTo(liLeft.x, liLeft.y);
1385                svgliPath.moveTo(liTop.x, liTop.y);
1386                svgliPath.lineTo(liRight.x, liRight.y);
1387
1388                sbSVG.append(svgliPath.toSVGElement(svgStroke,strokeWidthBasedOnDPI,null,Float.parseFloat(svgAlpha),Float.parseFloat(svgAlpha),"round"));
1389                //sbSVG.append(Shape2SVG.Convert(liPath, svgStroke, null, String.valueOf(liStrokeWidth), svgAlpha, svgAlpha, null));
1390            }
1391            if (ociBounds != null && ociShape != null)
1392            {
1393
1394                int status = SymbolID.getStatus(symbolID);
1395                Color statusColor = null;
1396
1397                switch (status) {
1398                    //Fully Capable
1399                    case SymbolID.Status_Present_FullyCapable:
1400                        statusColor = Color.green;
1401                        break;
1402                    //Damaged
1403                    case SymbolID.Status_Present_Damaged:
1404                        statusColor = Color.yellow;
1405                        break;
1406                    //Destroyed
1407                    case SymbolID.Status_Present_Destroyed:
1408                        statusColor = Color.red;
1409                        break;
1410                    //full to capacity(hospital)
1411                    case SymbolID.Status_Present_FullToCapacity:
1412                        statusColor = Color.blue;
1413                        break;
1414                    default:
1415                        break;
1416                }
1417
1418                String svgOCIStatusColor = RendererUtilities.colorToHexString(statusColor,false);
1419                sbSVG.append(Shape2SVG.Convert(ociBounds, null, svgStroke, svgStrokeWidth, svgAlpha, svgAlpha, null,null));
1420                sbSVG.append(Shape2SVG.Convert(ociShape, null, svgOCIStatusColor, svgStrokeWidth, svgAlpha, svgAlpha, null,null));
1421
1422                ociBounds = null;
1423                ociShape = null;
1424
1425            }
1426
1427            if (mobilityBounds != null)
1428            {
1429                if(svgMobilityGroup != null)
1430                    sbSVG.append(svgMobilityGroup);
1431                else if (svgMobilityPath != null)
1432                    sbSVG.append(svgMobilityPath.toSVGElement(svgStroke,strokeWidthBasedOnDPI,null,Float.parseFloat(svgAlpha),Float.parseFloat(svgAlpha),null));
1433
1434                mobilityBounds = null;
1435            }
1436
1437            //add symbol
1438            ssi = (SVGSymbolInfo)sdi;
1439            sbSVG.append(ssi.getSVG());
1440
1441            if (ociBounds != null && ociSlashShape != null)
1442            {
1443                SVGPath svgociSlash = processOperationalConditionIndicatorSlashSVG(symbolID,symbolBounds);
1444
1445                double size = symbolBounds.width();
1446                float ociStrokeWidth = 3f;
1447
1448                ociStrokeWidth = (float) size / 20f;
1449                if (ociStrokeWidth < 1f)
1450                    ociStrokeWidth = 1f;
1451
1452                sbSVG.append(svgociSlash.toSVGElement(svgStroke,ociStrokeWidth,null,Float.parseFloat(svgAlpha),Float.parseFloat(svgAlpha),null));
1453                //sbSVG.append(Shape2SVG.Convert(ociSlashShape, svgStroke, null, String.valueOf(ociStrokeWidth), svgAlpha, svgAlpha, null));
1454                ociBounds = null;
1455                ociSlashShape = null;
1456            }
1457
1458            if(rBounds != null)
1459            {
1460                String restrictedGroup = "<g id=\"restricted\" stroke-linecap=\"round\" stroke-linejoin=\"round\">";
1461                //triangle
1462                restrictedGroup += Shape2SVG.Convert(rsvgPath, "#000000", "#FFFF00", String.valueOf(rStrokeWidth),svgAlpha,svgAlpha,null,null);
1463                //exclamation
1464                restrictedGroup += Shape2SVG.Convert(rsvgPath2, "#000000", null, String.valueOf(rStrokeWidth * 1.66667),svgAlpha,svgAlpha,null,null);
1465                //dot
1466                restrictedGroup += Shape2SVG.ConvertCircle(rdotPt, rdotRadius, "#000000", "#000000", String.valueOf(rStrokeWidth),svgAlpha,svgAlpha,null);
1467                restrictedGroup += "</g>";
1468
1469                sbSVG.append(restrictedGroup);
1470            }
1471
1472            if(nsBounds != null)
1473            {
1474                String noStrikeGroup = "<g id=\"nostrike\">";
1475                noStrikeGroup += Shape2SVG.ConvertCircle(nsCirclePt, nsRadius,"#000000", "#FFFF00", String.valueOf(nsStrokeWidth),svgAlpha,svgAlpha,null);
1476                noStrikeGroup += Shape2SVG.Convert(nssvgLine, "#000000", null, String.valueOf(nsStrokeWidth),svgAlpha,svgAlpha,null,null);
1477                noStrikeGroup += "</g>";
1478                sbSVG.append(noStrikeGroup);
1479            }
1480
1481            if (domBounds != null)
1482            {
1483                //Path2D domPath = new Path2D.Double();
1484                SVGPath domPath = new SVGPath();
1485
1486                domPath.moveTo(domPoints[0].x, domPoints[0].y);
1487                if (domPoints[1] != null)
1488                {
1489                    domPath.lineTo(domPoints[1].x, domPoints[1].y);
1490                }
1491                if (domPoints[2] != null)
1492                {
1493                    domPath.lineTo(domPoints[2].x, domPoints[2].y);
1494                }
1495                //sbSVG.append(Shape2SVG.Convert(domPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, null));
1496                sbSVG.append(domPath.toSVGElement(svgStroke, Float.parseFloat(svgStrokeWidth), null,Float.parseFloat(svgAlpha), Float.parseFloat(svgAlpha),null));
1497
1498
1499                //domPath.reset();
1500                domPath = new SVGPath();
1501
1502                domPath.moveTo(domPoints[3].x, domPoints[3].y);
1503                domPath.lineTo(domPoints[4].x, domPoints[4].y);
1504                domPath.lineTo(domPoints[5].x, domPoints[5].y);
1505                sbSVG.append(Shape2SVG.Convert(domPath, "none", svgStroke, "0", svgAlpha, svgAlpha, null,null));
1506                sbSVG.append(domPath.toSVGElement("none", 0f, svgStroke,Float.parseFloat(svgAlpha), Float.parseFloat(svgAlpha),null));
1507
1508                domBounds = null;
1509                domPoints = null;
1510            }
1511
1512            newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds);
1513        }
1514
1515        // </editor-fold>
1516
1517        // <editor-fold defaultstate="collapsed" desc="Draw Modifiers (ImageInfo)">
1518        if(sdi instanceof ImageInfo)
1519        {
1520            ii = (ImageInfo) sdi;
1521
1522            Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888);
1523            Canvas ctx = new Canvas(bmp);
1524
1525            if (echelonBounds != null || amBounds != null) {
1526                //   ctx.font = RendererSettings.getModifierFont();
1527            }
1528
1529            //render////////////////////////////////////////////////////////
1530            Paint paint = new Paint();
1531            paint.setStyle(Style.STROKE);
1532            //paint.setColor(Color.black.toInt());
1533            paint.setColor(lineColor.toInt());
1534            if (alpha > -1)
1535                paint.setAlpha(alpha);
1536            paint.setStrokeWidth(2.0f);
1537
1538            paint.setStrokeWidth(strokeWidthBasedOnDPI);
1539
1540            if (hqBounds != null) {
1541                ctx.drawLine(pt1HQ.x, pt1HQ.y, pt2HQ.x, pt2HQ.y, paint);
1542            }
1543
1544            if (tfBounds != null) {
1545                ctx.drawRect(tfRectangle, paint);
1546            }
1547
1548        /*if (instBounds != null) Part of frame SVG now
1549        {
1550            paint.setStyle(Style.FILL);
1551            ctx.drawRect(instRectangle, paint);
1552        }//*/
1553
1554            if (ebBounds != null) {
1555                //draw bar fill
1556                paint.setStyle(Style.FILL);
1557                paint.setColor(ebColor.toInt());
1558                ctx.drawRect(ebRectangle, paint);
1559
1560                //draw bar outline
1561                paint.setStyle(Style.STROKE);
1562                paint.setStrokeWidth(4.0f);
1563                paint.setColor(lineColor.toInt());
1564                ctx.drawRect(ebRectangle, paint);
1565
1566                //draw bar text
1567                _modifierFont.setColor(Color.BLACK.toInt());
1568                _modifierFont.setStyle(Style.FILL);
1569                ctx.drawText(ebText.getText(), ebText.getLocation().x, ebText.getLocation().y, _modifierFont);
1570
1571                ebBounds = null;
1572                ebText = null;
1573                ebRectangle = null;
1574                paint.setStrokeWidth(strokeWidthBasedOnDPI);//2.0f
1575            }
1576
1577            if (echelonBounds != null) {
1578                TextInfo[] aTiEchelon =
1579                        {
1580                                tiEchelon
1581                        };
1582                renderText(ctx, aTiEchelon, textColor, textBackgroundColor);
1583
1584                echelonBounds = null;
1585                tiEchelon = null;
1586            }
1587
1588            if (amBounds != null) {
1589                TextInfo[] aTiAM =
1590                        {
1591                                tiAM
1592                        };
1593                renderText(ctx, aTiAM, textColor, textBackgroundColor);
1594                amBounds = null;
1595                tiAM = null;
1596            }
1597
1598            if (fdiBounds != null) {
1599
1600                Paint fdiPaint = new Paint();
1601                fdiPaint.setAntiAlias(true);
1602                fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0);
1603                if (alpha > -1)
1604                    fdiPaint.setAlpha(alpha);
1605                fdiPaint.setStyle(Style.STROKE);
1606
1607                /*int dpi = RendererSettings.getInstance().getDeviceDPI();
1608
1609                int lineLength = dpi / 96 * 6;
1610                int lineGap = dpi / 96 * 4;//*/
1611
1612                /// ///////////////////////////////////
1613                //Divide line in 14 parts. line is 3 parts to 2 parts gap
1614                float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft);
1615                //distance = distance / 14f;
1616                int lineGap = (int)((distance / 14f) * 2);
1617                int lineLength = (int)((distance / 14f) * 3);
1618                /// //////////////////////////////////
1619
1620                fdiPaint.setPathEffect(new DashPathEffect(new float[]
1621                        {
1622                                lineLength, lineGap
1623                        }, 0));
1624
1625
1626                fdiPaint.setStrokeCap(Cap.ROUND);
1627                fdiPaint.setStrokeJoin(Join.MITER);
1628                fdiPaint.setStrokeWidth(strokeWidthBasedOnDPI);
1629
1630                Path fdiPath = new Path();
1631
1632                fdiPath.moveTo(fdiTop.x, fdiTop.y);
1633                fdiPath.lineTo(fdiLeft.x, fdiLeft.y);
1634                fdiPath.moveTo(fdiTop.x, fdiTop.y);
1635                fdiPath.lineTo(fdiRight.x, fdiRight.y);
1636                ctx.drawPath(fdiPath, fdiPaint);
1637
1638                fdiBounds = null;
1639
1640            }
1641
1642            if (liBounds != null) {
1643
1644                Paint liPaint = new Paint();
1645                liPaint.setAntiAlias(true);
1646                liPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0);
1647                if (alpha > -1)
1648                    liPaint.setAlpha(alpha);
1649                liPaint.setStyle(Style.STROKE);
1650
1651                int dpi = RendererSettings.getInstance().getDeviceDPI();
1652
1653                liPaint.setStrokeCap(Cap.BUTT);
1654                liPaint.setStrokeJoin(Join.MITER);
1655                liPaint.setStrokeWidth(strokeWidthBasedOnDPI);
1656
1657                ctx.drawPath(liPath, liPaint);
1658
1659                liBounds = null;
1660
1661            }
1662
1663            if (mobilityBounds != null) {
1664                Paint mobilityPaint = new Paint();
1665                mobilityPaint.setStyle(Style.STROKE);
1666                //mobilityPaint.setColor(Color.black.toInt());
1667                mobilityPaint.setColor(lineColor.toInt());
1668                if (alpha > -1)
1669                    mobilityPaint.setAlpha(alpha);
1670
1671                //ctx.lineCap = "butt";
1672                //ctx.lineJoin = "miter";
1673                if (ad >= SymbolID.Mobility_WheeledLimitedCrossCountry && ad < SymbolID.Mobility_ShortTowedArray)//mobility
1674                {
1675                    //mobilityPaint.setStrokeWidth(3f);
1676                    mobilityPaint.setStrokeWidth(strokeWidthBasedOnDPI);
1677                    mobilityPaint.setAntiAlias(true);
1678                } else //towed-array
1679                {
1680                    //mobilityPaint.setStrokeWidth(3f);
1681                    mobilityPaint.setStrokeWidth(strokeWidthBasedOnDPI);
1682                    //mobilityPaint.setAntiAlias(true);
1683                }
1684
1685                ctx.drawPath(mobilityPath, mobilityPaint);
1686
1687                if (mobilityPathFill != null) {
1688                    mobilityPaint.setStyle(Style.FILL);
1689                    ctx.drawPath(mobilityPathFill, mobilityPaint);
1690                }
1691
1692                mobilityBounds = null;
1693
1694            }
1695
1696            if (ociBounds != null) {
1697                Paint ociPaint = new Paint();
1698
1699                int statusColor = 0;
1700                int status = SymbolID.getStatus(symbolID);
1701                if (status == (SymbolID.Status_Present_FullyCapable))//Fully Capable
1702                {
1703                    statusColor = Color.green.toInt();
1704                } else if (status == (SymbolID.Status_Present_Damaged))//Damage
1705                {
1706                    statusColor = Color.yellow.toInt();
1707                } else if (status == (SymbolID.Status_Present_Destroyed)) {
1708                    statusColor = Color.red.toInt();
1709                } else if (status == (SymbolID.Status_Present_FullToCapacity))//full to capacity(hospital)
1710                {
1711                    statusColor = Color.blue.toInt();
1712                }
1713
1714                ociPaint.setColor(lineColor.toInt());
1715                ociPaint.setStyle(Style.FILL);
1716
1717                if (alpha > -1)
1718                    ociPaint.setAlpha(alpha);
1719                ctx.drawRect(ociBounds, ociPaint);
1720                ociPaint.setColor(statusColor);
1721                if (alpha > -1)
1722                    ociPaint.setAlpha(alpha);
1723                ctx.drawRect(ociShape, ociPaint);
1724
1725                ociBounds = null;
1726                ociShape = null;
1727            }
1728
1729            //draw original icon.
1730            //ctx.drawImage(ii.getImage(),symbolBounds.left, symbolBounds.top);
1731            ctx.drawBitmap(ii.getImage(), null, symbolBounds, null);
1732
1733            if(rBounds != null)
1734            {
1735                Paint rPaint = new Paint();
1736                rPaint.setColor(Color.YELLOW.toInt());
1737                rPaint.setAlpha(alpha);
1738                rPaint.setStrokeCap(Cap.ROUND);
1739                rPaint.setStrokeJoin(Join.ROUND);
1740                rPaint.setStyle(Style.FILL);
1741                //triangle fill
1742                ctx.drawPath(rPath, rPaint);
1743
1744                //triangle outline
1745                rPaint.setStrokeWidth(rStrokeWidth);
1746                rPaint.setStyle(Style.STROKE);
1747                rPaint.setColor(Color.BLACK.toInt());
1748                ctx.drawPath(rPath, rPaint);
1749
1750                //exclamation line
1751                rPaint.setStrokeWidth(rStrokeWidth * 1.66667f);
1752                ctx.drawPath(rPath2, rPaint);
1753
1754                //exclamation dot
1755                rPaint.setStrokeWidth(rStrokeWidth);
1756                rPaint.setStyle(Style.FILL_AND_STROKE);
1757                ctx.drawCircle(rdotPt.x,rdotPt.y,rdotRadius,rPaint);
1758
1759            }
1760            if(nsBounds != null)
1761            {
1762                Paint nsPaint = new Paint();
1763                nsPaint.setColor(Color.YELLOW.toInt());
1764                nsPaint.setAlpha(alpha);
1765                nsPaint.setStrokeCap(Cap.ROUND);
1766                nsPaint.setStrokeJoin(Join.ROUND);
1767                nsPaint.setStyle(Style.FILL);
1768
1769                //circle fill
1770                ctx.drawCircle(nsCirclePt.x, nsCirclePt.y,nsRadius,nsPaint);
1771
1772                //circle outline
1773                nsPaint.setStyle(Style.STROKE);
1774                nsPaint.setColor(Color.BLACK.toInt());
1775                nsPaint.setStrokeWidth((float)nsStrokeWidth);
1776                ctx.drawCircle(nsCirclePt.x,nsCirclePt.y,nsRadius,nsPaint);
1777
1778                //draw slash
1779                ctx.drawPath(nsLine,nsPaint);
1780
1781            }
1782
1783            if (domBounds != null) {
1784                drawDOMArrow(ctx, domPoints, alpha, lineColor);
1785
1786                domBounds = null;
1787                domPoints = null;
1788            }
1789
1790            if (ociBoundsF != null) {
1791                Paint ociPaint = new Paint();
1792                int size = symbolBounds.width();
1793                float ociStrokeWidth = 3f;
1794
1795                ociStrokeWidth = size / 20f;
1796                if (ociStrokeWidth < 1f)
1797                    ociStrokeWidth = 1f;
1798            /*if(size > 50 && size < 100)
1799                ociStrokeWidth = 5f;
1800            else if(size >= 100 && size < 200)
1801                ociStrokeWidth = 7f;
1802            else if(size >= 200)
1803                ociStrokeWidth = 10f;*/
1804                //ociPaint.setColor(Color.black.toInt());
1805                ociPaint.setColor(lineColor.toInt());
1806                if (alpha > -1)
1807                    ociPaint.setAlpha(alpha);
1808                ociPaint.setStrokeWidth(ociStrokeWidth);
1809                ociPaint.setStrokeCap(Cap.BUTT);
1810                ociPaint.setStyle(Style.STROKE);
1811                ociPaint.setAntiAlias(true);
1812                ctx.drawPath(ociSlashShape, ociPaint);
1813
1814                ociBoundsF = null;
1815                ociSlashShape = null;
1816            }
1817
1818
1819            if (bmp != null)
1820                newsdi = new ImageInfo(bmp, centerPoint, symbolBounds);
1821        }
1822        // </editor-fold>
1823
1824        // <editor-fold defaultstate="collapsed" desc="Cleanup">
1825        // </editor-fold>
1826        if (newsdi != null)
1827        {
1828            return newsdi;
1829        }
1830        else
1831        {
1832            return null;
1833        }
1834
1835    }
1836
1837    /**
1838     *
1839     * @param symbolID
1840     * @return
1841     * @deprecated no longer a thing in 2525D
1842     * TODO: remove
1843     */
1844    private static double getYPositionForSCC(String symbolID)
1845    {
1846        double yPosition = 0.32;
1847        /*int aff = SymbolID.getAffiliation(symbolID);
1848        int context = SymbolID.getContext(symbolID);
1849        char affiliation = symbolID.charAt(1);
1850
1851        if(temp.equals("WMGC--"))//GROUND (BOTTOM) MILCO
1852        {
1853            if(affiliation == 'H' || 
1854                    affiliation == 'S')//suspect
1855                yPosition = 0.29;
1856            else if(affiliation == 'N' ||
1857                    affiliation == 'L')//exercise neutral
1858                yPosition = 0.32;
1859            else if(affiliation == 'F' ||
1860                    affiliation == 'A' ||//assumed friend
1861                    affiliation == 'D' ||//exercise friend
1862                    affiliation == 'M' ||//exercise assumed friend
1863                    affiliation == 'K' ||//faker
1864                    affiliation == 'J')//joker
1865                yPosition = 0.32;
1866            else
1867                yPosition = 0.34;
1868        }
1869        else if(temp.equals("WMMC--"))//MOORED MILCO
1870        {
1871            if(affiliation == 'H' || 
1872                    affiliation == 'S')//suspect
1873                yPosition = 0.25;
1874            else if(affiliation == 'N' ||
1875                    affiliation == 'L')//exercise neutral
1876                yPosition = 0.25;
1877            else if(affiliation == 'F' ||
1878                    affiliation == 'A' ||//assumed friend
1879                    affiliation == 'D' ||//exercise friend
1880                    affiliation == 'M' ||//exercise assumed friend
1881                    affiliation == 'K' ||//faker
1882                    affiliation == 'J')//joker
1883                yPosition = 0.25;
1884            else
1885                yPosition = 0.28;
1886        }
1887        else if(temp.equals("WMFC--"))//FLOATING MILCO
1888        {
1889            if(affiliation == 'H' || 
1890                    affiliation == 'S')//suspect
1891                yPosition = 0.29;
1892            else if(affiliation == 'N' ||
1893                    affiliation == 'L')//exercise neutral
1894                yPosition = 0.32;
1895            else if(affiliation == 'F' ||
1896                    affiliation == 'A' ||//assumed friend
1897                    affiliation == 'D' ||//exercise friend
1898                    affiliation == 'M' ||//exercise assumed friend
1899                    affiliation == 'K' ||//faker
1900                    affiliation == 'J')//joker
1901                yPosition = 0.32;
1902            else
1903                yPosition= 0.34;
1904        }
1905        else if(temp.equals("WMC---"))//GENERAL MILCO
1906        {
1907            if(affiliation == 'H' || 
1908                    affiliation == 'S')//suspect
1909                yPosition = 0.33;
1910            else if(affiliation == 'N' ||
1911                    affiliation == 'L')//exercise neutral
1912                yPosition = 0.36;
1913            else if(affiliation == 'F' ||
1914                    affiliation == 'A' ||//assumed friend
1915                    affiliation == 'D' ||//exercise friend
1916                    affiliation == 'M' ||//exercise assumed friend
1917                    affiliation == 'K' ||//faker
1918                    affiliation == 'J')//joker
1919                yPosition = 0.36;
1920            else
1921                yPosition = 0.36;
1922        }*/
1923        
1924        return yPosition;
1925    }
1926
1927    /**
1928     *
1929     * @param {type} symbolID
1930     * @param {type} bounds symbolBounds SO.Rectangle
1931     * @param {type} center SO.Point Location where symbol is centered.
1932     * @param {type} angle in degrees
1933     * @param {Boolean} isY Boolean.
1934     * @returns {Array} of SO.Point. First 3 items are the line. Last three are
1935     * the arrowhead.
1936     */
1937    private static Point[] createDOMArrowPoints(String symbolID, Rect bounds, Point center, float angle, boolean isY)
1938    {
1939        Point[] arrowPoints = new Point[6];
1940        Point pt1 = null;
1941        Point pt2 = null;
1942        Point pt3 = null;
1943
1944        int affiliation = SymbolID.getAffiliation(symbolID);
1945        int context = SymbolID.getContext(symbolID);
1946        int length = 40;
1947        if (SymbolUtilities.isCBRNEvent(symbolID))
1948        {
1949            length = Math.round(bounds.height() / 2);
1950        }
1951        else if((SymbolUtilities.isHQ(symbolID)))
1952        {
1953            if(SymbolUtilities.hasRectangleFrame(symbolID))
1954                length = bounds.height();
1955            else
1956                length = (int)Math.round(bounds.height() * 0.7);
1957        }
1958        else// if(bounds.height() >= 100)
1959        {
1960            length = (int)Math.round(bounds.height() * 0.7);
1961        }
1962
1963        //get endpoint
1964        int dx2, dy2,
1965                x1, y1,
1966                x2, y2;
1967
1968        x1 = Math.round(center.x);
1969        y1 = Math.round(center.y);
1970
1971        pt1 = new Point(x1, y1);
1972
1973        if (SymbolUtilities.hasModifier(symbolID, Modifiers.Q_DIRECTION_OF_MOVEMENT ) &&
1974            SymbolUtilities.isCBRNEvent(symbolID) ||
1975                SymbolUtilities.isLand(symbolID) ||
1976                SymbolID.getSymbolSet(symbolID)==SymbolID.SymbolSet_DismountedIndividuals)
1977        {
1978            //drawStaff = true;
1979            if(SymbolUtilities.isHQ(symbolID)==false)//has HQ staff to start from
1980            {
1981                y1 = bounds.top + bounds.height();
1982                pt1 = new Point(x1, y1);
1983
1984                if (isY == true && SymbolUtilities.isCBRNEvent(symbolID))//make room for y modifier
1985                {
1986                    int yModifierOffset = (int) _modifierFontHeight;
1987
1988                    yModifierOffset += RS.getTextOutlineWidth();
1989
1990                    pt1.offset(0, yModifierOffset);
1991                }
1992
1993                y1 = y1 + length;
1994                pt2 = new Point(x1, y1);
1995            }
1996            else
1997            {
1998                x1 = bounds.left+1;
1999                pt2 = new Point(x1, y1);
2000                if(SymbolUtilities.hasRectangleFrame(symbolID))
2001                {
2002                    /*y1 = bounds.top + bounds.height();
2003                    pt1 = new Point(x1, y1);
2004                    y1 = y1 + length;
2005                    pt2 = new Point(x1, y1);//*/
2006
2007                    pt1.x = x1;
2008                    y1 = bounds.top + (bounds.height());
2009                    pt1.y = y1;
2010                    x2 = x1;
2011                    pt2.x = x2;
2012                    y1 = pt1.y + bounds.height();
2013                    pt2.y = y1;//*/
2014
2015                }
2016                else
2017                {
2018                    pt1.x = x1;
2019                    y1 = bounds.top + (bounds.height() / 2);
2020                    pt1.y = y1;
2021                    x2 = x1;
2022                    pt2.x = x2;
2023                    y1 = pt1.y + bounds.height();
2024                    pt2.y = y1;
2025                }
2026            }
2027        }
2028
2029            //get endpoint given start point and an angle
2030        //x2 = x1 + (length * Math.cos(radians)));
2031        //y2 = y1 + (length * Math.sin(radians)));
2032        angle = angle - 90;//in java, east is zero, we want north to be zero
2033        double radians = 0;
2034        radians = (angle * (Math.PI / 180));//convert degrees to radians
2035
2036        dx2 = x1 + (int) (length * Math.cos(radians));
2037        dy2 = y1 + (int) (length * Math.sin(radians));
2038        x2 = Math.round(dx2);
2039        y2 = Math.round(dy2);
2040
2041
2042        //UPDATED ARROWHEAD CODE
2043        Point[] head = null;
2044        Point endPoint = new Point((int) x2, (int) y2);
2045        if(pt2 != null)
2046            head = createDOMArrowHead(pt2, endPoint);//pt3);
2047        else
2048            head = createDOMArrowHead(pt1, endPoint);//pt3);
2049
2050        if(head != null)
2051        {
2052            arrowPoints[0] = pt1;
2053            arrowPoints[1] = pt2;
2054            arrowPoints[2] = pt3;
2055            arrowPoints[3] = head[0];
2056            arrowPoints[4] = head[1];
2057            arrowPoints[5] = head[2];
2058
2059            //adjusted endpoint
2060            if(head.length >= 4 && head[3] != null)
2061            {
2062                arrowPoints[2] = head[3];
2063            }
2064        }
2065
2066        return arrowPoints;
2067
2068    }
2069
2070    private static Point[] createDOMArrowHead(Point lpt1, Point lpt2)
2071    {
2072        Point[] arrowPoints = new Point[6];
2073        Point pt1 = null;
2074        Point pt2 = null;
2075        Point pt3 = null;
2076
2077        int x1 = lpt1.x;
2078        int y1 = lpt1.y;
2079        int x2 = lpt2.x;
2080        int y2 = lpt2.y;
2081
2082        // Compute direction vector
2083        double dx = x2 - x1;
2084        double dy = y2 - y1;
2085        double length = Math.sqrt(dx * dx + dy * dy);
2086
2087        // Scale triangle size
2088        double scale = length * 0.1;  // Scaling factor for size
2089        double offset = scale * 1.5;  // Move triangle further down the line
2090
2091        // Normalize direction vector
2092        double unitX = dx / length;
2093        double unitY = dy / length;
2094
2095        // Compute perpendicular vector for triangle base
2096        double nx = -unitY;
2097        double ny = unitX;
2098
2099        // Compute adjusted triangle vertices
2100        int tipX = x2;
2101        int tipY = y2;
2102        int baseX1 = (int) (x2 - offset * unitX + scale * nx);
2103        int baseY1 = (int) (y2 - offset * unitY + scale * ny);
2104        int baseX2 = (int) (x2 - offset * unitX - scale * nx);
2105        int baseY2 = (int) (y2 - offset * unitY - scale * ny);
2106
2107
2108        //arrowHead = new Polygon(xPoints, yPoints, 3);
2109        arrowPoints[0] = new Point(tipX,tipY);
2110        arrowPoints[1] = new Point(baseX1,baseY1);
2111        arrowPoints[2] = new Point(baseX2,baseY2);
2112        // Adjust line endpoint to be the middle of the base line of the arrowhead
2113        int adjustedX2 = (baseX1 + baseX2) / 2;
2114        int adjustedY2 = (baseY1 + baseY2) / 2;
2115        arrowPoints[3] = new Point(adjustedX2,adjustedY2);
2116
2117        return arrowPoints;
2118
2119    }
2120
2121    private static void drawDOMArrow(Canvas ctx, Point[] domPoints, int alpha, Color lineColor)
2122    {
2123        float domStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f);
2124        if(domStrokeWidth < 1)
2125            domStrokeWidth=1;
2126
2127
2128        Paint domPaint = new Paint();
2129        domPaint.setAntiAlias(true);
2130        domPaint.setStrokeCap(Cap.BUTT);
2131        domPaint.setStrokeJoin(Join.MITER);
2132        domPaint.setStrokeWidth(domStrokeWidth);//3
2133        domPaint.setColor(lineColor.toInt());
2134        domPaint.setStyle(Style.STROKE);
2135        if(alpha > -1)
2136            domPaint.setAlpha(alpha);
2137
2138        Path domPath = new Path();
2139        domPath.moveTo(domPoints[0].x, domPoints[0].y);
2140        if (domPoints[1] != null)
2141        {
2142            domPath.lineTo(domPoints[1].x, domPoints[1].y);
2143        }
2144        if (domPoints[2] != null)
2145        {
2146            domPath.lineTo(domPoints[2].x, domPoints[2].y);
2147        }
2148        ctx.drawPath(domPath, domPaint);
2149
2150        domPath.reset();
2151        domPaint.setStyle(Style.FILL);
2152        domPath.moveTo(domPoints[3].x, domPoints[3].y);
2153        domPath.lineTo(domPoints[4].x, domPoints[4].y);
2154        domPath.lineTo(domPoints[5].x, domPoints[5].y);
2155        ctx.drawPath(domPath, domPaint);
2156    }
2157
2158    private static Rect processOperationalConditionIndicator(String symbolID, Rect symbolBounds, int offsetY)
2159    {
2160        //create Operational Condition Indicator
2161        //set color
2162        Rect bar = null;
2163        int status;
2164        Color statusColor;
2165        int barSize = 0;
2166        int pixelSize = symbolBounds.height();
2167
2168        status = SymbolID.getStatus(symbolID);
2169        if (status == SymbolID.Status_Present_FullyCapable ||
2170                status == SymbolID.Status_Present_Damaged ||
2171                status == SymbolID.Status_Present_Destroyed ||
2172                status == SymbolID.Status_Present_FullToCapacity)
2173        {
2174            if (pixelSize > 0)
2175            {
2176                barSize = Math.round(pixelSize / 5);
2177            }
2178
2179            if (barSize < 2)
2180            {
2181                barSize = 2;
2182            }
2183
2184            offsetY += Math.round(symbolBounds.top + symbolBounds.height());
2185
2186            bar = RectUtilities.makeRect(symbolBounds.left + 2, offsetY, Math.round(symbolBounds.width()) - 4, barSize);
2187        }
2188
2189        return bar;
2190    }
2191
2192    private static Path processOperationalConditionIndicatorSlash(String symbolID, Rect symbolBounds)
2193    {
2194        //create Operational Condition Indicator
2195        Path path = null;
2196        int status;
2197        status = SymbolID.getStatus(symbolID);
2198
2199        if (status == SymbolID.Status_Present_Damaged  || status == SymbolID.Status_Present_Destroyed)
2200        {
2201            float widthRatio = SymbolUtilities.getUnitRatioWidth(symbolID);
2202            float heightRatio = SymbolUtilities.getUnitRatioHeight(symbolID);
2203
2204            float slashHeight = (symbolBounds.height() / heightRatio * 1.47f);
2205            float slashWidth = (symbolBounds.width() / widthRatio * 0.85f);
2206            float centerX = symbolBounds.exactCenterX();
2207            float centerY = symbolBounds.exactCenterY();
2208            path = new Path();
2209            if(status == SymbolID.Status_Present_Damaged)//Damaged /
2210            {
2211                path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2));
2212                path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2));
2213            }
2214            else if(status == SymbolID.Status_Present_Destroyed)//Destroyed X
2215            {
2216                path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2));
2217                path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2));
2218                path.moveTo(centerX - (slashWidth/2),centerY-(slashHeight/2));
2219                path.lineTo(centerX + (slashWidth/2),centerY+(slashHeight/2));
2220            }
2221            return path;
2222
2223        }
2224
2225        return path;
2226    }
2227
2228    private static SVGPath processOperationalConditionIndicatorSlashSVG(String symbolID, Rect symbolBounds)
2229    {
2230        //create Operational Condition Indicator
2231        SVGPath path = null;
2232        int status;
2233        status = SymbolID.getStatus(symbolID);
2234
2235        if (status == SymbolID.Status_Present_Damaged  || status == SymbolID.Status_Present_Destroyed)
2236        {
2237            float widthRatio = SymbolUtilities.getUnitRatioWidth(symbolID);
2238            float heightRatio = SymbolUtilities.getUnitRatioHeight(symbolID);
2239
2240            float slashHeight = (symbolBounds.height() / heightRatio * 1.47f);
2241            float slashWidth = (symbolBounds.width() / widthRatio * 0.85f);
2242            float centerX = symbolBounds.exactCenterX();
2243            float centerY = symbolBounds.exactCenterY();
2244            path = new SVGPath();
2245            if(status == SymbolID.Status_Present_Damaged)//Damaged /
2246            {
2247                path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2));
2248                path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2));
2249            }
2250            else if(status == SymbolID.Status_Present_Destroyed)//Destroyed X
2251            {
2252                path.moveTo(centerX - (slashWidth/2),centerY+(slashHeight/2));
2253                path.lineTo(centerX + (slashWidth/2),centerY-(slashHeight/2));
2254                path.moveTo(centerX - (slashWidth/2),centerY-(slashHeight/2));
2255                path.lineTo(centerX + (slashWidth/2),centerY+(slashHeight/2));
2256            }
2257            return path;
2258
2259        }
2260
2261        return path;
2262    }
2263
2264
2265    public static SymbolDimensionInfo processSpeedLeader(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
2266    {
2267        SymbolDimensionInfo rsdi = sdi;
2268
2269        Rect imageBounds = sdi.getImageBounds();
2270        Rect symbolBounds = sdi.getSymbolBounds();
2271        Point symbolCenter = sdi.getCenterPoint();
2272        int ss = SymbolID.getSymbolSet(symbolID);
2273        int pixelSize = RendererSettings.getInstance().getDefaultPixelSize();
2274        int dpi = RendererSettings.getInstance().getDeviceDPI();
2275        if(attributes.containsKey(MilStdAttributes.PixelSize))
2276            pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize));
2277        float strokeWidth = 3f;
2278        strokeWidth = (float) dpi / 48f;
2279        if (strokeWidth < 1f)
2280            strokeWidth = 1f;
2281
2282        Path slPath = null;
2283        SVGPath slsvgPath = null;
2284        Rect slBounds = null;
2285        try {
2286            if (SymbolUtilities.hasModifier(symbolID, Modifiers.AJ_SPEED_LEADER) &&
2287                    (modifiers.containsKey(Modifiers.AJ_SPEED_LEADER))) {
2288                String aj = modifiers.get(Modifiers.AJ_SPEED_LEADER);
2289                String[] values = aj.split(" ");
2290                if (values.length >= 3) {
2291                    int speed = Integer.parseInt(values[0]);
2292                    String speedUnit = values[1];
2293                    int angle = 0;
2294                    if (values[2].length() == 3)
2295                        angle = Integer.parseInt(values[2]) - 90;
2296                    else
2297                        angle = (int) (Integer.parseInt(values[2]) * 0.05625) - 90;
2298
2299                    slPath = new Path();
2300                    slPath.moveTo(symbolCenter.x, symbolCenter.y);
2301                    slsvgPath = new SVGPath();
2302                    slsvgPath.moveTo(symbolCenter.x, symbolCenter.y);
2303
2304                    //convert to Knots
2305                    switch (speedUnit)//KPH, KPS, MPH, NMH, KTS//https://www.aviationhunt.com/speed-converter/
2306                    {
2307                        case "KPH":
2308                            speed = (int) (speed * 0.539957);
2309                            break;
2310                        case "KPS"://https://www.metric-conversions.org/speed/kilometers-per-second-to-knots.htm
2311                            speed = (int) (speed * 1943.84);
2312                            break;
2313                        case "MPH":
2314                            speed = (int) (speed * 0.86897);
2315                            break;
2316                    }
2317
2318                    int distance = 0;
2319                    char frame = SymbolID.getFrameShape(symbolID);
2320                    boolean fast = false;
2321                    if (frame == '0' && ss == SymbolID.SymbolSet_Air ||
2322                            ss == SymbolID.SymbolSet_AirMissile ||
2323                            ss == SymbolID.SymbolSet_SignalsIntelligence_Air ||
2324                            ss == SymbolID.SymbolSet_SpaceMissile ||
2325                            ss == SymbolID.SymbolSet_Space ||
2326                            (SymbolID.getVersion(symbolID) <= SymbolID.Version_2525Dch1 && ss == SymbolID.SymbolSet_SignalsIntelligence_Space))
2327                    {
2328                        fast = true;
2329                    }
2330                    else if(frame == SymbolID.FrameShape_Air || frame == SymbolID.FrameShape_Space)
2331                    {
2332                        fast = true;
2333                    }
2334
2335                    float distanceScaler = dpi;//spec does scale by inch, but if the symbol is too big, scale by pixel size
2336                    if(dpi < pixelSize)
2337                        distanceScaler = pixelSize;
2338
2339                    if(fast)
2340                    {//aircraft might be 1/4 inch if its speed is less than 300 knots, 1/2 inch if its speed is between 300 and 600 knots and 3/4 inch if its speed is more than 600 knots.
2341                        if (speed < 300)
2342                            distance = (int) (distanceScaler * 0.25)/300 * speed;
2343                        else if (speed < 600)
2344                            distance = (int) (distanceScaler * 0.5)/600 * speed;
2345                        else
2346                            distance = (int) (distanceScaler * 0.75);
2347                    }
2348                    else//submarine might be 1/4 inch if its speed is less than 15 knots, 1/2 inch if its speed is between 15 and 30 knots and 3/4 inch if its speed is more than 30 knots
2349                    {
2350                        if (speed < 15)
2351                            distance = (int) (distanceScaler * 0.25)/15 * speed;
2352                        else if (speed < 30)
2353                            distance = (int) (distanceScaler * 0.5)/30 * speed;
2354                        else
2355                            distance = (int) (distanceScaler * 0.75);
2356                    }
2357                    double radians = (angle * (Math.PI / 180));//convert degrees to radians
2358                    int x2 = (int) (symbolCenter.x + distance * Math.cos(radians));
2359                    int y2 = (int) (symbolCenter.y + distance * Math.sin(radians));
2360
2361                    slPath.lineTo(x2, y2);
2362                    slsvgPath.lineTo(x2, y2);
2363                    slBounds = slsvgPath.getBounds();
2364                    imageBounds.union(slBounds);
2365                }
2366
2367                if (sdi instanceof ImageInfo) {
2368                    Bitmap bmp = Bitmap.createBitmap((int) Math.ceil(imageBounds.width()), (int) Math.ceil(imageBounds.height()), Config.ARGB_8888);
2369                    Canvas ctx = new Canvas(bmp);
2370
2371                    int alpha = 1;
2372                    if (attributes.containsKey(MilStdAttributes.Alpha))
2373                        alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha));
2374
2375
2376                    Paint slPaint = new Paint();
2377                    slPaint.setColor(Color.BLACK.toInt());
2378                    slPaint.setAlpha(alpha * 255);
2379                    slPaint.setStyle(Style.STROKE);
2380                    slPaint.setStrokeWidth(strokeWidth);
2381
2382
2383                    float offsetX = 0;
2384                    float offsetY = 0;
2385                    if (imageBounds.left < 0)
2386                        offsetX = imageBounds.left * -1;
2387                    if (imageBounds.top < 0)
2388                        offsetY = imageBounds.top * -1;
2389
2390                    slPath.offset(offsetX,offsetY);
2391
2392                    slPath.offset(offsetX,offsetY);
2393                    ctx.drawBitmap(((ImageInfo) sdi).getImage(), offsetX, offsetY, null);
2394                    ctx.drawPath(slPath,slPaint);
2395
2396                    imageBounds.offset((int)offsetX,(int)offsetY);
2397                    symbolBounds.offset((int)offsetX,(int)offsetY);
2398                    symbolCenter.offset((int)offsetX,(int)offsetY);
2399
2400                    rsdi = new ImageInfo(bmp, symbolCenter, symbolBounds);
2401                }
2402                else if (sdi instanceof SVGSymbolInfo)
2403                {//public static String Convert(Shape shape,String stroke, String fill, String strokeWidth, String strokeOpacity, String fillOpacity, String dashArray, String lineCap)
2404                    String svg = ((SVGSymbolInfo) sdi).getSVG();
2405
2406                    svg += (Shape2SVG.Convert(slPath, "#000000", "none", String.valueOf(strokeWidth),null,null,null, null));
2407                    rsdi = new SVGSymbolInfo(svg,symbolCenter,symbolBounds,imageBounds);
2408                }
2409            }
2410        }
2411        catch(Exception exc)
2412        {
2413            ErrorLogger.LogException("ModifierRenderer","processSpeedLineIndicator",exc);
2414        }
2415
2416        return rsdi;
2417    }
2418
2419    /**
2420     * uses 2525C layout which shows most modifiers
2421     * @param sdi
2422     * @param symbolID
2423     * @param modifiers
2424     * @param attributes
2425     * @return
2426     */
2427    public static SymbolDimensionInfo processUnknownTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
2428    {
2429        int bufferHorizontal = (int)_modifierFontHeight/2;
2430        int bufferXL = bufferHorizontal;
2431        int bufferXR = bufferHorizontal;
2432        int bufferY = 2;
2433        int bufferText = 2;
2434        int x = 0;
2435        int y = 0;//best y
2436
2437        SymbolDimensionInfo  newsdi = null;
2438
2439        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
2440
2441        int descent = (int) (_modifierFontDescent + 0.5);
2442
2443        Rect labelBounds = null;
2444        int labelWidth, labelHeight;
2445
2446        Rect bounds = new Rect(sdi.getSymbolBounds());
2447        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
2448        Point centerPoint = new Point(sdi.getCenterPoint());
2449        Rect imageBounds = new Rect(sdi.getImageBounds());
2450
2451        int echelon = SymbolID.getAmplifierDescriptor(symbolID);
2452        String echelonText = SymbolUtilities.getEchelonText(echelon);
2453        String amText = SymbolUtilities.getStandardIdentityModifier(symbolID);
2454        int mobility = SymbolID.getAmplifierDescriptor(symbolID);
2455
2456        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
2457        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
2458
2459
2460        //check if text is too tall:
2461        boolean byLabelHeight = false;
2462        labelHeight = (int) (_modifierFontHeight + 0.5);/* RendererUtilities.measureTextHeight(RendererSettings.getModifierFontName(),
2463         RendererSettings.getModifierFontSize(),
2464         RendererSettings.getModifierFontStyle()).fullHeight;*/
2465
2466        int maxHeight = (bounds.height());
2467        if ((labelHeight * 3) > maxHeight)
2468        {
2469            byLabelHeight = true;
2470        }
2471
2472        //Affiliation Modifier being drawn as a display modifier
2473        String affiliationModifier = null;
2474        if (RS.getDrawAffiliationModifierAsLabel() == true)
2475        {
2476            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
2477        }
2478        if (affiliationModifier != null)
2479        {   //Set affiliation modifier
2480            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
2481            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
2482        }//*/
2483
2484
2485        //            int y0 = 0;//W            E/F
2486        //            int y1 = 0;//X/Y          G
2487        //            int y2 = 0;//V/AD/AE      H/AF
2488        //            int y3 = 0;//T            M CC
2489        //            int y4 = 0;//Z            J/K/L/N/P
2490        //
2491
2492        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
2493        String modifierValue = null;
2494        TextInfo tiTemp = null;
2495        //if(Modifiers.C_QUANTITY in modifiers
2496        if (modifiers.containsKey(Modifiers.C_QUANTITY)
2497                && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.C_QUANTITY))
2498        {
2499            String text = modifiers.get(Modifiers.C_QUANTITY);
2500            if(text != null)
2501            {
2502                    //bounds = armyc2.c5isr.renderer.utilities.RendererUtilities.getTextOutlineBounds(_modifierFont, text, new SO.Point(0,0));
2503                    tiTemp = new TextInfo(text, 0, 0, _modifierFont);
2504                    labelBounds = tiTemp.getTextBounds();
2505                    labelWidth = labelBounds.width();
2506                    x = Math.round((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f));
2507                    y = Math.round(symbolBounds.top - bufferY - descent);
2508                    tiTemp.setLocation(x, y);
2509                    tiArray.add(tiTemp);
2510            }
2511        }
2512
2513        //if(Modifiers.X_ALTITUDE_DEPTH in modifiers || Modifiers.Y_LOCATION in modifiers)
2514        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))
2515        {
2516            modifierValue = null;
2517
2518            String xm = null,
2519                    ym = null;
2520
2521            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.X_ALTITUDE_DEPTH))
2522            {
2523                xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);// xm = modifiers.X;
2524            }
2525            if (modifiers.containsKey(Modifiers.Y_LOCATION))
2526            {
2527                ym = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
2528            }
2529            if (xm == null && ym != null)
2530            {
2531                modifierValue = ym;
2532            }
2533            else if (xm != null && ym == null)
2534            {
2535                modifierValue = xm;
2536            }
2537            else if (xm != null && ym != null)
2538            {
2539                modifierValue = xm + "  " + ym;
2540            }
2541
2542            if(modifierValue != null)
2543            {
2544                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2545                    labelBounds = tiTemp.getTextBounds();
2546                    labelWidth = labelBounds.width();
2547        
2548                    if (!byLabelHeight)
2549                    {
2550                        x = bounds.left - labelBounds.width() - bufferXL;
2551                        y = bounds.top + labelHeight - descent;
2552                    }
2553                    else
2554                    {
2555                        x = bounds.left - labelBounds.width() - bufferXL;
2556        
2557                        y = (bounds.height());
2558                        y = (int) ((y * 0.5) + (labelHeight * 0.5));
2559        
2560                        y = y - ((labelHeight + bufferText));
2561                        y = bounds.top + y;
2562                    }
2563        
2564                    tiTemp.setLocation(x, y);
2565                    tiArray.add(tiTemp);
2566            }
2567        }
2568
2569        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) )
2570        {
2571            modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
2572
2573            if(modifierValue != null)
2574            {
2575                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2576                    labelBounds = tiTemp.getTextBounds();
2577                    labelWidth = labelBounds.width();
2578        
2579                    x = bounds.left + bounds.width() + bufferXR;
2580                    if (!byLabelHeight)
2581                    {
2582                        y = bounds.top + labelHeight - descent;
2583                    }
2584                    else
2585                    {
2586                        y = (bounds.height());
2587                        y = (int) ((y * 0.5) + (labelHeight * 0.5));
2588        
2589                        y = y - ((labelHeight + bufferText));
2590                        y = bounds.top + y;
2591                    }
2592        
2593                    tiTemp.setLocation(x, y);
2594                    tiArray.add(tiTemp);
2595
2596            }
2597        }
2598
2599        if ((modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) ||
2600                (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) ||
2601                (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME)))
2602        {
2603            String vm = null,
2604                    adm = null,
2605                    aem = null;
2606
2607            if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.V_EQUIP_TYPE))
2608            {
2609                vm = modifiers.get(Modifiers.V_EQUIP_TYPE);
2610            }
2611            if (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AD_PLATFORM_TYPE))
2612            {
2613                adm = modifiers.get(Modifiers.AD_PLATFORM_TYPE);
2614            }
2615            if (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
2616            {
2617                aem = modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME);
2618            }
2619
2620            modifierValue = "";
2621            if(vm != null && vm.equals("") == false)
2622                modifierValue = vm;
2623            if(adm != null && adm.equals("") == false)
2624                modifierValue += " " + adm;
2625            if(aem != null && aem.equals("") == false)
2626                modifierValue += " " + aem;
2627
2628            if(modifierValue != null)
2629                modifierValue = modifierValue.trim();
2630            if(modifierValue != null && modifierValue.equals("") == false)
2631            {
2632                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2633                    labelBounds = tiTemp.getTextBounds();
2634                    labelWidth = labelBounds.width();
2635        
2636                    x = bounds.left - labelBounds.width() - bufferXL;
2637        
2638                    y = (bounds.height());
2639                    y = (int) ((y * 0.5f) + ((labelHeight - descent) * 0.5f));
2640                    y = bounds.top + y;
2641        
2642                    tiTemp.setLocation(x, y);
2643                    tiArray.add(tiTemp);
2644            }
2645        }
2646
2647        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
2648        {
2649            modifierValue = "";
2650            String hm = "",
2651                    afm = "";
2652
2653            hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
2654            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
2655            {
2656                hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
2657            }
2658            if (modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AF_COMMON_IDENTIFIER))
2659            {
2660                afm = modifiers.get(Modifiers.AF_COMMON_IDENTIFIER);
2661            }
2662
2663            modifierValue = hm + " " + afm;
2664            modifierValue = modifierValue.trim();
2665
2666            if(modifierValue != null && modifierValue.equals("") == false)
2667            {
2668                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2669                    labelBounds = tiTemp.getTextBounds();
2670                    labelWidth = labelBounds.width();
2671        
2672                    x = bounds.left + bounds.width() + bufferXR;
2673        
2674                    y = (bounds.height());
2675                    y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5));
2676                    y = bounds.top + y;
2677        
2678                    tiTemp.setLocation(x, y);
2679                    tiArray.add(tiTemp);
2680
2681            }
2682        }
2683
2684        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
2685        {
2686            modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
2687
2688            if(modifierValue != null)
2689            {
2690                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2691                    labelBounds = tiTemp.getTextBounds();
2692                    labelWidth = labelBounds.width();
2693        
2694                    if (!byLabelHeight)
2695                    {
2696                        x = bounds.left - labelWidth - bufferXL;
2697                        y = bounds.top + bounds.height();
2698                    }
2699                    else
2700                    {
2701                        x = bounds.left - labelWidth - bufferXL;
2702        
2703                        y = (bounds.height());
2704                        y = (int) ((y * 0.5) + (labelHeight * 0.5));
2705        
2706                        y = y + ((labelHeight + bufferText) - descent);
2707                        y = bounds.top + y;
2708                    }
2709        
2710                    tiTemp.setLocation(x, y);
2711                    tiArray.add(tiTemp);
2712            }
2713        }
2714
2715        if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION) || modifiers.containsKey(Modifiers.AS_COUNTRY))
2716        {
2717            modifierValue = "";
2718
2719            if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.M_HIGHER_FORMATION))
2720            {
2721                modifierValue += modifiers.get(Modifiers.M_HIGHER_FORMATION);
2722            }
2723            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
2724            {
2725                if (modifierValue.length() > 0)
2726                {
2727                    modifierValue += " ";
2728                }
2729                modifierValue += modifiers.get(Modifiers.AS_COUNTRY);
2730            }
2731
2732            if(modifierValue.equals("")==false)
2733            {
2734                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2735                labelBounds = tiTemp.getTextBounds();
2736                labelWidth = labelBounds.width();
2737
2738                x = bounds.left + bounds.width() + bufferXR;
2739                if (!byLabelHeight)
2740                {
2741                    y = bounds.top + bounds.height();
2742                }
2743                else
2744                {
2745                    y = (bounds.height());
2746                    y = (int) ((y * 0.5) + (labelHeight * 0.5));
2747
2748                    y = y + ((labelHeight + bufferText - descent));
2749                    y = bounds.top + y;
2750                }
2751
2752                tiTemp.setLocation(x, y);
2753                tiArray.add(tiTemp);
2754
2755            }
2756        }
2757
2758        if (modifiers.containsKey(Modifiers.Z_SPEED) )
2759        {
2760            modifierValue = modifiers.get(Modifiers.Z_SPEED);
2761
2762            if(modifierValue != null)
2763            {
2764                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2765                    labelBounds = tiTemp.getTextBounds();
2766                    labelWidth = labelBounds.width();
2767        
2768                    x = bounds.left - labelWidth - bufferXL;
2769                    if (!byLabelHeight)
2770                    {
2771                        y = Math.round(bounds.top + bounds.height() + labelHeight + bufferText);
2772                    }
2773                    else
2774                    {
2775                        y = (bounds.height());
2776                        y = (int) ((y * 0.5) + (labelHeight * 0.5));
2777        
2778                        y = y + ((labelHeight + bufferText) * 2) - (descent * 2);
2779                        y = Math.round(bounds.top + y);
2780                    }
2781        
2782                    tiTemp.setLocation(x, y);
2783                    tiArray.add(tiTemp);
2784            }
2785        }
2786
2787        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)
2788                || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
2789                || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)//
2790                || modifiers.containsKey(Modifiers.N_HOSTILE)//
2791                || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))//
2792        {
2793            modifierValue = null;
2794
2795            String jm = null,
2796                    km = null,
2797                    lm = null,
2798                    nm = null,
2799                    pm = null;
2800
2801            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
2802            {
2803                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
2804            }
2805            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.K_COMBAT_EFFECTIVENESS))
2806            {
2807                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
2808            }
2809            if (modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.L_SIGNATURE_EQUIP))
2810            {
2811                lm = modifiers.get(Modifiers.L_SIGNATURE_EQUIP);
2812            }
2813            if (modifiers.containsKey(Modifiers.N_HOSTILE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.N_HOSTILE))
2814            {
2815                nm = modifiers.get(Modifiers.N_HOSTILE);
2816            }
2817            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.P_IFF_SIF_AIS))
2818            {
2819                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
2820            }
2821
2822            modifierValue = "";
2823            if (jm != null && jm.equals("") == false)
2824            {
2825                modifierValue = modifierValue + jm;
2826            }
2827            if (km != null && km.equals("") == false)
2828            {
2829                modifierValue = modifierValue + " " + km;
2830            }
2831            if (lm != null && lm.equals("") == false)
2832            {
2833                modifierValue = modifierValue + " " + lm;
2834            }
2835            if (nm != null && nm.equals("") == false)
2836            {
2837                modifierValue = modifierValue + " " + nm;
2838            }
2839            if (pm != null && pm.equals("") == false)
2840            {
2841                modifierValue = modifierValue + " " + pm;
2842            }
2843
2844            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
2845            {
2846                modifierValue = modifierValue.substring(1);
2847            }
2848
2849            modifierValue = modifierValue.trim();
2850
2851            if(modifierValue.equals("")==false)
2852            {
2853                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2854                labelBounds = tiTemp.getTextBounds();
2855                labelWidth = labelBounds.width();
2856
2857                x = bounds.left + bounds.width() + bufferXR;
2858                if (!byLabelHeight)
2859                {
2860                    y = Math.round(bounds.top + bounds.height() + labelHeight + bufferText);
2861                }
2862                else
2863                {
2864                    y = (bounds.height());
2865                    y = (int) ((y * 0.5) + (labelHeight * 0.5));
2866
2867                    y = y + ((labelHeight + bufferText) * 2) - (descent * 2);
2868                    y = Math.round(bounds.top + y);
2869                }
2870
2871                tiTemp.setLocation(x, y);
2872                tiArray.add(tiTemp);
2873
2874            }
2875
2876        }
2877
2878        if (modifiers.containsKey(Modifiers.W_DTG_1))
2879        {
2880            modifierValue = modifiers.get(Modifiers.W_DTG_1);
2881
2882            if(modifierValue != null)
2883            {
2884                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2885                    labelBounds = tiTemp.getTextBounds();
2886                    labelWidth = labelBounds.width();
2887        
2888                    if (!byLabelHeight)
2889                    {
2890                        x = bounds.left - labelWidth - bufferXL;
2891                        y = bounds.top - bufferY - descent;
2892                    }
2893                    else
2894                    {
2895                        x = bounds.left - labelWidth - bufferXL;
2896        
2897                        y = (bounds.height());
2898                        y = (int) ((y * 0.5) + (labelHeight * 0.5));
2899        
2900                        y = y - ((labelHeight + bufferText) * 2);
2901                        y = bounds.top + y;
2902                    }
2903        
2904                    tiTemp.setLocation(x, y);
2905                    tiArray.add(tiTemp);
2906            }
2907        }
2908
2909        if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) || modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
2910        {
2911            modifierValue = null;
2912            String E = null,
2913                    F = null;
2914
2915            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
2916            {
2917                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
2918                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
2919            }
2920            if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.F_REINFORCED_REDUCED))
2921            {
2922                F = modifiers.get(Modifiers.F_REINFORCED_REDUCED);
2923            }
2924
2925            if (E != null && E.equals("") == false)
2926            {
2927                modifierValue = E;
2928            }
2929
2930            if (F != null && F.equals("") == false)
2931            {
2932                if (F.toUpperCase(Locale.US) == ("R"))
2933                {
2934                    F = "(+)";
2935                }
2936                else if (F.toUpperCase(Locale.US) == ("D"))
2937                {
2938                    F = "(-)";
2939                }
2940                else if (F.toUpperCase(Locale.US) == ("RD"))
2941                {
2942                    F = "(" + (char) (177) + ")";
2943                }
2944            }
2945
2946            if (F != null && F.equals("") == false)
2947            {
2948                if (modifierValue != null && modifierValue.equals("") == false)
2949                {
2950                    modifierValue = modifierValue + " " + F;
2951                }
2952                else
2953                {
2954                    modifierValue = F;
2955                }
2956            }
2957
2958            if(modifierValue != null)
2959            {
2960                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2961                    labelBounds = tiTemp.getTextBounds();
2962                    labelWidth = labelBounds.width();
2963        
2964                    if (!byLabelHeight)
2965                    {
2966                        x = bounds.left + bounds.width() + bufferXR;
2967                        y = bounds.top - bufferY - descent;
2968                    }
2969                    else
2970                    {
2971                        x = bounds.left + bounds.width() + bufferXR;
2972        
2973                        y = (bounds.height());
2974                        y = (int) ((y * 0.5) + (labelHeight * 0.5));
2975        
2976                        y = y - ((labelHeight + bufferText) * 2);
2977                        y = bounds.top + y;
2978                    }
2979        
2980                    tiTemp.setLocation(x, y);
2981                    tiArray.add(tiTemp);
2982
2983            }
2984        }
2985
2986        if (modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AA_SPECIAL_C2_HQ))
2987        {
2988            modifierValue = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ);
2989
2990            if(modifierValue != null)
2991            {
2992                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
2993                    labelBounds = tiTemp.getTextBounds();
2994                    labelWidth = labelBounds.width();
2995        
2996                    x = (int) ((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f));
2997        
2998                    y = (symbolBounds.height());//checkpoint, get box above the point
2999                    y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5));
3000                    y = symbolBounds.top + y;
3001        
3002                    tiTemp.setLocation(x, y);
3003                    tiArray.add(tiTemp);
3004            }
3005        }
3006
3007
3008        // </editor-fold>
3009
3010        //Shift Points and Draw
3011        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
3012
3013        // <editor-fold defaultstate="collapsed" desc="Cleanup">
3014        tiArray = null;
3015        tiTemp = null;
3016        //tempShape = null;
3017        //ctx = null;
3018        //buffer = null;
3019        // </editor-fold>
3020
3021        return newsdi;
3022    }
3023
3024    /**
3025     *
3026     * @param sdi
3027     * @param symbolID
3028     * @param modifiers
3029     * @param attributes
3030     * @return
3031     */
3032    public static SymbolDimensionInfo processLandUnitTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
3033    {
3034        int bufferXL = 7;
3035        int bufferXR = 7;
3036        int bufferY = 2;
3037        int bufferText = 2;
3038        int x = 0;
3039        int y = 0;//best y
3040        SymbolDimensionInfo  newsdi = null;
3041
3042        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
3043
3044        int descent = (int) (_modifierFontDescent + 0.5);
3045
3046        Rect labelBounds = null;
3047        int labelWidth, labelHeight;
3048
3049        Rect bounds = new Rect(sdi.getSymbolBounds());
3050        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
3051        Point centerPoint = new Point(sdi.getCenterPoint());
3052        Rect imageBounds = new Rect(sdi.getImageBounds());
3053
3054        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
3055        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
3056
3057        //check if text is too tall:
3058        boolean byLabelHeight = false;
3059        labelHeight = (int) (_modifierFontHeight + 0.5);/* RendererUtilities.measureTextHeight(RendererSettings.getModifierFontName(),
3060         RendererSettings.getModifierFontSize(),
3061         RendererSettings.getModifierFontStyle()).fullHeight;*/
3062
3063        int maxHeight = (bounds.height());
3064        if ((labelHeight * 3) > maxHeight)
3065        {
3066            byLabelHeight = true;
3067        }
3068
3069        //Affiliation Modifier being drawn as a display modifier
3070        String affiliationModifier = null;
3071        if (RS.getDrawAffiliationModifierAsLabel() == true)
3072        {
3073            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
3074        }
3075        if (affiliationModifier != null)
3076        {   //Set affiliation modifier
3077            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
3078            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
3079        }//*/
3080
3081        //Check for Valid Country Code
3082        int cc = SymbolID.getCountryCode(symbolID);
3083        String scc = "";
3084        if(cc > 0)
3085        {
3086            scc = GENCLookup.getInstance().get3CharCode(cc);
3087        }
3088        if(!scc.isEmpty())
3089            modifiers.put(Modifiers.AS_COUNTRY, scc);
3090
3091        //            int y0 = 0;//W            E/F/AS
3092        //            int y1 = 0;//X/Y          G
3093        //            int y2 =                  H
3094        //            int y3 = 0;//T            M
3095        //            int y4 = 0;//Z            J/K//P
3096        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
3097        String modifierValue = null;
3098        TextInfo tiTemp = null;
3099
3100
3101        //if(Modifiers.X_ALTITUDE_DEPTH in modifiers || Modifiers.Y_LOCATION in modifiers)
3102        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))
3103        {
3104            modifierValue = null;
3105
3106            String xm = null,
3107                    ym = null;
3108
3109            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) )
3110            {
3111                xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);// xm = modifiers.X;
3112            }
3113            if (modifiers.containsKey(Modifiers.Y_LOCATION))
3114            {
3115                ym = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
3116            }
3117            if (xm == null && ym != null)
3118            {
3119                modifierValue = ym;
3120            }
3121            else if (xm != null && ym == null)
3122            {
3123                modifierValue = xm;
3124            }
3125            else if (xm != null && ym != null)
3126            {
3127                modifierValue = xm + "  " + ym;
3128            }
3129
3130            if(modifierValue != null)
3131            {
3132                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3133                labelBounds = tiTemp.getTextBounds();
3134                labelWidth = labelBounds.width();
3135
3136                //on left
3137                x = (int)getLabelXPosition(bounds, labelWidth, false);
3138                //above center
3139                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 1);
3140
3141                tiTemp.setLocation(x, y);
3142                tiArray.add(tiTemp);
3143            }
3144        }
3145
3146        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
3147        {
3148            modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
3149
3150            if(modifierValue != null)
3151            {
3152                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3153                labelBounds = tiTemp.getTextBounds();
3154                labelWidth = labelBounds.width();
3155
3156                //on right
3157                x = (int)getLabelXPosition(bounds, labelWidth, true);
3158                //just above H
3159                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
3160
3161                tiTemp.setLocation(x, y);
3162                tiArray.add(tiTemp);
3163
3164            }
3165        }
3166
3167
3168        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
3169        {
3170            modifierValue = null;
3171
3172            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
3173            {
3174                modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
3175            }
3176
3177            if(modifierValue != null && modifierValue.equals("") == false)
3178            {
3179                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3180                labelBounds = tiTemp.getTextBounds();
3181                labelWidth = labelBounds.width();
3182
3183                //on right
3184                x = (int)getLabelXPosition(bounds, labelWidth, true);
3185                //center
3186                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
3187
3188                tiTemp.setLocation(x, y);
3189                tiArray.add(tiTemp);
3190
3191            }
3192        }
3193
3194        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
3195        {
3196            modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
3197
3198            if(modifierValue != null)
3199            {
3200                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3201                labelBounds = tiTemp.getTextBounds();
3202                labelWidth = labelBounds.width();
3203
3204                //on left
3205                x = (int)getLabelXPosition(bounds, labelWidth, false);
3206                //just below center
3207                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -1);
3208
3209
3210                tiTemp.setLocation(x, y);
3211                tiArray.add(tiTemp);
3212            }
3213        }
3214
3215        if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
3216        {
3217            modifierValue = "";
3218
3219            if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
3220            {
3221                modifierValue += modifiers.get(Modifiers.M_HIGHER_FORMATION);
3222            }
3223
3224            if(modifierValue.equals("")==false)
3225            {
3226                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3227                labelBounds = tiTemp.getTextBounds();
3228                labelWidth = labelBounds.width();
3229
3230                //on right
3231                x = (int)getLabelXPosition(bounds, labelWidth, true);
3232                //below H
3233                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
3234
3235                tiTemp.setLocation(x, y);
3236                tiArray.add(tiTemp);
3237
3238            }
3239        }
3240
3241        if (modifiers.containsKey(Modifiers.Z_SPEED) )
3242        {
3243            modifierValue = modifiers.get(Modifiers.Z_SPEED);
3244
3245            if(modifierValue != null)
3246            {
3247                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3248                labelBounds = tiTemp.getTextBounds();
3249                labelWidth = labelBounds.width();
3250
3251                //on left
3252                x = (int)getLabelXPosition(bounds, labelWidth, false);
3253                //below T
3254                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -2);
3255
3256
3257                tiTemp.setLocation(x, y);
3258                tiArray.add(tiTemp);
3259            }
3260        }
3261
3262        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)
3263                || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
3264                || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))//
3265        {
3266            modifierValue = "";
3267
3268            String jm = null,
3269                    km = null,
3270                    pm = null;
3271
3272            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
3273            {
3274                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
3275            }
3276            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS))
3277            {
3278                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
3279            }
3280            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
3281            {
3282                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
3283            }
3284
3285            if (jm != null && jm.equals("") == false)
3286            {
3287                modifierValue = modifierValue + jm;
3288            }
3289            if (km != null && km.equals("") == false)
3290            {
3291                modifierValue = modifierValue + " " + km;
3292            }
3293            if (pm != null && pm.equals("") == false)
3294            {
3295                modifierValue = modifierValue + " " + pm;
3296            }
3297
3298            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
3299            {
3300                modifierValue = modifierValue.substring(1);
3301            }
3302
3303            modifierValue = modifierValue.trim();
3304
3305            if(modifierValue.equals("")==false)
3306            {
3307                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3308                labelBounds = tiTemp.getTextBounds();
3309                labelWidth = labelBounds.width();
3310
3311                //on right
3312                x = (int)getLabelXPosition(bounds, labelWidth, true);
3313                //below M
3314                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
3315
3316
3317                tiTemp.setLocation(x, y);
3318                tiArray.add(tiTemp);
3319
3320            }
3321
3322        }
3323
3324        if (modifiers.containsKey(Modifiers.W_DTG_1))
3325        {
3326            modifierValue = modifiers.get(Modifiers.W_DTG_1);
3327
3328            if(modifierValue != null)
3329            {
3330                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3331                labelBounds = tiTemp.getTextBounds();
3332                labelWidth = labelBounds.width();
3333
3334                //on left
3335                x = (int)getLabelXPosition(bounds, labelWidth, false);
3336                //above X/Y
3337                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
3338
3339
3340                tiTemp.setLocation(x, y);
3341                tiArray.add(tiTemp);
3342            }
3343        }
3344
3345        if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) ||
3346                modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
3347                modifiers.containsKey(Modifiers.AS_COUNTRY))
3348        {
3349            modifierValue = null;
3350            String E = null,
3351                    F = null,
3352                    AS = null;
3353
3354            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
3355            {
3356                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
3357                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
3358            }
3359            if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED))
3360            {
3361                F = modifiers.get(Modifiers.F_REINFORCED_REDUCED);
3362            }
3363            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
3364            {
3365                AS = modifiers.get(Modifiers.AS_COUNTRY);
3366            }
3367
3368            if (E != null && E.equals("") == false)
3369            {
3370                modifierValue = E;
3371            }
3372
3373            if (F != null && F.equals("") == false)
3374            {
3375                if (F.toUpperCase(Locale.US).equals("R"))
3376                {
3377                    F = "(+)";
3378                }
3379                else if (F.toUpperCase(Locale.US).equals("D"))
3380                {
3381                    F = "(-)";
3382                }
3383                else if (F.toUpperCase(Locale.US).equals("RD"))
3384                {
3385                    F = "(" + (char) (177) + ")";
3386                }
3387            }
3388
3389            if (F != null && F.equals("") == false)
3390            {
3391                if (modifierValue != null && modifierValue.equals("") == false)
3392                {
3393                    modifierValue = modifierValue + " " + F;
3394                }
3395                else
3396                {
3397                    modifierValue = F;
3398                }
3399            }
3400
3401            if (AS != null && AS.equals("") == false)
3402            {
3403                if (modifierValue != null && modifierValue.equals("") == false)
3404                {
3405                    modifierValue = modifierValue + " " + AS;
3406                }
3407                else
3408                {
3409                    modifierValue = AS;
3410                }
3411            }
3412
3413            if(modifierValue != null)
3414            {
3415                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3416                labelBounds = tiTemp.getTextBounds();
3417                labelWidth = labelBounds.width();
3418
3419                //on right
3420                x = (int)getLabelXPosition(bounds, labelWidth, true);
3421                //above G
3422                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
3423
3424
3425                tiTemp.setLocation(x, y);
3426                tiArray.add(tiTemp);
3427
3428            }
3429        }
3430
3431        if (modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ)  &&
3432            SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AA_SPECIAL_C2_HQ))
3433        {
3434            modifierValue = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ);
3435
3436            if(modifierValue != null)
3437            {
3438                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3439                labelBounds = tiTemp.getTextBounds();
3440                labelWidth = labelBounds.width();
3441
3442                x = (int) ((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f));
3443
3444                y = (symbolBounds.height());//checkpoint, get box above the point
3445                y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5));
3446                y = symbolBounds.top + y;
3447
3448                tiTemp.setLocation(x, y);
3449                tiArray.add(tiTemp);
3450            }
3451        }
3452
3453
3454        // </editor-fold>
3455
3456        //Shift Points and Draw
3457        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
3458
3459        // <editor-fold defaultstate="collapsed" desc="Cleanup">
3460        tiArray = null;
3461        tiTemp = null;
3462        //tempShape = null;
3463        //ctx = null;
3464        //buffer = null;
3465        // </editor-fold>
3466
3467        return newsdi;
3468    }
3469
3470    public static SymbolDimensionInfo processLandUnitTextModifiersE(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
3471    {
3472        int bufferXL = 7;
3473        int bufferXR = 7;
3474        int bufferY = 2;
3475        int bufferText = 2;
3476        int x = 0;
3477        int y = 0;//best y
3478        SymbolDimensionInfo newsdi = null;
3479
3480        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
3481
3482        int descent = (int) (_modifierFontDescent + 0.5);
3483
3484        Rect labelBounds = null;
3485        int labelWidth, labelHeight;
3486
3487        Rect bounds = new Rect(sdi.getSymbolBounds());
3488        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
3489        Point centerPoint = new Point(sdi.getCenterPoint());
3490        Rect imageBounds = new Rect(sdi.getImageBounds());
3491
3492
3493        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
3494        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
3495
3496        //check if text is too tall:
3497        boolean byLabelHeight = false;
3498        labelHeight = (int) (_modifierFontHeight + 0.5);/* RendererUtilities.measureTextHeight(RendererSettings.getModifierFontName(),
3499         RendererSettings.getModifierFontSize(),
3500         RendererSettings.getModifierFontStyle()).fullHeight;*/
3501
3502        int maxHeight = (bounds.height());
3503        if ((labelHeight * 3) > maxHeight)
3504        {
3505            byLabelHeight = true;
3506        }
3507
3508        //Affiliation Modifier being drawn as a display modifier
3509        String affiliationModifier = null;
3510        if (RS.getDrawAffiliationModifierAsLabel() == true)
3511        {
3512            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
3513        }
3514        if (affiliationModifier != null)
3515        {   //Set affiliation modifier
3516            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
3517            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
3518        }//*/
3519
3520        //Check for Valid Country Code
3521        int cc = SymbolID.getCountryCode(symbolID);
3522        String scc = "";
3523        if(cc > 0)
3524        {
3525            scc = GENCLookup.getInstance().get3CharCode(cc);
3526        }
3527        if(!scc.isEmpty())
3528            modifiers.put(Modifiers.AS_COUNTRY, scc);
3529
3530        //            int y0 = 0;//W            E/F/AS
3531        //            int y1 = 0;//X/Y          G/AQ
3532        //            int y2 =   //V/AD/AE      H/AF
3533        //            int y3 = 0;//T            M
3534        //            int y4 = 0;//Z            J/K/L/P
3535        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
3536        String modifierValue = null;
3537        TextInfo tiTemp = null;
3538
3539
3540        //if(Modifiers.X_ALTITUDE_DEPTH in modifiers || Modifiers.Y_LOCATION in modifiers)
3541        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))
3542        {
3543            modifierValue = null;
3544
3545            String xm = null,
3546                    ym = null;
3547
3548            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) )
3549            {
3550                xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);// xm = modifiers.X;
3551            }
3552            if (modifiers.containsKey(Modifiers.Y_LOCATION))
3553            {
3554                ym = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
3555            }
3556            if (xm == null && ym != null)
3557            {
3558                modifierValue = ym;
3559            }
3560            else if (xm != null && ym == null)
3561            {
3562                modifierValue = xm;
3563            }
3564            else if (xm != null && ym != null)
3565            {
3566                modifierValue = xm + "  " + ym;
3567            }
3568
3569            if(modifierValue != null)
3570            {
3571                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3572                labelBounds = tiTemp.getTextBounds();
3573                labelWidth = labelBounds.width();
3574
3575                //on left
3576                x = (int)getLabelXPosition(bounds, labelWidth, false);
3577                //above center V
3578                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
3579
3580                tiTemp.setLocation(x, y);
3581                tiArray.add(tiTemp);
3582            }
3583        }
3584
3585        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) ||
3586                modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
3587        {
3588            modifierValue = null;
3589
3590            String gm = null,
3591                    aqm = null;
3592
3593            if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) && SymbolUtilities.hasModifier(symbolID, Modifiers.G_STAFF_COMMENTS))
3594            {
3595                gm = modifiers.get(Modifiers.G_STAFF_COMMENTS);// xm = modifiers.X;
3596            }
3597            if (modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
3598            {
3599                aqm = modifiers.get(Modifiers.AQ_GUARDED_UNIT);// ym = modifiers.Y;
3600            }
3601            if (gm == null && aqm != null)
3602            {
3603                modifierValue = aqm;
3604            }
3605            else if (gm != null && aqm == null)
3606            {
3607                modifierValue = gm;
3608            }
3609            else if (gm != null && aqm != null)
3610            {
3611                modifierValue = gm + "  " + aqm;
3612            }
3613
3614            if(modifierValue != null)
3615            {
3616                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3617                labelBounds = tiTemp.getTextBounds();
3618                labelWidth = labelBounds.width();
3619
3620                //on right
3621                x = (int)getLabelXPosition(bounds, labelWidth, true);
3622                //above center H
3623                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
3624
3625                tiTemp.setLocation(x, y);
3626                tiArray.add(tiTemp);
3627
3628            }
3629        }
3630
3631
3632        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) ||
3633                modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
3634        {
3635            modifierValue = null;
3636            String hm = null;
3637            String afm = null;
3638
3639            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
3640            {
3641                hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
3642            }
3643            if (modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
3644            {
3645                afm = modifiers.get(Modifiers.AF_COMMON_IDENTIFIER);
3646            }
3647            if (hm == null && afm != null)
3648            {
3649                modifierValue = afm;
3650            }
3651            else if (hm != null && afm == null)
3652            {
3653                modifierValue = hm;
3654            }
3655            else if (hm != null && afm != null)
3656            {
3657                modifierValue = hm + "  " + afm;
3658            }
3659
3660            if(modifierValue != null && modifierValue.equals("") == false)
3661            {
3662                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3663                labelBounds = tiTemp.getTextBounds();
3664                labelWidth = labelBounds.width();
3665
3666                //on right
3667                x = (int)getLabelXPosition(bounds, labelWidth, true);
3668                //center
3669                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
3670
3671                tiTemp.setLocation(x, y);
3672                tiArray.add(tiTemp);
3673
3674            }
3675        }
3676
3677        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) || modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) || modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
3678        {
3679            modifierValue = "";
3680
3681            String vm = null,
3682                    adm = null,
3683                    aem = null;
3684
3685            if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
3686            {
3687                vm = modifiers.get(Modifiers.V_EQUIP_TYPE);
3688            }
3689            if (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE))
3690            {
3691                adm = modifiers.get(Modifiers.AD_PLATFORM_TYPE);
3692            }
3693            if (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
3694            {
3695                aem = modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME);
3696            }
3697            if (vm != null && vm.equals("") == false)
3698            {
3699                modifierValue = modifierValue + vm;
3700            }
3701            if (adm != null && adm.equals("") == false)
3702            {
3703                modifierValue = modifierValue + " " + adm;
3704            }
3705            if (aem != null && aem.equals("") == false)
3706            {
3707                modifierValue = modifierValue + " " + aem;
3708            }
3709
3710            modifierValue = modifierValue.trim();
3711
3712            if(modifierValue != null && modifierValue.equals("") == false)
3713            {
3714                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3715                labelBounds = tiTemp.getTextBounds();
3716                labelWidth = (int)labelBounds.width();
3717
3718                //on left
3719                x = (int)getLabelXPosition(bounds, labelWidth, false);
3720                //above center V
3721                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
3722
3723                tiTemp.setLocation(x, y);
3724                tiArray.add(tiTemp);
3725
3726            }
3727        }
3728
3729        if (modifiers.containsKey(Modifiers.C_QUANTITY) ||
3730                modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) )
3731        {
3732            modifierValue = null;
3733
3734            String cm = "",
3735                    tm = "";
3736
3737            if (modifiers.containsKey(Modifiers.C_QUANTITY) && SymbolUtilities.hasModifier(symbolID, Modifiers.C_QUANTITY))
3738            {
3739                cm = modifiers.get(Modifiers.C_QUANTITY);// xm = modifiers.X;
3740            }
3741            if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
3742            {
3743                tm = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);// ym = modifiers.Y;
3744            }
3745            modifierValue = cm + "  " + tm;
3746            modifierValue = modifierValue.trim();
3747
3748            if(modifierValue != null)
3749            {
3750                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3751                labelBounds = tiTemp.getTextBounds();
3752                labelWidth = labelBounds.width();
3753
3754                //on left
3755                x = (int)getLabelXPosition(bounds, labelWidth, false);
3756                //below center V
3757                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
3758
3759
3760                tiTemp.setLocation(x, y);
3761                tiArray.add(tiTemp);
3762            }
3763        }
3764
3765        if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
3766        {
3767            modifierValue = "";
3768
3769            if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
3770            {
3771                modifierValue += modifiers.get(Modifiers.M_HIGHER_FORMATION);
3772            }
3773
3774            if(modifierValue.equals("")==false)
3775            {
3776                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3777                labelBounds = tiTemp.getTextBounds();
3778                labelWidth = labelBounds.width();
3779
3780                //on right
3781                x = (int)getLabelXPosition(bounds, labelWidth, true);
3782                //below center H
3783                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
3784
3785                tiTemp.setLocation(x, y);
3786                tiArray.add(tiTemp);
3787
3788            }
3789        }
3790
3791        if (modifiers.containsKey(Modifiers.Z_SPEED) )
3792        {
3793            modifierValue = modifiers.get(Modifiers.Z_SPEED);
3794
3795            if(modifierValue != null)
3796            {
3797                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3798                labelBounds = tiTemp.getTextBounds();
3799                labelWidth = labelBounds.width();
3800
3801                //on left
3802                x = (int)getLabelXPosition(bounds, labelWidth, false);
3803                //below T
3804                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
3805
3806
3807                tiTemp.setLocation(x, y);
3808                tiArray.add(tiTemp);
3809            }
3810        }
3811
3812        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)
3813                || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
3814                || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)//
3815                || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))//
3816        {
3817            modifierValue = "";
3818
3819            String jm = null,
3820                    km = null,
3821                    lm = null,
3822                    pm = null;
3823
3824            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
3825            {
3826                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
3827            }
3828            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS))
3829            {
3830                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
3831            }
3832            if (modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP))
3833            {
3834                lm = modifiers.get(Modifiers.L_SIGNATURE_EQUIP);
3835            }
3836            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
3837            {
3838                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
3839            }
3840
3841            if (jm != null && jm.equals("") == false)
3842            {
3843                modifierValue = modifierValue + jm;
3844            }
3845            if (km != null && km.equals("") == false)
3846            {
3847                modifierValue = modifierValue + " " + km;
3848            }
3849            if (lm != null && lm.equals("") == false)
3850            {
3851                modifierValue = modifierValue + " " + lm;
3852            }
3853            if (pm != null && pm.equals("") == false)
3854            {
3855                modifierValue = modifierValue + " " + pm;
3856            }
3857
3858            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
3859            {
3860                modifierValue = modifierValue.substring(1);
3861            }
3862
3863            modifierValue = modifierValue.trim();
3864
3865            if(modifierValue.equals("")==false)
3866            {
3867                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3868                labelBounds = tiTemp.getTextBounds();
3869                labelWidth = labelBounds.width();
3870
3871                //on right
3872                x = (int)getLabelXPosition(bounds, labelWidth, true);
3873                //below M
3874                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
3875
3876
3877                tiTemp.setLocation(x, y);
3878                tiArray.add(tiTemp);
3879
3880            }
3881
3882        }
3883
3884        if (modifiers.containsKey(Modifiers.W_DTG_1))
3885        {
3886            modifierValue = modifiers.get(Modifiers.W_DTG_1);
3887
3888            if(modifierValue != null)
3889            {
3890                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3891                labelBounds = tiTemp.getTextBounds();
3892                labelWidth = labelBounds.width();
3893
3894                //on left
3895                x = (int)getLabelXPosition(bounds, labelWidth, false);
3896                //above X/Y
3897                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
3898
3899
3900                tiTemp.setLocation(x, y);
3901                tiArray.add(tiTemp);
3902            }
3903        }
3904
3905        if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) ||
3906                modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
3907                modifiers.containsKey(Modifiers.AS_COUNTRY))
3908        {
3909            modifierValue = null;
3910            String E = null,
3911                    F = null,
3912                    AS = null;
3913
3914            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
3915            {
3916                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
3917                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
3918            }
3919            if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED))
3920            {
3921                F = modifiers.get(Modifiers.F_REINFORCED_REDUCED);
3922            }
3923            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
3924            {
3925                AS = modifiers.get(Modifiers.AS_COUNTRY);
3926            }
3927
3928            if (E != null && E.equals("") == false)
3929            {
3930                modifierValue = E;
3931            }
3932
3933            if (F != null && F.equals("") == false)
3934            {
3935                if (F.toUpperCase(Locale.US) == ("R"))
3936                {
3937                    F = "(+)";
3938                }
3939                else if (F.toUpperCase(Locale.US) == ("D"))
3940                {
3941                    F = "(-)";
3942                }
3943                else if (F.toUpperCase(Locale.US) == ("RD"))
3944                {
3945                    F = "(" + (char) (177) + ")";
3946                }
3947            }
3948
3949            if (F != null && F.equals("") == false)
3950            {
3951                if (modifierValue != null && modifierValue.equals("") == false)
3952                {
3953                    modifierValue = modifierValue + " " + F;
3954                }
3955                else
3956                {
3957                    modifierValue = F;
3958                }
3959            }
3960
3961            if (AS != null && AS.equals("") == false)
3962            {
3963                if (modifierValue != null && modifierValue.equals("") == false)
3964                {
3965                    modifierValue = modifierValue + " " + AS;
3966                }
3967                else
3968                {
3969                    modifierValue = AS;
3970                }
3971            }
3972
3973            if(modifierValue != null)
3974            {
3975                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3976                labelBounds = tiTemp.getTextBounds();
3977                labelWidth = labelBounds.width();
3978
3979                //on right
3980                x = (int)getLabelXPosition(bounds, labelWidth, true);
3981                //above G
3982                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
3983
3984
3985                tiTemp.setLocation(x, y);
3986                tiArray.add(tiTemp);
3987
3988            }
3989        }
3990
3991        if (modifiers.containsKey(Modifiers.AA_SPECIAL_C2_HQ)  &&
3992                SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.AA_SPECIAL_C2_HQ))
3993        {
3994            modifierValue = modifiers.get(Modifiers.AA_SPECIAL_C2_HQ);
3995
3996            if(modifierValue != null)
3997            {
3998                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
3999                labelBounds = tiTemp.getTextBounds();
4000                labelWidth = labelBounds.width();
4001
4002                x = (int) ((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f));
4003
4004                y = (symbolBounds.height());//checkpoint, get box above the point
4005                y = (int) ((y * 0.5) + ((labelHeight - descent) * 0.5));
4006                y = symbolBounds.top + y;
4007
4008                tiTemp.setLocation(x, y);
4009                tiArray.add(tiTemp);
4010            }
4011        }
4012
4013
4014
4015        // </editor-fold>
4016
4017        //Shift Points and Draw
4018        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
4019
4020        // <editor-fold defaultstate="collapsed" desc="Cleanup">
4021        tiArray = null;
4022        tiTemp = null;
4023        //tempShape = null;
4024        //ctx = null;
4025        //buffer = null;
4026        // </editor-fold>
4027
4028        return newsdi;
4029    }
4030
4031    public static SymbolDimensionInfo  processAirSpaceUnitTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
4032    {
4033        int bufferXL = 7;
4034        int bufferXR = 7;
4035        int bufferY = 2;
4036        int bufferText = 0;
4037        int x = 0;
4038        int y = 0;//best y
4039        SymbolDimensionInfo newsdi = null;
4040
4041        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
4042
4043        int descent = (int) (_modifierFontDescent + 0.5);
4044
4045        Rect labelBounds = null;
4046        int labelWidth, labelHeight;
4047
4048        Rect bounds = new Rect(sdi.getSymbolBounds());
4049        Rect imageBounds = new Rect(sdi.getImageBounds());
4050
4051
4052        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
4053        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
4054
4055        labelHeight = (int) (_modifierFontHeight + 0.5);
4056
4057        //Affiliation Modifier being drawn as a display modifier
4058        String affiliationModifier = null;
4059        if (RS.getDrawAffiliationModifierAsLabel() == true)
4060        {
4061            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
4062        }
4063        if (affiliationModifier != null)
4064        {   //Set affiliation modifier
4065            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
4066            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
4067        }//*/
4068
4069        //Check for Valid Country Code
4070        int cc = SymbolID.getCountryCode(symbolID);
4071        String scc = "";
4072        if(cc > 0)
4073        {
4074            scc = GENCLookup.getInstance().get3CharCode(cc);
4075        }
4076        if(!scc.isEmpty())
4077            modifiers.put(Modifiers.AS_COUNTRY, scc);
4078
4079        //            int y0 = 0;//             T
4080        //            int y1 = 0;//             P
4081        //            int y2 =                  V
4082        //            int y3 = 0;//             Z/X
4083        //            int y4 = 0;//             G/H
4084        //
4085
4086        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
4087        String modifierValue = null;
4088        TextInfo tiTemp = null;
4089
4090        if(SymbolUtilities.isAir(symbolID))
4091        {
4092            if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
4093            {
4094
4095                String gm = "";
4096                String hm = "";
4097                if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
4098                    gm = modifiers.get(Modifiers.G_STAFF_COMMENTS);
4099
4100                if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
4101                    hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
4102
4103                modifierValue = gm + " " + hm;
4104                modifierValue = modifierValue.trim();
4105
4106                if(modifierValue != null && !modifierValue.equals(""))
4107                {
4108                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4109                    labelBounds = tiTemp.getTextBounds();
4110                    labelWidth = labelBounds.width();
4111
4112                    //on right
4113                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4114                    //below Z/X
4115                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
4116
4117                    tiTemp.setLocation(x, y);
4118                    tiArray.add(tiTemp);
4119
4120                }
4121            }
4122
4123            if (modifiers.containsKey(Modifiers.Z_SPEED) || modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
4124            {
4125                modifierValue = "";
4126                String zm = "";
4127                String xm = "";
4128                if(modifiers.containsKey(Modifiers.Z_SPEED))
4129                    zm = modifiers.get(Modifiers.Z_SPEED);
4130
4131                if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
4132                    xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
4133
4134                modifierValue = zm + " " + xm;
4135                modifierValue = modifierValue.trim();
4136
4137                if(modifierValue != null && modifierValue.equals("")==false)
4138                {
4139                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4140                    labelBounds = tiTemp.getTextBounds();
4141                    labelWidth = labelBounds.width();
4142
4143                    //on right
4144                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4145                    //below V
4146                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
4147
4148                    tiTemp.setLocation(x, y);
4149                    tiArray.add(tiTemp);
4150
4151                }
4152            }
4153
4154
4155
4156            if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
4157            {
4158                modifierValue = modifiers.get(Modifiers.V_EQUIP_TYPE);
4159
4160                if(modifierValue != null && modifierValue.equals("") == false)
4161                {
4162                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4163                    labelBounds = tiTemp.getTextBounds();
4164                    labelWidth = labelBounds.width();
4165
4166                    //on right
4167                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4168                    //center
4169                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
4170
4171                    tiTemp.setLocation(x, y);
4172                    tiArray.add(tiTemp);
4173
4174                }
4175            }
4176
4177            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
4178            {
4179                modifierValue = modifiers.get(Modifiers.P_IFF_SIF_AIS);
4180
4181                if(modifierValue != null && modifierValue.equals("") == false)
4182                {
4183                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4184                    labelBounds = tiTemp.getTextBounds();
4185                    labelWidth = labelBounds.width();
4186
4187                    //on right
4188                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4189                    //above V
4190                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
4191
4192                    tiTemp.setLocation(x, y);
4193                    tiArray.add(tiTemp);
4194
4195                }
4196            }
4197
4198            if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
4199            {
4200                modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
4201
4202                if(modifierValue != null && modifierValue.equals("") == false)
4203                {
4204                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4205                    labelBounds = tiTemp.getTextBounds();
4206                    labelWidth = labelBounds.width();
4207
4208                    //on right
4209                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4210                    //above P
4211                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
4212
4213                    tiTemp.setLocation(x, y);
4214                    tiArray.add(tiTemp);
4215
4216                }
4217            }
4218
4219            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
4220                    modifiers.containsKey(Modifiers.AS_COUNTRY))
4221            {
4222                modifierValue = null;
4223                String em = "";
4224                String asm = "";
4225
4226                if(modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
4227                    em = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
4228                if(modifiers.containsKey(Modifiers.AS_COUNTRY))
4229                    asm = modifiers.get(Modifiers.AS_COUNTRY);
4230
4231                modifierValue = em + " " + asm;
4232                modifierValue = modifierValue.trim();
4233
4234                if (modifierValue.equals("") == false)
4235                {
4236                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4237                    labelBounds = tiTemp.getTextBounds();
4238                    labelWidth = labelBounds.width();
4239
4240                    //on right
4241                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4242                    //above T
4243                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 3);
4244
4245                    tiTemp.setLocation(x, y);
4246                    tiArray.add(tiTemp);
4247
4248                }
4249            }
4250        }
4251        else //space
4252        {
4253            if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
4254            {
4255
4256                String gm = "";
4257                String hm = "";
4258                if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
4259                    gm = modifiers.get(Modifiers.G_STAFF_COMMENTS);
4260
4261                if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
4262                    hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
4263
4264                modifierValue = gm + " " + hm;
4265                modifierValue = modifierValue.trim();
4266
4267                if(modifierValue != null && !modifierValue.equals(""))
4268                {
4269                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4270                    labelBounds = tiTemp.getTextBounds();
4271                    labelWidth = labelBounds.width();
4272
4273                    //on right
4274                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4275                    //below Z/X
4276                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -2);
4277
4278                    tiTemp.setLocation(x, y);
4279                    tiArray.add(tiTemp);
4280
4281                }
4282            }
4283
4284            if (modifiers.containsKey(Modifiers.Z_SPEED) || modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
4285            {
4286                modifierValue = "";
4287                String zm = "";
4288                String xm = "";
4289                if(modifiers.containsKey(Modifiers.Z_SPEED))
4290                    zm = modifiers.get(Modifiers.Z_SPEED);
4291
4292                if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
4293                    xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
4294
4295                modifierValue = zm + " " + xm;
4296                modifierValue = modifierValue.trim();
4297
4298                if(modifierValue != null && modifierValue.equals("")==false)
4299                {
4300                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4301                    labelBounds = tiTemp.getTextBounds();
4302                    labelWidth = labelBounds.width();
4303
4304                    //on right
4305                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4306                    //below center
4307                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -1);
4308
4309                    tiTemp.setLocation(x, y);
4310                    tiArray.add(tiTemp);
4311
4312                }
4313            }
4314
4315            if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
4316            {
4317                modifierValue = modifiers.get(Modifiers.V_EQUIP_TYPE);
4318
4319                if(modifierValue != null && modifierValue.equals("") == false)
4320                {
4321                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4322                    labelBounds = tiTemp.getTextBounds();
4323                    labelWidth = labelBounds.width();
4324
4325                    //right
4326                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4327                    //above vertical center
4328                    y = (int)getLabelYPosition(bounds, labelHeight, descent, 0, false, 1);
4329
4330                    tiTemp.setLocation(x, y);
4331                    tiArray.add(tiTemp);
4332
4333                }
4334            }
4335
4336            if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
4337            {
4338                modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
4339
4340                if(modifierValue != null && modifierValue.equals("") == false)
4341                {
4342                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4343                    labelBounds = tiTemp.getTextBounds();
4344                    labelWidth = labelBounds.width();
4345
4346                    //on right
4347                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4348                    //above V
4349                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
4350
4351                    tiTemp.setLocation(x, y);
4352                    tiArray.add(tiTemp);
4353
4354                }
4355            }
4356
4357            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
4358                    modifiers.containsKey(Modifiers.AS_COUNTRY))
4359            {
4360                modifierValue = null;
4361                String em = "";
4362                String asm = "";
4363
4364                if(modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
4365                    em = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
4366                if(modifiers.containsKey(Modifiers.AS_COUNTRY))
4367                    asm = modifiers.get(Modifiers.AS_COUNTRY);
4368
4369                modifierValue = em + " " + asm;
4370                modifierValue = modifierValue.trim();
4371
4372                if (modifierValue.equals("") == false)
4373                {
4374                    tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4375                    labelBounds = tiTemp.getTextBounds();
4376                    labelWidth = labelBounds.width();
4377
4378                    //on right
4379                    x = (int)getLabelXPosition(bounds, labelWidth, true);
4380                    //above T
4381                    y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 3);
4382
4383                    tiTemp.setLocation(x, y);
4384                    tiArray.add(tiTemp);
4385
4386                }
4387            }
4388        }
4389
4390
4391
4392        // </editor-fold>
4393
4394        //Shift Points and Draw
4395        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
4396
4397        // <editor-fold defaultstate="collapsed" desc="Cleanup">
4398        tiArray = null;
4399        tiTemp = null;
4400        //tempShape = null;
4401        //ctx = null;
4402        //buffer = null;
4403        // </editor-fold>
4404
4405        return newsdi;
4406    }
4407
4408    public static SymbolDimensionInfo  processAirSpaceUnitTextModifiersE(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
4409    {
4410        int bufferXL = 7;
4411        int bufferXR = 7;
4412        int bufferY = 2;
4413        int bufferText = 2;
4414        int x = 0;
4415        int y = 0;//best y
4416        SymbolDimensionInfo newsdi = null;
4417
4418        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
4419
4420        int descent = (int) (_modifierFontDescent + 0.5);
4421
4422        Rect labelBounds = null;
4423        int labelWidth, labelHeight;
4424
4425        Rect bounds = new Rect(sdi.getSymbolBounds());
4426        Rect imageBounds = new Rect(sdi.getImageBounds());
4427
4428
4429        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
4430        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
4431
4432        labelHeight = (int) (_modifierFontHeight + 0.5);
4433
4434        //Affiliation Modifier being drawn as a display modifier
4435        String affiliationModifier = null;
4436        if (RS.getDrawAffiliationModifierAsLabel() == true)
4437        {
4438            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
4439        }
4440        if (affiliationModifier != null)
4441        {   //Set affiliation modifier
4442            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
4443            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
4444        }//*/
4445
4446        //Check for Valid Country Code
4447        int cc = SymbolID.getCountryCode(symbolID);
4448        String scc = "";
4449        if(cc > 0)
4450        {
4451            scc = GENCLookup.getInstance().get3CharCode(cc);
4452        }
4453        if(!scc.isEmpty())
4454            modifiers.put(Modifiers.AS_COUNTRY, scc);
4455
4456        //                              AO
4457        //                              B/C
4458        //            int y0 = 0;//W            AS
4459        //            int y1 = 0;//AR           T/Y
4460        //            int y2 =     AD           V/AF
4461        //            int y3 = 0;//             P/X/Z
4462        //            int y4 = 0;//             G/H/J
4463        //
4464
4465        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
4466        String modifierValue = null;
4467        TextInfo tiTemp = null;
4468
4469        //if(Modifiers.C_QUANTITY in modifiers
4470        int ad = SymbolID.getAmplifierDescriptor(symbolID);
4471        if (modifiers.containsKey(Modifiers.C_QUANTITY) && !(ad > 0 && ad < 30))//if C and no echelon
4472        {
4473            String text = modifiers.get(Modifiers.C_QUANTITY);
4474            if(text != null)
4475            {
4476                //bounds = armyc2.c5isr.renderer.utilities.RendererUtilities.getTextOutlineBounds(_modifierFont, text, new SO.Point(0,0));
4477                tiTemp = new TextInfo(text, 0, 0, _modifierFont);
4478                labelBounds = tiTemp.getTextBounds();
4479                labelWidth = labelBounds.width();
4480                x = Math.round((bounds.left + (bounds.width() * 0.5f)) - (labelWidth * 0.5f));
4481                y = Math.round(bounds.top - bufferY - descent);
4482                tiTemp.setLocation(x, y);
4483                tiArray.add(tiTemp);
4484            }
4485        }
4486
4487        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) ||
4488                modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) ||
4489                modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
4490        {
4491
4492            String gm = "";
4493            String hm = "";
4494            String jm = "";
4495            if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
4496                gm = modifiers.get(Modifiers.G_STAFF_COMMENTS);
4497
4498            if(modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
4499                hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
4500
4501            if(modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
4502                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
4503
4504            modifierValue = gm + " " + hm;
4505            modifierValue = modifierValue.trim();
4506            modifierValue += " " + jm;
4507            modifierValue = modifierValue.trim();
4508
4509            if(modifierValue != null && modifierValue.equals("")==false)
4510            {
4511                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4512                labelBounds = tiTemp.getTextBounds();
4513                labelWidth = labelBounds.width();
4514
4515                //on right
4516                x = (int)getLabelXPosition(bounds, labelWidth, true);
4517                //below P
4518                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
4519
4520                tiTemp.setLocation(x, y);
4521                tiArray.add(tiTemp);
4522
4523            }
4524        }
4525
4526        if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) ||
4527                modifiers.containsKey(Modifiers.Z_SPEED) ||
4528                modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
4529        {
4530            modifierValue = null;
4531            String pm = "";
4532            String zm = "";
4533            String xm = "";
4534
4535            if(modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
4536                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
4537
4538            if(modifiers.containsKey(Modifiers.Z_SPEED))
4539                zm = modifiers.get(Modifiers.Z_SPEED);
4540
4541            if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
4542                xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
4543
4544            modifierValue = pm + " " + xm;
4545            modifierValue = modifierValue.trim();
4546            modifierValue += " " + zm;
4547            modifierValue = modifierValue.trim();
4548
4549            if(modifierValue != null && modifierValue.equals("")==false)
4550            {
4551                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4552                labelBounds = tiTemp.getTextBounds();
4553                labelWidth = labelBounds.width();
4554
4555                //on right
4556                x = (int)getLabelXPosition(bounds, labelWidth, true);
4557                //below V
4558                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
4559
4560                tiTemp.setLocation(x, y);
4561                tiArray.add(tiTemp);
4562
4563            }
4564        }
4565
4566
4567
4568        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) ||
4569                modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
4570        {
4571            modifierValue = null;
4572            String vm = "";
4573            String afm = "";
4574
4575            if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
4576                vm = modifiers.get(Modifiers.V_EQUIP_TYPE);
4577
4578            if(modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER) && SymbolID.getSymbolSet(symbolID)==SymbolID.SymbolSet_Air)
4579                afm = modifiers.get(Modifiers.AF_COMMON_IDENTIFIER);
4580
4581            modifierValue = vm + " " + afm;
4582            modifierValue = modifierValue.trim();
4583
4584            if(modifierValue != null && modifierValue.equals("") == false)
4585            {
4586                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4587                labelBounds = tiTemp.getTextBounds();
4588                labelWidth = labelBounds.width();
4589
4590                //on right
4591                x = (int)getLabelXPosition(bounds, labelWidth, true);
4592                //center
4593                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
4594
4595                tiTemp.setLocation(x, y);
4596                tiArray.add(tiTemp);
4597
4598            }
4599        }
4600
4601
4602        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) ||
4603                modifiers.containsKey(Modifiers.Y_LOCATION))
4604        {
4605            String tm = "";
4606            String ym = "";
4607
4608            if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
4609                tm = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
4610
4611            if(modifiers.containsKey(Modifiers.Y_LOCATION))
4612                ym = modifiers.get(Modifiers.Y_LOCATION);
4613
4614
4615            modifierValue = tm + " " + ym;
4616            modifierValue = modifierValue.trim();
4617
4618            if(modifierValue != null && modifierValue.equals("") == false)
4619            {
4620                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4621                labelBounds = tiTemp.getTextBounds();
4622                labelWidth = labelBounds.width();
4623
4624                //on right
4625                x = (int)getLabelXPosition(bounds, labelWidth, true);
4626                //above V
4627                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
4628
4629                tiTemp.setLocation(x, y);
4630                tiArray.add(tiTemp);
4631
4632            }
4633        }
4634
4635        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
4636                modifiers.containsKey(Modifiers.AS_COUNTRY))
4637        {
4638            modifierValue = null;
4639            String em = "";
4640            String asm = "";
4641
4642            if(modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
4643                em = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
4644            if(modifiers.containsKey(Modifiers.AS_COUNTRY))
4645                asm = modifiers.get(Modifiers.AS_COUNTRY);
4646
4647            modifierValue = em + " " + asm;
4648            modifierValue = modifierValue.trim();
4649
4650            if (modifierValue.equals("") == false) {
4651                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4652                labelBounds = tiTemp.getTextBounds();
4653                labelWidth = labelBounds.width();
4654
4655                //on right
4656                x = (int)getLabelXPosition(bounds, labelWidth, true);
4657                //above T
4658                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
4659
4660                tiTemp.setLocation(x, y);
4661                tiArray.add(tiTemp);
4662
4663            }
4664        }
4665
4666        if (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE)) {
4667            modifierValue = modifiers.get(Modifiers.AD_PLATFORM_TYPE);
4668
4669            if (modifierValue != null && modifierValue.equals("") == false) {
4670                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4671                labelBounds = tiTemp.getTextBounds();
4672                labelWidth = (int) labelBounds.width();
4673
4674                //left
4675                x = (int)getLabelXPosition(bounds, labelWidth, false);
4676                //center
4677                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
4678
4679
4680                tiTemp.setLocation(x, y);
4681                tiArray.add(tiTemp);
4682
4683            }
4684        }
4685
4686        if (modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR)) {
4687            modifierValue = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR);
4688
4689            if (modifierValue != null && modifierValue.equals("") == false) {
4690                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4691                labelBounds = tiTemp.getTextBounds();
4692                labelWidth = (int) labelBounds.width();
4693
4694                //left
4695                x = (int)getLabelXPosition(bounds, labelWidth, false);
4696                //just above AD
4697                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
4698
4699
4700                tiTemp.setLocation(x, y);
4701                tiArray.add(tiTemp);
4702
4703            }
4704        }
4705
4706        if (modifiers.containsKey(Modifiers.W_DTG_1)) {
4707            modifierValue = modifiers.get(Modifiers.W_DTG_1);
4708
4709            if (modifierValue != null && modifierValue.equals("") == false) {
4710                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4711                labelBounds = tiTemp.getTextBounds();
4712                labelWidth = (int) labelBounds.width();
4713
4714                //left
4715                x = (int)getLabelXPosition(bounds, labelWidth, false);
4716                //above AR
4717                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
4718
4719                tiTemp.setLocation(x, y);
4720                tiArray.add(tiTemp);
4721
4722            }
4723        }
4724
4725        // </editor-fold>
4726
4727        //Shift Points and Draw
4728        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
4729
4730        // <editor-fold defaultstate="collapsed" desc="Cleanup">
4731        tiArray = null;
4732        tiTemp = null;
4733        //tempShape = null;
4734        //ctx = null;
4735        //buffer = null;
4736        // </editor-fold>
4737
4738        return newsdi;
4739    }
4740    public static SymbolDimensionInfo  processLandEquipmentTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
4741    {
4742        int bufferXL = 7;
4743        int bufferXR = 7;
4744        int bufferY = 2;
4745        int bufferText = 2;
4746        int x = 0;
4747        int y = 0;//best y
4748        SymbolDimensionInfo newsdi = null;
4749
4750        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
4751
4752        int descent = (int) (_modifierFontDescent + 0.5);
4753
4754        Rect labelBounds = null;
4755        int labelWidth, labelHeight;
4756
4757        Rect bounds = new Rect(sdi.getSymbolBounds());
4758        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
4759        Point centerPoint = new Point(sdi.getCenterPoint());
4760        Rect imageBounds = new Rect(sdi.getImageBounds());
4761
4762
4763        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
4764        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
4765
4766        labelHeight = (int) (_modifierFontHeight + 0.5);
4767
4768        //Affiliation Modifier being drawn as a display modifier
4769        String affiliationModifier = null;
4770        if (RS.getDrawAffiliationModifierAsLabel() == true)
4771        {
4772            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
4773        }
4774        if (affiliationModifier != null)
4775        {   //Set affiliation modifier
4776            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
4777            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
4778        }//*/
4779
4780        //Check for Valid Country Code
4781        int cc = SymbolID.getCountryCode(symbolID);
4782        String scc = "";
4783        if(cc > 0)
4784        {
4785            scc = GENCLookup.getInstance().get3CharCode(cc);
4786        }
4787        if(!scc.isEmpty())
4788            modifiers.put(Modifiers.AS_COUNTRY, scc);
4789        //                                 C
4790        //            int y0 = 0;//W/AR
4791        //            int y1 = 0;//X/Y          G/AQ
4792        //            int y2 = 0;//V/AD/AE      H/AF
4793        //            int y3 = 0;//T            J/N/L/P
4794        //            int y4 = 0;//Z
4795        //
4796        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
4797        String modifierValue = null;
4798        TextInfo tiTemp = null;
4799        //if(Modifiers.C_QUANTITY in modifiers
4800        if (modifiers.containsKey(Modifiers.C_QUANTITY))
4801        {
4802            String text = modifiers.get(Modifiers.C_QUANTITY);
4803            if(text != null)
4804            {
4805                //bounds = armyc2.c5isr.renderer.utilities.RendererUtilities.getTextOutlineBounds(_modifierFont, text, new SO.Point(0,0));
4806                tiTemp = new TextInfo(text, 0, 0, _modifierFont);
4807                labelBounds = tiTemp.getTextBounds();
4808                labelWidth = labelBounds.width();
4809                x = Math.round((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f));
4810                y = Math.round(symbolBounds.top - bufferY - descent);
4811                tiTemp.setLocation(x, y);
4812                tiArray.add(tiTemp);
4813            }
4814        }
4815
4816        //if(Modifiers.X_ALTITUDE_DEPTH in modifiers || Modifiers.Y_LOCATION in modifiers)
4817        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))
4818        {
4819            modifierValue = null;
4820
4821            String xm = null,
4822                    ym = null;
4823
4824            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
4825            {
4826                xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);// xm = modifiers.X;
4827            }
4828            if (modifiers.containsKey(Modifiers.Y_LOCATION))
4829            {
4830                ym = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
4831            }
4832            if (xm == null && ym != null)
4833            {
4834                modifierValue = ym;
4835            }
4836            else if (xm != null && ym == null)
4837            {
4838                modifierValue = xm;
4839            }
4840            else if (xm != null && ym != null)
4841            {
4842                modifierValue = xm + "  " + ym;
4843            }
4844
4845            if(modifierValue != null)
4846            {
4847                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4848                labelBounds = tiTemp.getTextBounds();
4849                labelWidth = labelBounds.width();
4850
4851                //on left
4852                x = (int)getLabelXPosition(bounds, labelWidth, false);
4853                //just above center  V/AD/AE
4854                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
4855
4856                tiTemp.setLocation(x, y);
4857                tiArray.add(tiTemp);
4858            }
4859        }
4860
4861        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
4862        {
4863            modifierValue = "";
4864            String mg = "";
4865            String maq = "";
4866
4867            if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
4868                mg = modifiers.get(Modifiers.G_STAFF_COMMENTS);
4869            if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
4870                maq = modifiers.get(Modifiers.AQ_GUARDED_UNIT);
4871
4872            modifierValue = mg + " " + maq;
4873
4874            modifierValue = modifierValue.trim();
4875
4876            if(modifierValue != null)
4877            {
4878                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4879                labelBounds = tiTemp.getTextBounds();
4880                labelWidth = labelBounds.width();
4881
4882                //on right
4883                x = (int)getLabelXPosition(bounds, labelWidth, true);
4884                //above center H
4885                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
4886
4887                tiTemp.setLocation(x, y);
4888                tiArray.add(tiTemp);
4889
4890            }
4891        }
4892
4893
4894        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
4895        {
4896            modifierValue = "";
4897            String hm = "",
4898                    afm = "";
4899
4900            hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
4901            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
4902            {
4903                hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
4904            }
4905            if (modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
4906            {
4907                afm = modifiers.get(Modifiers.AF_COMMON_IDENTIFIER);
4908            }
4909
4910            modifierValue = hm + " " + afm;
4911            modifierValue = modifierValue.trim();
4912
4913            if(modifierValue != null && modifierValue.equals("") == false)
4914            {
4915                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4916                labelBounds = tiTemp.getTextBounds();
4917                labelWidth = labelBounds.width();
4918
4919                //on right
4920                x = (int)getLabelXPosition(bounds, labelWidth, true);
4921                //center
4922                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
4923
4924                tiTemp.setLocation(x, y);
4925                tiArray.add(tiTemp);
4926
4927            }
4928        }
4929
4930        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
4931        {
4932            modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
4933
4934            if(modifierValue != null)
4935            {
4936                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4937                labelBounds = tiTemp.getTextBounds();
4938                labelWidth = labelBounds.width();
4939
4940                //on left
4941                x = (int)getLabelXPosition(bounds, labelWidth, false);
4942                //below V
4943                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
4944
4945
4946                tiTemp.setLocation(x, y);
4947                tiArray.add(tiTemp);
4948            }
4949        }
4950
4951
4952
4953        if (modifiers.containsKey(Modifiers.Z_SPEED) )
4954        {
4955            modifierValue = modifiers.get(Modifiers.Z_SPEED);
4956
4957            if(modifierValue != null)
4958            {
4959                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
4960                labelBounds = tiTemp.getTextBounds();
4961                labelWidth = labelBounds.width();
4962
4963                //on left
4964                x = (int)getLabelXPosition(bounds, labelWidth, false);
4965                //below T
4966                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
4967
4968
4969                tiTemp.setLocation(x, y);
4970                tiArray.add(tiTemp);
4971            }
4972        }
4973
4974        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)
4975                || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)//
4976                || modifiers.containsKey(Modifiers.N_HOSTILE)//
4977                || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))//
4978        {
4979            modifierValue = null;
4980
4981            String jm = null,
4982                    lm = null,
4983                    nm = null,
4984                    pm = null;
4985
4986            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
4987            {
4988                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
4989            }
4990            if (modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.L_SIGNATURE_EQUIP))
4991            {
4992                lm = modifiers.get(Modifiers.L_SIGNATURE_EQUIP);
4993            }
4994            if (modifiers.containsKey(Modifiers.N_HOSTILE) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.N_HOSTILE))
4995            {
4996                nm = modifiers.get(Modifiers.N_HOSTILE);
4997            }
4998            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.P_IFF_SIF_AIS))
4999            {
5000                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
5001            }
5002
5003            modifierValue = "";
5004            if (jm != null && jm.equals("") == false)
5005            {
5006                modifierValue = modifierValue + jm;
5007            }
5008            if (lm != null && lm.equals("") == false)
5009            {
5010                modifierValue = modifierValue + " " + lm;
5011            }
5012            if (nm != null && nm.equals("") == false)
5013            {
5014                modifierValue = modifierValue + " " + nm;
5015            }
5016            if (pm != null && pm.equals("") == false)
5017            {
5018                modifierValue = modifierValue + " " + pm;
5019            }
5020
5021            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
5022            {
5023                modifierValue = modifierValue.substring(1);
5024            }
5025
5026            modifierValue = modifierValue.trim();
5027
5028            if(modifierValue.equals("")==false)
5029            {
5030                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5031                labelBounds = tiTemp.getTextBounds();
5032                labelWidth = labelBounds.width();
5033
5034                //on right
5035                x = (int)getLabelXPosition(bounds, labelWidth, true);
5036                //below center H
5037                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
5038
5039
5040                tiTemp.setLocation(x, y);
5041                tiArray.add(tiTemp);
5042
5043            }
5044
5045        }
5046
5047        if (modifiers.containsKey(Modifiers.W_DTG_1) ||
5048                modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR))
5049        {
5050            modifierValue = "";
5051            String mw = "";
5052            String mar = "";
5053            if(modifiers.containsKey(Modifiers.W_DTG_1))
5054                mw = modifiers.get(Modifiers.W_DTG_1);
5055
5056            if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR))
5057                mar = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR);
5058
5059            modifierValue = mw + " " + mar;
5060
5061            modifierValue = modifierValue.trim();
5062
5063            if(modifierValue != null)
5064            {
5065                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5066                labelBounds = tiTemp.getTextBounds();
5067                labelWidth = labelBounds.width();
5068
5069                //on left
5070                x = (int)getLabelXPosition(bounds, labelWidth, false);
5071                //above X/Y
5072                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
5073
5074
5075                tiTemp.setLocation(x, y);
5076                tiArray.add(tiTemp);
5077            }
5078        }
5079
5080        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
5081                modifiers.containsKey(Modifiers.AS_COUNTRY))
5082        {
5083            modifierValue = null;
5084            String E = null,
5085                    AS = null;
5086
5087            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
5088            {
5089                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
5090                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
5091            }
5092            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
5093            {
5094                AS = modifiers.get(Modifiers.AS_COUNTRY);
5095            }
5096
5097            if (E != null && E.equals("") == false)
5098            {
5099                modifierValue = E;
5100            }
5101
5102            if (AS != null && AS.equals("") == false)
5103            {
5104                if (modifierValue != null && modifierValue.equals("") == false)
5105                {
5106                    modifierValue = modifierValue + " " + AS;
5107                }
5108                else
5109                {
5110                    modifierValue = AS;
5111                }
5112            }
5113
5114            if(modifierValue != null && !modifierValue.isEmpty())
5115            {
5116                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5117                labelBounds = tiTemp.getTextBounds();
5118                labelWidth = labelBounds.width();
5119
5120                //on right
5121                x = (int)getLabelXPosition(bounds, labelWidth, true);
5122                //above G/AQ
5123                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
5124
5125
5126                tiTemp.setLocation(x, y);
5127                tiArray.add(tiTemp);
5128
5129            }
5130        }
5131
5132        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) ||
5133                modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) ||
5134                modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
5135        {
5136            String mv = null,
5137                    mad = null,
5138                    mae = null;
5139
5140            if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
5141            {
5142                mv = modifiers.get(Modifiers.V_EQUIP_TYPE);
5143            }
5144            if (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE))
5145            {
5146                mad = modifiers.get(Modifiers.AD_PLATFORM_TYPE);
5147            }
5148            if (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
5149            {
5150                mae = modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME);
5151            }
5152
5153            modifierValue = "";
5154            if (mv != null && mv.equals("") == false)
5155            {
5156                modifierValue = modifierValue + mv;
5157            }
5158            if (mad != null && mad.equals("") == false)
5159            {
5160                modifierValue = modifierValue + " " + mad;
5161            }
5162            if (mae != null && mae.equals("") == false)
5163            {
5164                modifierValue = modifierValue + " " + mae;
5165            }
5166
5167            modifierValue = modifierValue.trim();
5168
5169            if(modifierValue != null)
5170            {
5171                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5172                labelBounds = tiTemp.getTextBounds();
5173                labelWidth = labelBounds.width();
5174
5175                //on left
5176                x = (int)getLabelXPosition(bounds, labelWidth, false);
5177                //center
5178                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
5179
5180                tiTemp.setLocation(x, y);
5181                tiArray.add(tiTemp);
5182            }
5183        }
5184
5185
5186        // </editor-fold>
5187
5188        //Shift Points and Draw
5189        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
5190
5191        // <editor-fold defaultstate="collapsed" desc="Cleanup">
5192        tiArray = null;
5193        tiTemp = null;
5194        //tempShape = null;
5195        //ctx = null;
5196        //buffer = null;
5197        // </editor-fold>
5198
5199        return newsdi;
5200    }
5201
5202    public static SymbolDimensionInfo  processLandEquipmentTextModifiersE(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
5203    {
5204        int bufferXL = 7;
5205        int bufferXR = 7;
5206        int bufferY = 2;
5207        int bufferText = 2;
5208        int x = 0;
5209        int y = 0;//best y
5210        SymbolDimensionInfo newsdi = null;
5211
5212        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
5213
5214        int descent = (int) (_modifierFontDescent + 0.5);
5215
5216        Rect labelBounds = null;
5217        int labelWidth, labelHeight;
5218
5219        Rect bounds = new Rect(sdi.getSymbolBounds());
5220        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
5221        Point centerPoint = new Point(sdi.getCenterPoint());
5222        Rect imageBounds = new Rect(sdi.getImageBounds());
5223
5224        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
5225        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
5226
5227        labelHeight = (int) (_modifierFontHeight + 0.5);
5228
5229        //Affiliation Modifier being drawn as a display modifier
5230        String affiliationModifier = null;
5231        if (RS.getDrawAffiliationModifierAsLabel() == true)
5232        {
5233            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
5234        }
5235        if (affiliationModifier != null)
5236        {   //Set affiliation modifier
5237            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
5238            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
5239        }//*/
5240
5241        //Check for Valid Country Code
5242        int cc = SymbolID.getCountryCode(symbolID);
5243        String scc = "";
5244        if(cc > 0)
5245        {
5246            scc = GENCLookup.getInstance().get3CharCode(cc);
5247        }
5248        if(!scc.isEmpty())
5249            modifiers.put(Modifiers.AS_COUNTRY, scc);
5250        //                                 C
5251        //            int y0 = 0;//W            AS
5252        //            int y1 = 0;//X/Y          G/AQ
5253        //            int y2 = 0;//V/AD/AE
5254        //            int y3 = 0;//T            H/AF
5255        //            int y4 = 0;//Z            J/N/L/P
5256        //
5257        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
5258        String modifierValue = null;
5259        TextInfo tiTemp = null;
5260        //if(Modifiers.C_QUANTITY in modifiers
5261        /*if (modifiers.containsKey(Modifiers.C_QUANTITY))
5262        {
5263            String text = modifiers.get(Modifiers.C_QUANTITY);
5264            if(text != null)
5265            {
5266                //bounds = armyc2.c5isr.renderer.utilities.RendererUtilities.getTextOutlineBounds(_modifierFont, text, new SO.Point(0,0));
5267                tiTemp = new TextInfo(text, 0, 0, _modifierFont);
5268                labelBounds = tiTemp.getTextBounds();
5269                labelWidth = labelBounds.width();
5270                x = Math.round((symbolBounds.left + (symbolBounds.width() * 0.5f)) - (labelWidth * 0.5f));
5271                y = Math.round(symbolBounds.top - bufferY - descent);
5272                tiTemp.setLocation(x, y);
5273                tiArray.add(tiTemp);
5274            }
5275        }//*/
5276
5277        //if(Modifiers.X_ALTITUDE_DEPTH in modifiers || Modifiers.Y_LOCATION in modifiers)
5278        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))
5279        {
5280            modifierValue = null;
5281
5282            String xm = null,
5283                    ym = null;
5284
5285            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
5286            {
5287                xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);// xm = modifiers.X;
5288            }
5289            if (modifiers.containsKey(Modifiers.Y_LOCATION))
5290            {
5291                ym = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
5292            }
5293            if (xm == null && ym != null)
5294            {
5295                modifierValue = ym;
5296            }
5297            else if (xm != null && ym == null)
5298            {
5299                modifierValue = xm;
5300            }
5301            else if (xm != null && ym != null)
5302            {
5303                modifierValue = xm + "  " + ym;
5304            }
5305
5306            if(modifierValue != null)
5307            {
5308                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5309                labelBounds = tiTemp.getTextBounds();
5310                labelWidth = labelBounds.width();
5311
5312                //on left
5313                x = (int)getLabelXPosition(bounds, labelWidth, false);
5314                //just above V/AD/AE
5315                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
5316
5317                tiTemp.setLocation(x, y);
5318                tiArray.add(tiTemp);
5319            }
5320        }
5321
5322        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
5323        {
5324            modifierValue = "";
5325            String mg = "";
5326            String maq = "";
5327
5328            if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
5329                mg = modifiers.get(Modifiers.G_STAFF_COMMENTS);
5330            if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
5331                maq = modifiers.get(Modifiers.AQ_GUARDED_UNIT);
5332
5333            modifierValue = mg + " " + maq;
5334
5335            modifierValue = modifierValue.trim();
5336
5337            if(modifierValue != null)
5338            {
5339                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5340                labelBounds = tiTemp.getTextBounds();
5341                labelWidth = labelBounds.width();
5342
5343                //on right
5344                x = (int)getLabelXPosition(bounds, labelWidth, true);
5345                //just above center
5346                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 1);
5347
5348
5349                tiTemp.setLocation(x, y);
5350                tiArray.add(tiTemp);
5351
5352            }
5353        }
5354
5355
5356        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1) || modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
5357        {
5358            modifierValue = "";
5359            String hm = "",
5360                    afm = "";
5361
5362            hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
5363            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
5364            {
5365                hm = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
5366            }
5367            if (modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
5368            {
5369                afm = modifiers.get(Modifiers.AF_COMMON_IDENTIFIER);
5370            }
5371
5372            modifierValue = hm + " " + afm;
5373            modifierValue = modifierValue.trim();
5374
5375            if(modifierValue != null && modifierValue.equals("") == false)
5376            {
5377                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5378                labelBounds = tiTemp.getTextBounds();
5379                labelWidth = labelBounds.width();
5380
5381                //on right
5382                x = (int)getLabelXPosition(bounds, labelWidth, true);
5383                //H, below G/AQ
5384                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -1);
5385
5386                tiTemp.setLocation(x, y);
5387                tiArray.add(tiTemp);
5388
5389            }
5390        }
5391
5392        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) ||
5393                modifiers.containsKey(Modifiers.C_QUANTITY))
5394        {
5395            modifierValue = null;
5396
5397            String cm = null,
5398                    tm = null;
5399
5400            if (modifiers.containsKey(Modifiers.C_QUANTITY))
5401            {
5402                cm = modifiers.get(Modifiers.C_QUANTITY);// xm = modifiers.X;
5403            }
5404            if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
5405            {
5406                tm = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);// ym = modifiers.Y;
5407            }
5408
5409            modifierValue = cm + " " + tm;
5410            modifierValue = modifierValue.trim();
5411
5412            if(modifierValue != null)
5413            {
5414                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5415                labelBounds = tiTemp.getTextBounds();
5416                labelWidth = labelBounds.width();
5417
5418                //on left
5419                x = (int)getLabelXPosition(bounds, labelWidth, false);
5420                //just below V/AD/AE
5421                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
5422
5423
5424                tiTemp.setLocation(x, y);
5425                tiArray.add(tiTemp);
5426            }
5427        }
5428
5429        if (modifiers.containsKey(Modifiers.Z_SPEED) )
5430        {
5431            modifierValue = modifiers.get(Modifiers.Z_SPEED);
5432
5433            if(modifierValue != null)
5434            {
5435                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5436                labelBounds = tiTemp.getTextBounds();
5437                labelWidth = labelBounds.width();
5438
5439                //on left
5440                x = (int)getLabelXPosition(bounds, labelWidth, false);
5441                //below T
5442                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
5443
5444
5445                tiTemp.setLocation(x, y);
5446                tiArray.add(tiTemp);
5447            }
5448        }
5449
5450        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)
5451                || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
5452                || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP)//
5453                || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))//
5454        {
5455            modifierValue = "";
5456
5457            String jm = null,
5458                    km = null,
5459                    lm = null,
5460                    pm = null;
5461
5462            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
5463            {
5464                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
5465            }
5466            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS))
5467            {
5468                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
5469            }
5470            if (modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP))
5471            {
5472                lm = modifiers.get(Modifiers.L_SIGNATURE_EQUIP);
5473            }
5474            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
5475            {
5476                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
5477            }
5478
5479            if (jm != null && jm.equals("") == false)
5480            {
5481                modifierValue = modifierValue + jm;
5482            }
5483            if (km != null && km.equals("") == false)
5484            {
5485                modifierValue = modifierValue + " " + km;
5486            }
5487            if (lm != null && lm.equals("") == false)
5488            {
5489                modifierValue = modifierValue + " " + lm;
5490            }
5491            if (pm != null && pm.equals("") == false)
5492            {
5493                modifierValue = modifierValue + " " + pm;
5494            }
5495
5496            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
5497            {
5498                modifierValue = modifierValue.substring(1);
5499            }
5500
5501            modifierValue = modifierValue.trim();
5502
5503            if(modifierValue.equals("")==false)
5504            {
5505                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5506                labelBounds = tiTemp.getTextBounds();
5507                labelWidth = labelBounds.width();
5508
5509                //on right
5510                x = (int)getLabelXPosition(bounds, labelWidth, true);
5511                //below H/AF
5512                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -2);
5513
5514
5515                tiTemp.setLocation(x, y);
5516                tiArray.add(tiTemp);
5517
5518            }
5519
5520        }
5521
5522        if (modifiers.containsKey(Modifiers.W_DTG_1))
5523        {
5524            modifierValue = modifiers.get(Modifiers.W_DTG_1);
5525
5526            if(modifierValue != null)
5527            {
5528                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5529                labelBounds = tiTemp.getTextBounds();
5530                labelWidth = labelBounds.width();
5531
5532                //on left
5533                x = (int)getLabelXPosition(bounds, labelWidth, false);
5534                //above X/Y
5535                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
5536
5537
5538                tiTemp.setLocation(x, y);
5539                tiArray.add(tiTemp);
5540            }
5541        }
5542
5543        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) ||
5544                modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE) ||
5545                modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
5546        {
5547            String mv = null,
5548                    mad = null,
5549                    mae = null;
5550
5551            if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
5552            {
5553                mv = modifiers.get(Modifiers.V_EQUIP_TYPE);
5554            }
5555            if (modifiers.containsKey(Modifiers.AD_PLATFORM_TYPE))
5556            {
5557                mad = modifiers.get(Modifiers.AD_PLATFORM_TYPE);
5558            }
5559            if (modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
5560            {
5561                mae = modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME);
5562            }
5563
5564            modifierValue = "";
5565            if (mv != null && mv.equals("") == false)
5566            {
5567                modifierValue = modifierValue + mv;
5568            }
5569            if (mad != null && mad.equals("") == false)
5570            {
5571                modifierValue = modifierValue + " " + mad;
5572            }
5573            if (mae != null && mae.equals("") == false)
5574            {
5575                modifierValue = modifierValue + " " + mae;
5576            }
5577
5578            modifierValue = modifierValue.trim();
5579
5580            if(modifierValue != null)
5581            {
5582                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5583                labelBounds = tiTemp.getTextBounds();
5584                labelWidth = labelBounds.width();
5585
5586                //on left
5587                x = (int)getLabelXPosition(bounds, labelWidth, false);
5588                //center
5589                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
5590
5591                tiTemp.setLocation(x, y);
5592                tiArray.add(tiTemp);
5593            }
5594        }
5595
5596        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
5597                modifiers.containsKey(Modifiers.AS_COUNTRY))
5598        {
5599            modifierValue = null;
5600            String E = null,
5601                    AS = null;
5602
5603            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
5604            {
5605                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
5606                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
5607            }
5608            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
5609            {
5610                AS = modifiers.get(Modifiers.AS_COUNTRY);
5611            }
5612
5613            if (E != null && E.equals("") == false)
5614            {
5615                modifierValue = E;
5616            }
5617
5618            if (AS != null && AS.equals("") == false)
5619            {
5620                if (modifierValue != null && modifierValue.equals("") == false)
5621                {
5622                    modifierValue = modifierValue + " " + AS;
5623                }
5624                else
5625                {
5626                    modifierValue = AS;
5627                }
5628            }
5629
5630            if(modifierValue != null && !modifierValue.isEmpty())
5631            {
5632                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5633                labelBounds = tiTemp.getTextBounds();
5634                labelWidth = labelBounds.width();
5635
5636                //on right
5637                x = (int)getLabelXPosition(bounds, labelWidth, true);
5638                //above G/AQ
5639                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
5640
5641                tiTemp.setLocation(x, y);
5642                tiArray.add(tiTemp);
5643
5644            }
5645        }
5646
5647        // </editor-fold>
5648
5649        //Shift Points and Draw
5650        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
5651
5652        // <editor-fold defaultstate="collapsed" desc="Cleanup">
5653        tiArray = null;
5654        tiTemp = null;
5655        //tempShape = null;
5656        //ctx = null;
5657        //buffer = null;
5658        // </editor-fold>
5659
5660        return newsdi;
5661    }
5662
5663    public static SymbolDimensionInfo  processLandInstallationTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
5664    {
5665        int bufferXL = 7;
5666        int bufferXR = 7;
5667        int bufferY = 2;
5668        int bufferText = 2;
5669        int x = 0;
5670        int y = 0;//best y
5671        SymbolDimensionInfo newsdi = null;
5672
5673        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
5674
5675        int descent = (int) (_modifierFontDescent + 0.5);
5676
5677        Rect labelBounds = null;
5678        int labelWidth, labelHeight;
5679
5680        Rect bounds = new Rect(sdi.getSymbolBounds());
5681        Rect imageBounds = new Rect(sdi.getImageBounds());
5682
5683        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
5684        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
5685
5686        labelHeight = (int) (_modifierFontHeight + 0.5);
5687
5688        //Affiliation Modifier being drawn as a display modifier
5689        String affiliationModifier = null;
5690        if (RS.getDrawAffiliationModifierAsLabel() == true)
5691        {
5692            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
5693        }
5694        if (affiliationModifier != null)
5695        {   //Set affiliation modifier
5696            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
5697            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
5698        }//*/
5699
5700        //Check for Valid Country Code
5701        int cc = SymbolID.getCountryCode(symbolID);
5702        String scc = "";
5703        if(cc > 0)
5704        {
5705            scc = GENCLookup.getInstance().get3CharCode(cc);
5706        }
5707        if(!scc.isEmpty())
5708            modifiers.put(Modifiers.AS_COUNTRY, scc);
5709        //
5710        //            int y0 = 0;//
5711        //            int y1 = 0;//W            G
5712        //            int y2 = 0;//X/Y          H
5713        //            int y3 = 0;//T            J/K/P
5714        //            int y4 = 0;//
5715        //
5716        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
5717        String modifierValue = null;
5718        TextInfo tiTemp = null;
5719
5720        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
5721        {
5722            modifierValue = "";
5723
5724
5725            if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
5726                modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
5727
5728            if(modifierValue != null)
5729            {
5730                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5731                labelBounds = tiTemp.getTextBounds();
5732                labelWidth = labelBounds.width();
5733
5734                //on right
5735                x = (int)getLabelXPosition(bounds, labelWidth, true);
5736                //above center H
5737                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
5738
5739                tiTemp.setLocation(x, y);
5740                tiArray.add(tiTemp);
5741
5742            }
5743        }
5744
5745
5746        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
5747        {
5748            modifierValue = "";
5749
5750            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
5751            {
5752                modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
5753            }
5754
5755
5756            if(modifierValue != null && modifierValue.equals("") == false)
5757            {
5758                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5759                labelBounds = tiTemp.getTextBounds();
5760                labelWidth = labelBounds.width();
5761
5762                //on right
5763                x = (int)getLabelXPosition(bounds, labelWidth, true);
5764                //center
5765                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
5766
5767                tiTemp.setLocation(x, y);
5768                tiArray.add(tiTemp);
5769
5770            }
5771        }
5772
5773        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
5774        {
5775            modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
5776
5777            if(modifierValue != null)
5778            {
5779                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5780                labelBounds = tiTemp.getTextBounds();
5781                labelWidth = labelBounds.width();
5782
5783                //on left
5784                x = (int)getLabelXPosition(bounds, labelWidth, false);
5785                //below center X/Y
5786                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
5787
5788
5789                tiTemp.setLocation(x, y);
5790                tiArray.add(tiTemp);
5791            }
5792        }
5793
5794
5795        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)
5796                || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
5797                || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))//
5798        {
5799            modifierValue = null;
5800
5801            String jm = null,
5802                    km = null,
5803                    pm = null;
5804
5805            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
5806            {
5807                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
5808            }
5809            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.K_COMBAT_EFFECTIVENESS))
5810            {
5811                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
5812            }
5813            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.P_IFF_SIF_AIS))
5814            {
5815                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
5816            }
5817
5818            modifierValue = "";
5819            if (jm != null && jm.equals("") == false)
5820            {
5821                modifierValue = modifierValue + jm;
5822            }
5823            if (km != null && km.equals("") == false)
5824            {
5825                modifierValue = modifierValue + " " + km;
5826            }
5827            if (pm != null && pm.equals("") == false)
5828            {
5829                modifierValue = modifierValue + " " + pm;
5830            }
5831
5832            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
5833            {
5834                modifierValue = modifierValue.substring(1);
5835            }
5836
5837            modifierValue = modifierValue.trim();
5838
5839            if(modifierValue.equals("")==false)
5840            {
5841                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5842                labelBounds = tiTemp.getTextBounds();
5843                labelWidth = labelBounds.width();
5844
5845                //on right
5846                x = (int)getLabelXPosition(bounds, labelWidth, true);
5847                //below center H
5848                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
5849
5850
5851                tiTemp.setLocation(x, y);
5852                tiArray.add(tiTemp);
5853
5854            }
5855
5856        }
5857
5858        if (modifiers.containsKey(Modifiers.W_DTG_1) )
5859        {
5860            modifierValue = "";
5861            String mw = "";
5862            String mar = "";
5863            if(modifiers.containsKey(Modifiers.W_DTG_1))
5864                modifierValue = modifiers.get(Modifiers.W_DTG_1);
5865
5866            if(modifierValue != null)
5867            {
5868                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5869                labelBounds = tiTemp.getTextBounds();
5870                labelWidth = labelBounds.width();
5871
5872                //on left
5873                x = (int)getLabelXPosition(bounds, labelWidth, false);
5874                //above center X/Y
5875                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
5876
5877
5878                tiTemp.setLocation(x, y);
5879                tiArray.add(tiTemp);
5880            }
5881        }
5882
5883        if (modifiers.containsKey(Modifiers.AS_COUNTRY)  ||
5884                modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
5885        {
5886            modifierValue = "";
5887            String E = null,
5888                    AS = null;
5889
5890            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) )
5891            {
5892                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
5893                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
5894            }
5895            if (modifiers.containsKey(Modifiers.AS_COUNTRY) )
5896            {
5897                AS = modifiers.get(Modifiers.AS_COUNTRY);
5898            }
5899
5900            if (E != null && E.equals("") == false)
5901            {
5902                modifierValue += E;
5903            }
5904
5905            if (AS != null && AS.equals("") == false)
5906            {
5907                modifierValue = modifierValue + " " + AS;
5908            }
5909
5910            modifierValue = modifierValue.trim();
5911
5912            if(modifierValue.equals("")==false)
5913            {
5914                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5915                labelBounds = tiTemp.getTextBounds();
5916                labelWidth = labelBounds.width();
5917
5918                //on right
5919                x = (int)getLabelXPosition(bounds, labelWidth, true);
5920                //above G
5921                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
5922
5923
5924                tiTemp.setLocation(x, y);
5925                tiArray.add(tiTemp);
5926
5927            }
5928        }
5929
5930        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) ||
5931                modifiers.containsKey(Modifiers.Y_LOCATION) )
5932        {
5933            String mx = null,
5934                    my = null;
5935
5936            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
5937            {
5938                mx = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
5939            }
5940            if (modifiers.containsKey(Modifiers.Y_LOCATION))
5941            {
5942                my = modifiers.get(Modifiers.Y_LOCATION);
5943            }
5944
5945
5946            modifierValue = "";
5947            if (mx != null && mx.equals("") == false)
5948            {
5949                modifierValue = modifierValue + mx;
5950            }
5951            if (my != null && my.equals("") == false)
5952            {
5953                modifierValue = modifierValue + " " + my;
5954            }
5955
5956            modifierValue = modifierValue.trim();
5957
5958            if(modifierValue != null)
5959            {
5960                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
5961                labelBounds = tiTemp.getTextBounds();
5962                labelWidth = labelBounds.width();
5963
5964                //on left
5965                x = (int)getLabelXPosition(bounds, labelWidth, false);
5966                //center
5967                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
5968
5969                tiTemp.setLocation(x, y);
5970                tiArray.add(tiTemp);
5971            }
5972        }
5973
5974
5975
5976        // </editor-fold>
5977
5978        //Shift Points and Draw
5979        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
5980
5981        // <editor-fold defaultstate="collapsed" desc="Cleanup">
5982        tiArray = null;
5983        tiTemp = null;
5984        //tempShape = null;
5985        //ctx = null;
5986        //buffer = null;
5987        // </editor-fold>
5988
5989        return newsdi;
5990    }
5991
5992    public static SymbolDimensionInfo  processLandInstallationTextModifiersE(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
5993    {
5994        int bufferXL = 7;
5995        int bufferXR = 7;
5996        int bufferY = 2;
5997        int bufferText = 2;
5998        int x = 0;
5999        int y = 0;//best y
6000        SymbolDimensionInfo newsdi = null;
6001
6002        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
6003
6004        int descent = (int) (_modifierFontDescent + 0.5);
6005
6006
6007        Rect labelBounds = null;
6008        int labelWidth, labelHeight;
6009
6010        Rect bounds = new Rect(sdi.getSymbolBounds());
6011        Rect imageBounds = new Rect(sdi.getImageBounds());
6012
6013        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
6014        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
6015
6016        labelHeight = (int) (_modifierFontHeight + 0.5);
6017
6018        //Affiliation Modifier being drawn as a display modifier
6019        String affiliationModifier = null;
6020        if (RS.getDrawAffiliationModifierAsLabel() == true)
6021        {
6022            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
6023        }
6024        if (affiliationModifier != null)
6025        {   //Set affiliation modifier
6026            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
6027            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
6028        }//*/
6029
6030        //Check for Valid Country Code
6031        int cc = SymbolID.getCountryCode(symbolID);
6032        String scc = "";
6033        if(cc > 0)
6034        {
6035            scc = GENCLookup.getInstance().get3CharCode(cc);
6036        }
6037        if(!scc.isEmpty())
6038            modifiers.put(Modifiers.AS_COUNTRY, scc);
6039        //
6040        //            int y0 = 0;// W            AS
6041        //            int y1 = 0;//X/Y           G/AQ
6042        //            int y2 = 0;//              H
6043        //            int y3 = 0;//C/AE            M
6044        //            int y4 = 0;//T             J/K/P
6045        //
6046        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
6047        String modifierValue = null;
6048        TextInfo tiTemp = null;
6049
6050        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) || modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
6051        {
6052            modifierValue = "";
6053            String mg = "";
6054            String maq = "";
6055
6056            if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
6057                mg = modifiers.get(Modifiers.G_STAFF_COMMENTS);
6058            if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
6059                maq = modifiers.get(Modifiers.AQ_GUARDED_UNIT);
6060
6061            modifierValue = mg + " " + maq;
6062
6063            modifierValue = modifierValue.trim();
6064
6065            if(modifierValue != null)
6066            {
6067                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6068                labelBounds = tiTemp.getTextBounds();
6069                labelWidth = (int)labelBounds.width();
6070
6071                //on right
6072                x = (int)getLabelXPosition(bounds, labelWidth, true);
6073                //above center H
6074                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
6075
6076                tiTemp.setLocation(x, y);
6077                tiArray.add(tiTemp);
6078
6079            }
6080        }
6081
6082        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
6083        {
6084            modifierValue = "";
6085
6086            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
6087            {
6088                modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
6089            }
6090
6091
6092            if(modifierValue != null && modifierValue.equals("") == false)
6093            {
6094                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6095                labelBounds = tiTemp.getTextBounds();
6096                labelWidth = labelBounds.width();
6097
6098                //on right
6099                x = (int)getLabelXPosition(bounds, labelWidth, true);
6100                //center
6101                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
6102
6103                tiTemp.setLocation(x, y);
6104                tiArray.add(tiTemp);
6105
6106            }
6107        }
6108
6109        if (modifiers.containsKey(Modifiers.C_QUANTITY) ||
6110                modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
6111        {
6112            modifierValue = "";
6113            String mc = "";
6114            String mae = "";
6115
6116            if(modifiers.containsKey(Modifiers.C_QUANTITY))
6117                mc = modifiers.get(Modifiers.C_QUANTITY);
6118            if(modifiers.containsKey(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME))
6119                mae = modifiers.get(Modifiers.AE_EQUIPMENT_TEARDOWN_TIME);
6120
6121            modifierValue = mc + " " + mae;
6122
6123            modifierValue = modifierValue.trim();
6124
6125            if(modifierValue != null)
6126            {
6127                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6128                labelBounds = tiTemp.getTextBounds();
6129                labelWidth = (int)labelBounds.width();
6130
6131                //on left
6132                x = (int)getLabelXPosition(bounds, labelWidth, false);
6133                //just below center
6134                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -1);
6135
6136
6137                tiTemp.setLocation(x, y);
6138                tiArray.add(tiTemp);
6139            }
6140        }
6141
6142        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
6143        {
6144            modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
6145
6146            if(modifierValue != null)
6147            {
6148                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6149                labelBounds = tiTemp.getTextBounds();
6150                labelWidth = labelBounds.width();
6151
6152                //on left
6153                x = (int)getLabelXPosition(bounds, labelWidth, false);
6154                //below C/AE
6155                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -2);
6156
6157
6158                tiTemp.setLocation(x, y);
6159                tiArray.add(tiTemp);
6160            }
6161        }
6162
6163        if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
6164        {
6165            modifierValue = modifiers.get(Modifiers.M_HIGHER_FORMATION);
6166
6167
6168            if(modifierValue.equals("")==false)
6169            {
6170                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6171                labelBounds = tiTemp.getTextBounds();
6172                labelWidth = (int)labelBounds.width();
6173
6174                //on right
6175                x = (int)getLabelXPosition(bounds, labelWidth, true);
6176                //below center H
6177                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
6178
6179                tiTemp.setLocation(x, y);
6180                tiArray.add(tiTemp);
6181
6182            }
6183        }
6184
6185        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)
6186                || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
6187                || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))//
6188        {
6189            modifierValue = null;
6190
6191            String jm = null,
6192                    km = null,
6193                    pm = null;
6194
6195            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
6196            {
6197                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
6198            }
6199            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.K_COMBAT_EFFECTIVENESS))
6200            {
6201                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
6202            }
6203            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.P_IFF_SIF_AIS))
6204            {
6205                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
6206            }
6207
6208            modifierValue = "";
6209            if (jm != null && jm.equals("") == false)
6210            {
6211                modifierValue = modifierValue + jm;
6212            }
6213            if (km != null && km.equals("") == false)
6214            {
6215                modifierValue = modifierValue + " " + km;
6216            }
6217            if (pm != null && pm.equals("") == false)
6218            {
6219                modifierValue = modifierValue + " " + pm;
6220            }
6221
6222            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
6223            {
6224                modifierValue = modifierValue.substring(1);
6225            }
6226
6227            modifierValue = modifierValue.trim();
6228
6229            if(modifierValue.equals("")==false)
6230            {
6231                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6232                labelBounds = tiTemp.getTextBounds();
6233                labelWidth = labelBounds.width();
6234
6235                //on right
6236                x = (int)getLabelXPosition(bounds, labelWidth, true);
6237                //below M
6238                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
6239
6240
6241                tiTemp.setLocation(x, y);
6242                tiArray.add(tiTemp);
6243
6244            }
6245
6246        }
6247
6248        if (modifiers.containsKey(Modifiers.W_DTG_1) )
6249        {
6250            modifierValue = "";
6251            String mw = "";
6252            String mar = "";
6253            if(modifiers.containsKey(Modifiers.W_DTG_1))
6254                modifierValue = modifiers.get(Modifiers.W_DTG_1);
6255
6256            if(modifierValue != null)
6257            {
6258                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6259                labelBounds = tiTemp.getTextBounds();
6260                labelWidth = labelBounds.width();
6261
6262                //on left
6263                x = (int)getLabelXPosition(bounds, labelWidth, false);
6264                //above X/Y
6265                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
6266
6267
6268                tiTemp.setLocation(x, y);
6269                tiArray.add(tiTemp);
6270            }
6271        }
6272
6273        if (modifiers.containsKey(Modifiers.AS_COUNTRY)  ||
6274                modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
6275        {
6276            modifierValue = "";
6277            String E = null,
6278                    AS = null;
6279
6280            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) )
6281            {
6282                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
6283                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
6284            }
6285            if (modifiers.containsKey(Modifiers.AS_COUNTRY) )
6286            {
6287                AS = modifiers.get(Modifiers.AS_COUNTRY);
6288            }
6289
6290            if (E != null && E.equals("") == false)
6291            {
6292                modifierValue += E;
6293            }
6294
6295            if (AS != null && AS.equals("") == false)
6296            {
6297                modifierValue = modifierValue + " " + AS;
6298            }
6299
6300            modifierValue = modifierValue.trim();
6301
6302            if(modifierValue != null)
6303            {
6304                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6305                labelBounds = tiTemp.getTextBounds();
6306                labelWidth = (int)labelBounds.width();
6307
6308                //on right
6309                x = (int)getLabelXPosition(bounds, labelWidth, true);
6310                //above G
6311                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
6312
6313
6314                tiTemp.setLocation(x, y);
6315                tiArray.add(tiTemp);
6316
6317            }
6318        }
6319
6320        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) ||
6321                modifiers.containsKey(Modifiers.Y_LOCATION) )
6322        {
6323            String mx = null,
6324                    my = null;
6325
6326            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
6327            {
6328                mx = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
6329            }
6330            if (modifiers.containsKey(Modifiers.Y_LOCATION))
6331            {
6332                my = modifiers.get(Modifiers.Y_LOCATION);
6333            }
6334
6335
6336            modifierValue = "";
6337            if (mx != null && mx.equals("") == false)
6338            {
6339                modifierValue = modifierValue + mx;
6340            }
6341            if (my != null && my.equals("") == false)
6342            {
6343                modifierValue = modifierValue + " " + my;
6344            }
6345
6346            modifierValue = modifierValue.trim();
6347
6348            if(modifierValue != null)
6349            {
6350                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6351                labelBounds = tiTemp.getTextBounds();
6352                labelWidth = labelBounds.width();
6353
6354                //on left
6355                x = (int)getLabelXPosition(bounds, labelWidth, false);
6356                //above vertical center
6357                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 1);
6358
6359                tiTemp.setLocation(x, y);
6360                tiArray.add(tiTemp);
6361            }
6362        }
6363
6364
6365
6366        // </editor-fold>
6367
6368        //Shift Points and Draw
6369        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
6370
6371        // <editor-fold defaultstate="collapsed" desc="Cleanup">
6372        tiArray = null;
6373        tiTemp = null;
6374        //tempShape = null;
6375        //ctx = null;
6376        //buffer = null;
6377        // </editor-fold>
6378
6379        return newsdi;
6380    }
6381
6382    public static SymbolDimensionInfo  processDismountedIndividualsTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
6383    {
6384        int bufferXL = 7;
6385        int bufferXR = 7;
6386        int bufferY = 2;
6387        int bufferText = 2;
6388        int x = 0;
6389        int y = 0;//best y
6390        SymbolDimensionInfo newsdi = null;
6391
6392        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
6393
6394        int descent = (int) (_modifierFontDescent + 0.5);
6395
6396
6397        Rect labelBounds = null;
6398        int labelWidth, labelHeight;
6399
6400        Rect bounds = new Rect(sdi.getSymbolBounds());
6401        Rect imageBounds = new Rect(sdi.getImageBounds());
6402
6403        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
6404        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
6405
6406        labelHeight = (int) (_modifierFontHeight + 0.5);
6407
6408        //Affiliation Modifier being drawn as a display modifier
6409        String affiliationModifier = null;
6410        if (RS.getDrawAffiliationModifierAsLabel() == true)
6411        {
6412            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
6413        }
6414        if (affiliationModifier != null)
6415        {   //Set affiliation modifier
6416            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
6417            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
6418        }//*/
6419
6420        //Check for Valid Country Code
6421        int cc = SymbolID.getCountryCode(symbolID);
6422        String scc = "";
6423        if(cc > 0)
6424        {
6425            scc = GENCLookup.getInstance().get3CharCode(cc);
6426        }
6427        if(!scc.isEmpty())
6428            modifiers.put(Modifiers.AS_COUNTRY, scc);
6429        //
6430        //            int y0 = 0;//W/           AS
6431        //            int y1 = 0;//X/Y          G
6432        //            int y2 = 0;//V/AF         H
6433        //            int y3 = 0;//T            M
6434        //            int y4 = 0;//Z            J/K/P
6435        //
6436 
6437        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
6438        String modifierValue = null;
6439        TextInfo tiTemp = null;
6440
6441
6442        //if(Modifiers.X_ALTITUDE_DEPTH in modifiers || Modifiers.Y_LOCATION in modifiers)
6443        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH) || modifiers.containsKey(Modifiers.Y_LOCATION))
6444        {
6445            modifierValue = null;
6446
6447            String xm = null,
6448                    ym = null;
6449
6450            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
6451            {
6452                xm = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);// xm = modifiers.X;
6453            }
6454            if (modifiers.containsKey(Modifiers.Y_LOCATION))
6455            {
6456                ym = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
6457            }
6458            if (xm == null && ym != null)
6459            {
6460                modifierValue = ym;
6461            }
6462            else if (xm != null && ym == null)
6463            {
6464                modifierValue = xm;
6465            }
6466            else if (xm != null && ym != null)
6467            {
6468                modifierValue = xm + "  " + ym;
6469            }
6470
6471            if(modifierValue != null)
6472            {
6473                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6474                labelBounds = tiTemp.getTextBounds();
6475                labelWidth = (int)labelBounds.width();
6476
6477                //on left
6478                x = (int)getLabelXPosition(bounds, labelWidth, false);
6479                //above center V
6480                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
6481
6482                tiTemp.setLocation(x, y);
6483                tiArray.add(tiTemp);
6484            }
6485        }
6486
6487        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
6488        {
6489            modifierValue = null;
6490
6491
6492            if(modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
6493                modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
6494
6495
6496            if(modifierValue != null)
6497            {
6498                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6499                labelBounds = tiTemp.getTextBounds();
6500                labelWidth = (int)labelBounds.width();
6501
6502                //on right
6503                x = (int)getLabelXPosition(bounds, labelWidth, true);
6504                //above center H
6505                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
6506
6507                tiTemp.setLocation(x, y);
6508                tiArray.add(tiTemp);
6509
6510            }
6511        }
6512
6513
6514        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
6515        {
6516            modifierValue = null;
6517            String hm = "";
6518
6519            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
6520                modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
6521
6522
6523            if(modifierValue != null && modifierValue.equals("") == false)
6524            {
6525                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6526                labelBounds = tiTemp.getTextBounds();
6527                labelWidth = (int)labelBounds.width();
6528
6529                //on right
6530                x = (int)getLabelXPosition(bounds, labelWidth, true);
6531                //center
6532                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
6533
6534                tiTemp.setLocation(x, y);
6535                tiArray.add(tiTemp);
6536
6537            }
6538        }
6539
6540        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
6541        {
6542            modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
6543
6544            if(modifierValue != null)
6545            {
6546                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6547                labelBounds = tiTemp.getTextBounds();
6548                labelWidth = (int)labelBounds.width();
6549
6550                //on left
6551                x = (int)getLabelXPosition(bounds, labelWidth, false);
6552                //below center V
6553                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
6554
6555
6556                tiTemp.setLocation(x, y);
6557                tiArray.add(tiTemp);
6558            }
6559        }
6560
6561        if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
6562        {
6563            modifierValue = "";
6564
6565            if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
6566            {
6567                modifierValue += modifiers.get(Modifiers.M_HIGHER_FORMATION);
6568            }
6569
6570            if(modifierValue.equals("")==false)
6571            {
6572                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6573                labelBounds = tiTemp.getTextBounds();
6574                labelWidth = (int)labelBounds.width();
6575
6576                //on right
6577                x = (int)getLabelXPosition(bounds, labelWidth, true);
6578                //below center H
6579                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
6580
6581                tiTemp.setLocation(x, y);
6582                tiArray.add(tiTemp);
6583
6584            }
6585        }
6586
6587        if (modifiers.containsKey(Modifiers.Z_SPEED))
6588        {
6589            modifierValue = modifiers.get(Modifiers.Z_SPEED);
6590
6591            if(modifierValue != null)
6592            {
6593                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6594                labelBounds = tiTemp.getTextBounds();
6595                labelWidth = (int)labelBounds.width();
6596
6597                //on left
6598                x = (int)getLabelXPosition(bounds, labelWidth, false);
6599                //below T
6600                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
6601
6602
6603                tiTemp.setLocation(x, y);
6604                tiArray.add(tiTemp);
6605            }
6606        }
6607
6608        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING)
6609                || modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
6610                || modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))//
6611        {
6612            modifierValue = null;
6613
6614            String jm = null,
6615                    km = null,
6616                    pm = null;
6617
6618            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
6619            {
6620                jm = modifiers.get(Modifiers.J_EVALUATION_RATING);
6621            }
6622            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)  && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.K_COMBAT_EFFECTIVENESS))
6623            {
6624                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
6625            }
6626            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS) && SymbolUtilities.canSymbolHaveModifier(symbolID, Modifiers.P_IFF_SIF_AIS))
6627            {
6628                pm = modifiers.get(Modifiers.P_IFF_SIF_AIS);
6629            }
6630
6631            modifierValue = "";
6632            if (jm != null && jm.equals("") == false)
6633            {
6634                modifierValue = modifierValue + jm;
6635            }
6636            if (km != null && km.equals("") == false)
6637            {
6638                modifierValue = modifierValue + " " + km;
6639            }
6640            if (pm != null && pm.equals("") == false)
6641            {
6642                modifierValue = modifierValue + " " + pm;
6643            }
6644
6645            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
6646            {
6647                modifierValue = modifierValue.substring(1);
6648            }
6649
6650            modifierValue = modifierValue.trim();
6651
6652            if(modifierValue.equals("")==false)
6653            {
6654                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6655                labelBounds = tiTemp.getTextBounds();
6656                labelWidth = (int)labelBounds.width();
6657
6658                //on right
6659                x = (int)getLabelXPosition(bounds, labelWidth, true);
6660                //below M
6661                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
6662
6663
6664                tiTemp.setLocation(x, y);
6665                tiArray.add(tiTemp);
6666
6667            }
6668
6669        }
6670
6671        if (modifiers.containsKey(Modifiers.W_DTG_1))
6672        {
6673            modifierValue = null;
6674
6675            modifierValue = modifiers.get(Modifiers.W_DTG_1);
6676
6677
6678            if(modifierValue != null)
6679            {
6680                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6681                labelBounds = tiTemp.getTextBounds();
6682                labelWidth = (int)labelBounds.width();
6683
6684                //on left
6685                x = (int)getLabelXPosition(bounds, labelWidth, false);
6686                //above X/Y
6687                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
6688
6689
6690                tiTemp.setLocation(x, y);
6691                tiArray.add(tiTemp);
6692            }
6693        }
6694
6695        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) ||
6696                modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
6697        {
6698            String mv = null,
6699                    maf = null;
6700
6701            if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
6702            {
6703                mv = modifiers.get(Modifiers.V_EQUIP_TYPE);
6704            }
6705            if (modifiers.containsKey(Modifiers.AF_COMMON_IDENTIFIER))
6706            {
6707                maf = modifiers.get(Modifiers.AF_COMMON_IDENTIFIER);
6708            }
6709
6710
6711            modifierValue = "";
6712            if (mv != null && mv.equals("") == false)
6713            {
6714                modifierValue = modifierValue + mv;
6715            }
6716            if (maf != null && maf.equals("") == false)
6717            {
6718                modifierValue = modifierValue + " " + maf;
6719            }
6720
6721            modifierValue = modifierValue.trim();
6722
6723            if(modifierValue != null)
6724            {
6725                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6726                labelBounds = tiTemp.getTextBounds();
6727                labelWidth = (int)labelBounds.width();
6728
6729                //on left
6730                x = (int)getLabelXPosition(bounds, labelWidth, false);
6731                //center
6732                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
6733
6734                tiTemp.setLocation(x, y);
6735                tiArray.add(tiTemp);
6736            }
6737        }
6738
6739        if (modifiers.containsKey(Modifiers.AS_COUNTRY) ||
6740                modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
6741        {
6742            modifierValue = "";
6743            String E = null,
6744                    AS = null;
6745
6746            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
6747            {
6748                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
6749                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
6750            }
6751            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
6752            {
6753                AS = modifiers.get(Modifiers.AS_COUNTRY);
6754            }
6755
6756            if (E != null && E.equals("") == false)
6757            {
6758                modifierValue += E;
6759            }
6760
6761            if (AS != null && AS.equals("") == false)
6762            {
6763                modifierValue = modifierValue + " " + AS;
6764            }
6765
6766            modifierValue = modifierValue.trim();
6767
6768            if(modifierValue != null)
6769            {
6770                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6771                labelBounds = tiTemp.getTextBounds();
6772                labelWidth = (int)labelBounds.width();
6773
6774                //on right
6775                x = (int)getLabelXPosition(bounds, labelWidth, true);
6776                //above G
6777                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
6778
6779
6780                tiTemp.setLocation(x, y);
6781                tiArray.add(tiTemp);
6782
6783            }
6784        }
6785
6786
6787        // </editor-fold>
6788
6789        //Shift Points and Draw
6790        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
6791
6792        // <editor-fold defaultstate="collapsed" desc="Cleanup">
6793        tiArray = null;
6794        tiTemp = null;
6795        //tempShape = null;
6796        //ctx = null;
6797        //buffer = null;
6798        // </editor-fold>
6799
6800        return newsdi;
6801    }
6802
6803    public static SymbolDimensionInfo  processSeaSurfaceTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
6804    {
6805        int bufferXL = 7;
6806        int bufferXR = 7;
6807        int bufferY = 2;
6808        int bufferText = 2;
6809        int x = 0;
6810        int y = 0;//best y
6811        SymbolDimensionInfo newsdi = null;
6812
6813        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
6814
6815        int descent = (int) (_modifierFontDescent + 0.5);
6816
6817        Rect labelBounds = null;
6818        int labelWidth, labelHeight;
6819
6820        Rect bounds = new Rect(sdi.getSymbolBounds());
6821        Rect imageBounds = new Rect(sdi.getImageBounds());
6822
6823
6824        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
6825        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
6826
6827        labelHeight = (int) (_modifierFontHeight + 0.5);
6828
6829        //Affiliation Modifier being drawn as a display modifier
6830        String affiliationModifier = null;
6831        if (RS.getDrawAffiliationModifierAsLabel() == true)
6832        {
6833            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
6834        }
6835        if (affiliationModifier != null)
6836        {   //Set affiliation modifier
6837            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
6838            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
6839        }//*/
6840
6841        //Check for Valid Country Code
6842        int cc = SymbolID.getCountryCode(symbolID);
6843        String scc = "";
6844        if(cc > 0)
6845        {
6846            scc = GENCLookup.getInstance().get3CharCode(cc);
6847        }
6848        if(!scc.isEmpty())
6849            modifiers.put(Modifiers.AS_COUNTRY, scc);
6850
6851        //            int y0 = 0;//AQ/AR        E/T
6852        //            int y1 = 0;//              V
6853        //            int y2 =                   P
6854        //            int y3 = 0;//             G/H
6855        //            int y4 = 0;//             Y/Z
6856        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
6857        String modifierValue = null;
6858        TextInfo tiTemp = null;
6859
6860
6861
6862
6863        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
6864        {
6865            modifierValue = modifiers.get(Modifiers.V_EQUIP_TYPE);
6866
6867            if(modifierValue != null)
6868            {
6869                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6870                labelBounds = tiTemp.getTextBounds();
6871                labelWidth = labelBounds.width();
6872
6873                //on right
6874                x = (int)getLabelXPosition(bounds, labelWidth, true);
6875                //above center
6876                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 1);
6877
6878                tiTemp.setLocation(x, y);
6879                tiArray.add(tiTemp);
6880
6881            }
6882        }
6883
6884
6885        if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
6886        {
6887            modifierValue = null;
6888
6889            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
6890            {
6891                modifierValue = modifiers.get(Modifiers.P_IFF_SIF_AIS);
6892            }
6893
6894            if(modifierValue != null && modifierValue.equals("") == false)
6895            {
6896                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6897                labelBounds = tiTemp.getTextBounds();
6898                labelWidth = labelBounds.width();
6899
6900                //on right
6901                x = (int)getLabelXPosition(bounds, labelWidth, true);
6902                //below center
6903                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -1);
6904
6905                tiTemp.setLocation(x, y);
6906                tiArray.add(tiTemp);
6907
6908            }
6909        }
6910
6911
6912
6913        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) ||
6914                modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
6915        {
6916            modifierValue = "";
6917            String mg = "",
6918                mh = "";
6919
6920            if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
6921            {
6922                mg += modifiers.get(Modifiers.G_STAFF_COMMENTS);
6923            }
6924
6925            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
6926            {
6927                mh += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
6928            }
6929
6930            modifierValue = mg + " " + mh;
6931
6932            modifierValue = modifierValue.trim();
6933
6934            if(modifierValue.equals("")==false)
6935            {
6936                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6937                labelBounds = tiTemp.getTextBounds();
6938                labelWidth = labelBounds.width();
6939
6940                //on right
6941                x = (int)getLabelXPosition(bounds, labelWidth, true);
6942                //below P
6943                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -2);
6944
6945                tiTemp.setLocation(x, y);
6946                tiArray.add(tiTemp);
6947
6948            }
6949        }
6950
6951
6952        if (modifiers.containsKey(Modifiers.Y_LOCATION)
6953                || modifiers.containsKey(Modifiers.Z_SPEED))//
6954        {
6955            modifierValue = null;
6956
6957            String ym = "",
6958                    zm = "";
6959
6960            if (modifiers.containsKey(Modifiers.Y_LOCATION))
6961            {
6962                ym = modifiers.get(Modifiers.Y_LOCATION);
6963            }
6964            if (modifiers.containsKey(Modifiers.Z_SPEED))
6965            {
6966                zm = modifiers.get(Modifiers.Z_SPEED);
6967            }
6968
6969            modifierValue = ym + " " + zm;
6970
6971            modifierValue = modifierValue.trim();
6972
6973
6974            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
6975            {
6976                modifierValue = modifierValue.substring(1);
6977            }
6978
6979            modifierValue = modifierValue.trim();
6980
6981            if(modifierValue.equals("")==false)
6982            {
6983                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
6984                labelBounds = tiTemp.getTextBounds();
6985                labelWidth = labelBounds.width();
6986
6987                //on right
6988                x = (int)getLabelXPosition(bounds, labelWidth, true);
6989                //below G
6990                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -3);
6991
6992
6993                tiTemp.setLocation(x, y);
6994                tiArray.add(tiTemp);
6995
6996            }
6997
6998        }
6999
7000        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
7001        {
7002            modifierValue = modifierValue = modifiers.get(Modifiers.P_IFF_SIF_AIS);
7003
7004            if(modifierValue != null && modifierValue.equals("") == false)
7005            {
7006                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7007                labelBounds = tiTemp.getTextBounds();
7008                labelWidth = labelBounds.width();
7009
7010                //on right
7011                x = (int)getLabelXPosition(bounds, labelWidth, true);
7012                //above V
7013                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
7014
7015                tiTemp.setLocation(x, y);
7016                tiArray.add(tiTemp);
7017
7018            }
7019        }
7020
7021        if (modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) ||
7022                modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR))
7023        {
7024            modifierValue = "";
7025
7026            String maq = "",
7027                    mar = "";
7028            if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
7029                maq = modifiers.get(Modifiers.AQ_GUARDED_UNIT);
7030
7031            if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR))
7032                mar = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR);
7033
7034            modifierValue = maq + " " + mar;
7035            modifierValue = modifierValue.trim();
7036
7037            if(modifierValue != null)
7038            {
7039                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7040                labelBounds = tiTemp.getTextBounds();
7041                labelWidth = labelBounds.width();
7042
7043                /*//on left
7044                x = bounds.left - labelWidth - bufferXL;
7045                //above V
7046                y = (bounds.height());
7047                y = (int) ((y * 0.5) + (labelHeight * 0.5));
7048                y = y - ((labelHeight + bufferText) * 2);
7049                y = bounds.top + y;//*/
7050
7051                //on left
7052                x = (int)getLabelXPosition(bounds, labelWidth, false);
7053                //top left
7054                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
7055
7056                tiTemp.setLocation(x, y);
7057                tiArray.add(tiTemp);
7058            }
7059        }
7060
7061        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
7062                modifiers.containsKey(Modifiers.AS_COUNTRY))
7063        {
7064            modifierValue = null;
7065            String E = "",
7066                    AS = "";
7067
7068            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
7069            {
7070                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
7071                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
7072            }
7073            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
7074            {
7075                AS = modifiers.get(Modifiers.AS_COUNTRY);
7076            }
7077
7078            modifierValue = E + " " + AS;
7079            modifierValue = modifierValue.trim();
7080
7081
7082            if(modifierValue.equals("")==false)
7083            {
7084                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7085                labelBounds = tiTemp.getTextBounds();
7086                labelWidth = labelBounds.width();
7087
7088                //on right
7089                x = (int)getLabelXPosition(bounds, labelWidth, true);
7090                //below G
7091                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 3);
7092
7093
7094                tiTemp.setLocation(x, y);
7095                tiArray.add(tiTemp);
7096
7097            }
7098        }
7099
7100
7101        // </editor-fold>
7102
7103        //Shift Points and Draw
7104        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
7105
7106        // <editor-fold defaultstate="collapsed" desc="Cleanup">
7107        tiArray = null;
7108        tiTemp = null;
7109        //tempShape = null;
7110        //ctx = null;
7111        //buffer = null;
7112        // </editor-fold>
7113
7114        return newsdi;
7115    }
7116
7117    public static SymbolDimensionInfo  processSeaSurfaceTextModifiersE(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
7118    {
7119        int bufferXL = 7;
7120        int bufferXR = 7;
7121        int bufferY = 2;
7122        int bufferText = 2;
7123        int x = 0;
7124        int y = 0;//best y
7125        SymbolDimensionInfo newsdi = null;
7126
7127        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
7128
7129        int descent = (int) (_modifierFontDescent + 0.5);
7130
7131        Rect labelBounds = null;
7132        int labelWidth, labelHeight;
7133
7134        Rect bounds = new Rect(sdi.getSymbolBounds());
7135        Rect imageBounds = new Rect(sdi.getImageBounds());
7136
7137
7138        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
7139        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
7140
7141        labelHeight = (int) (_modifierFontHeight + 0.5);
7142
7143        //Affiliation Modifier being drawn as a display modifier
7144        String affiliationModifier = null;
7145        if (RS.getDrawAffiliationModifierAsLabel() == true)
7146        {
7147            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
7148        }
7149        if (affiliationModifier != null)
7150        {   //Set affiliation modifier
7151            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
7152            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
7153        }//*/
7154
7155        //Check for Valid Country Code
7156        int cc = SymbolID.getCountryCode(symbolID);
7157        String scc = "";
7158        if(cc > 0)
7159        {
7160            scc = GENCLookup.getInstance().get3CharCode(cc);
7161        }
7162        if(!scc.isEmpty())
7163            modifiers.put(Modifiers.AS_COUNTRY, scc);
7164
7165        //            int y0 = 0;//AQ/AR        E/T
7166        //            int y1 = 0;//              V
7167        //            int y2 =                   P
7168        //            int y3 = 0;//             G/H
7169        //            int y4 = 0;//             Y/Z
7170        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
7171        String modifierValue = null;
7172        TextInfo tiTemp = null;
7173
7174
7175
7176
7177        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
7178        {
7179            modifierValue = modifiers.get(Modifiers.V_EQUIP_TYPE);
7180
7181            if(modifierValue != null)
7182            {
7183                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7184                labelBounds = tiTemp.getTextBounds();
7185                labelWidth = labelBounds.width();
7186
7187                //on right
7188                x = (int)getLabelXPosition(bounds, labelWidth, true);
7189                //above center
7190                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 1);
7191
7192                tiTemp.setLocation(x, y);
7193                tiArray.add(tiTemp);
7194
7195            }
7196        }
7197
7198
7199        if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
7200        {
7201            modifierValue = null;
7202
7203            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
7204            {
7205                modifierValue = modifiers.get(Modifiers.P_IFF_SIF_AIS);
7206            }
7207
7208            if(modifierValue != null && modifierValue.equals("") == false)
7209            {
7210                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7211                labelBounds = tiTemp.getTextBounds();
7212                labelWidth = labelBounds.width();
7213
7214                //on right
7215                x = (int)getLabelXPosition(bounds, labelWidth, true);
7216                //below center
7217                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -1);
7218
7219                tiTemp.setLocation(x, y);
7220                tiArray.add(tiTemp);
7221
7222            }
7223        }
7224
7225
7226
7227        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) ||
7228                modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
7229        {
7230            modifierValue = "";
7231            String mg = "",
7232                    mh = "";
7233
7234            if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
7235            {
7236                mg += modifiers.get(Modifiers.G_STAFF_COMMENTS);
7237            }
7238
7239            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
7240            {
7241                mh += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
7242            }
7243
7244            modifierValue = mg + " " + mh;
7245
7246            modifierValue = modifierValue.trim();
7247
7248            if(modifierValue.equals("")==false)
7249            {
7250                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7251                labelBounds = tiTemp.getTextBounds();
7252                labelWidth = labelBounds.width();
7253
7254                //on right
7255                x = (int)getLabelXPosition(bounds, labelWidth, true);
7256                //below P
7257                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -2);
7258
7259                tiTemp.setLocation(x, y);
7260                tiArray.add(tiTemp);
7261
7262            }
7263        }
7264
7265
7266        if (modifiers.containsKey(Modifiers.Y_LOCATION)
7267                || modifiers.containsKey(Modifiers.Z_SPEED))//
7268        {
7269            modifierValue = null;
7270
7271            String ym = "",
7272                    zm = "";
7273
7274            if (modifiers.containsKey(Modifiers.Y_LOCATION))
7275            {
7276                ym = modifiers.get(Modifiers.Y_LOCATION);
7277            }
7278            if (modifiers.containsKey(Modifiers.Z_SPEED))
7279            {
7280                zm = modifiers.get(Modifiers.Z_SPEED);
7281            }
7282
7283            modifierValue = ym + " " + zm;
7284
7285            modifierValue = modifierValue.trim();
7286
7287
7288            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
7289            {
7290                modifierValue = modifierValue.substring(1);
7291            }
7292
7293            modifierValue = modifierValue.trim();
7294
7295            if(modifierValue.equals("")==false)
7296            {
7297                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7298                labelBounds = tiTemp.getTextBounds();
7299                labelWidth = labelBounds.width();
7300
7301                //on right
7302                x = (int)getLabelXPosition(bounds, labelWidth, true);
7303                //below G
7304                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -3);
7305
7306
7307                tiTemp.setLocation(x, y);
7308                tiArray.add(tiTemp);
7309
7310            }
7311
7312        }
7313
7314        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
7315        {
7316            modifierValue = modifierValue = modifiers.get(Modifiers.P_IFF_SIF_AIS);
7317
7318            if(modifierValue != null && modifierValue.equals("") == false)
7319            {
7320                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7321                labelBounds = tiTemp.getTextBounds();
7322                labelWidth = labelBounds.width();
7323
7324                //on right
7325                x = (int)getLabelXPosition(bounds, labelWidth, true);
7326                //above V
7327                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
7328
7329                tiTemp.setLocation(x, y);
7330                tiArray.add(tiTemp);
7331
7332            }
7333        }
7334
7335        if (modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT) ||
7336                modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR))
7337        {
7338            modifierValue = "";
7339
7340            String maq = "",
7341                    mar = "";
7342            if(modifiers.containsKey(Modifiers.AQ_GUARDED_UNIT))
7343                maq = modifiers.get(Modifiers.AQ_GUARDED_UNIT);
7344
7345            if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR))
7346                mar = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR);
7347
7348            modifierValue = maq + " " + mar;
7349            modifierValue = modifierValue.trim();
7350
7351            if(modifierValue != null)
7352            {
7353                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7354                labelBounds = tiTemp.getTextBounds();
7355                labelWidth = labelBounds.width();
7356
7357                /*//on left
7358                x = bounds.left - labelWidth - bufferXL;
7359                //above V
7360                y = (bounds.height());
7361                y = (int) ((y * 0.5) + (labelHeight * 0.5));
7362                y = y - ((labelHeight + bufferText) * 2);
7363                y = bounds.top + y;//*/
7364
7365                //on left
7366                x = (int)getLabelXPosition(bounds, labelWidth, false);
7367                //top left
7368                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
7369
7370                tiTemp.setLocation(x, y);
7371                tiArray.add(tiTemp);
7372            }
7373        }
7374
7375        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
7376                modifiers.containsKey(Modifiers.AS_COUNTRY))
7377        {
7378            modifierValue = null;
7379            String E = "",
7380                    AS = "";
7381
7382            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
7383            {
7384                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
7385                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
7386            }
7387            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
7388            {
7389                AS = modifiers.get(Modifiers.AS_COUNTRY);
7390            }
7391
7392            modifierValue = E + " " + AS;
7393            modifierValue = modifierValue.trim();
7394
7395
7396            if(modifierValue.equals("")==false)
7397            {
7398                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7399                labelBounds = tiTemp.getTextBounds();
7400                labelWidth = labelBounds.width();
7401
7402                //on right
7403                x = (int)getLabelXPosition(bounds, labelWidth, true);
7404                //below G
7405                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 3);
7406
7407
7408                tiTemp.setLocation(x, y);
7409                tiArray.add(tiTemp);
7410
7411            }
7412        }
7413
7414
7415        // </editor-fold>
7416
7417        //Shift Points and Draw
7418        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
7419
7420        // <editor-fold defaultstate="collapsed" desc="Cleanup">
7421        tiArray = null;
7422        tiTemp = null;
7423        //tempShape = null;
7424        //ctx = null;
7425        //buffer = null;
7426        // </editor-fold>
7427
7428        return newsdi;
7429    }
7430
7431    public static SymbolDimensionInfo  processSeaSubSurfaceTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
7432    {
7433        int bufferXL = 7;
7434        int bufferXR = 7;
7435        int bufferY = 2;
7436        int bufferText = 2;
7437        int x = 0;
7438        int y = 0;//best y
7439        SymbolDimensionInfo newsdi = null;
7440
7441        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
7442
7443        int descent = (int) (_modifierFontDescent + 0.5);
7444
7445        Rect labelBounds = null;
7446        int labelWidth, labelHeight;
7447
7448        Rect bounds = new Rect(sdi.getSymbolBounds());
7449        Rect imageBounds = new Rect(sdi.getImageBounds());
7450
7451
7452        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
7453        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
7454
7455        labelHeight = (int) (_modifierFontHeight + 0.5);
7456
7457        //Affiliation Modifier being drawn as a display modifier
7458        String affiliationModifier = null;
7459        if (RS.getDrawAffiliationModifierAsLabel() == true)
7460        {
7461            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
7462        }
7463        if (affiliationModifier != null)
7464        {   //Set affiliation modifier
7465            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
7466            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
7467        }//*/
7468
7469        //Check for Valid Country Code
7470        int cc = SymbolID.getCountryCode(symbolID);
7471        String scc = "";
7472        if(cc > 0)
7473        {
7474            scc = GENCLookup.getInstance().get3CharCode(cc);
7475        }
7476        if(!scc.isEmpty())
7477            modifiers.put(Modifiers.AS_COUNTRY, scc);
7478
7479        //            int y0 = 0;//AR           T
7480        //            int y1 = 0;//             V
7481        //            int y2 =                  X
7482        //            int y3 = 0;//             G
7483        //            int y4 = 0;//             H
7484        //
7485
7486        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
7487        String modifierValue = null;
7488        TextInfo tiTemp = null;
7489
7490        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
7491                modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) ||
7492                modifiers.containsKey(Modifiers.AS_COUNTRY))
7493        {
7494
7495            String em = "";
7496            String tm = "";
7497            String asm = "";
7498            if(modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
7499                em = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
7500
7501            if(modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
7502                tm = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
7503
7504            if(modifiers.containsKey(Modifiers.AS_COUNTRY))
7505                asm = modifiers.get(Modifiers.AS_COUNTRY);
7506
7507            modifierValue = em + " " + tm;
7508            modifierValue = modifierValue.trim();
7509            modifierValue = modifierValue + " " + asm;
7510            modifierValue = modifierValue.trim();
7511
7512            if(modifierValue.equals("")==false)
7513            {
7514                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7515                labelBounds = tiTemp.getTextBounds();
7516                labelWidth = labelBounds.width();
7517
7518                //on right
7519                x = (int)getLabelXPosition(bounds, labelWidth, true);
7520                //on top
7521                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
7522
7523                tiTemp.setLocation(x, y);
7524                tiArray.add(tiTemp);
7525
7526            }
7527        }
7528
7529        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE) )
7530        {
7531            modifierValue = "";
7532
7533            if(modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
7534                modifierValue = modifiers.get(Modifiers.V_EQUIP_TYPE);
7535
7536            if(modifierValue != null && modifierValue.equals("")==false)
7537            {
7538                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7539                labelBounds = tiTemp.getTextBounds();
7540                labelWidth = labelBounds.width();
7541
7542                //on right
7543                x = (int)getLabelXPosition(bounds, labelWidth, true);
7544                //below T
7545                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
7546
7547                tiTemp.setLocation(x, y);
7548                tiArray.add(tiTemp);
7549
7550            }
7551        }
7552
7553        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
7554        {
7555            modifierValue = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
7556
7557            if(modifierValue != null && modifierValue.equals("") == false)
7558            {
7559                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7560                labelBounds = tiTemp.getTextBounds();
7561                labelWidth = labelBounds.width();
7562
7563                //on right
7564                x = (int)getLabelXPosition(bounds, labelWidth, true);
7565                //centered below V
7566                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
7567
7568                tiTemp.setLocation(x, y);
7569                tiArray.add(tiTemp);
7570
7571            }
7572        }
7573
7574        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
7575        {
7576            modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
7577
7578            if(modifierValue != null && modifierValue.equals("") == false)
7579            {
7580                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7581                labelBounds = tiTemp.getTextBounds();
7582                labelWidth = labelBounds.width();
7583
7584                //on right
7585                x = (int)getLabelXPosition(bounds, labelWidth, true);
7586                //below X
7587                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
7588
7589                tiTemp.setLocation(x, y);
7590                tiArray.add(tiTemp);
7591
7592            }
7593        }
7594
7595        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
7596        {
7597            modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
7598
7599            if(modifierValue != null && modifierValue.equals("") == false)
7600            {
7601                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7602                labelBounds = tiTemp.getTextBounds();
7603                labelWidth = labelBounds.width();
7604
7605                //on right
7606                x = (int)getLabelXPosition(bounds, labelWidth, true);
7607                //below G
7608                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
7609
7610                tiTemp.setLocation(x, y);
7611                tiArray.add(tiTemp);
7612
7613            }
7614        }
7615
7616        if (modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR) )
7617        {
7618            modifierValue = "";
7619
7620            if(modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR))
7621                modifierValue = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR);
7622
7623            if(modifierValue != null && modifierValue.equals("")==false)
7624            {
7625                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7626                labelBounds = tiTemp.getTextBounds();
7627                labelWidth = labelBounds.width();
7628
7629                //on left
7630                x = (int)getLabelXPosition(bounds, labelWidth, false);
7631                //on top
7632                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
7633
7634                tiTemp.setLocation(x, y);
7635                tiArray.add(tiTemp);
7636
7637            }
7638        }
7639
7640
7641        // </editor-fold>
7642
7643        //Shift Points and Draw
7644        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
7645
7646        // <editor-fold defaultstate="collapsed" desc="Cleanup">
7647        tiArray = null;
7648        tiTemp = null;
7649        //tempShape = null;
7650        //ctx = null;
7651        //buffer = null;
7652        // </editor-fold>
7653
7654        return newsdi;
7655    }
7656
7657    public static SymbolDimensionInfo  processSeaSubSurfaceTextModifiersE(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
7658    {
7659        int bufferXL = 7;
7660        int bufferXR = 7;
7661        int bufferY = 2;
7662        int bufferText = 2;
7663        int x = 0;
7664        int y = 0;//best y
7665        SymbolDimensionInfo newsdi = null;
7666
7667        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
7668
7669        int descent = (int) (_modifierFontDescent + 0.5);
7670
7671        Rect labelBounds = null;
7672        int labelWidth, labelHeight;
7673
7674        Rect bounds = new Rect(sdi.getSymbolBounds());
7675        Rect imageBounds = new Rect(sdi.getImageBounds());
7676
7677
7678        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
7679        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
7680
7681        labelHeight = (int) (_modifierFontHeight + 0.5);
7682
7683        //Affiliation Modifier being drawn as a display modifier
7684        String affiliationModifier = null;
7685        if (RS.getDrawAffiliationModifierAsLabel() == true)
7686        {
7687            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
7688        }
7689        if (affiliationModifier != null)
7690        {   //Set affiliation modifier
7691            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
7692            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
7693        }//*/
7694
7695        //Check for Valid Country Code
7696        int cc = SymbolID.getCountryCode(symbolID);
7697        String scc = "";
7698        if(cc > 0)
7699        {
7700            scc = GENCLookup.getInstance().get3CharCode(cc);
7701        }
7702        if(!scc.isEmpty())
7703            modifiers.put(Modifiers.AS_COUNTRY, scc);
7704
7705        //            int y0 = 0;//AR        E/T
7706        //            int y1 = 0;//              V
7707        //            int y2 =                   P
7708        //            int y3 = 0;//             G/H
7709        //            int y4 = 0;//             Y/Z
7710        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
7711        String modifierValue = null;
7712        TextInfo tiTemp = null;
7713
7714
7715
7716
7717        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
7718        {
7719            modifierValue = modifiers.get(Modifiers.V_EQUIP_TYPE);
7720
7721            if(modifierValue != null)
7722            {
7723                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7724                labelBounds = tiTemp.getTextBounds();
7725                labelWidth = labelBounds.width();
7726
7727                //on right
7728                x = (int)getLabelXPosition(bounds, labelWidth, true);
7729                //above vertical center
7730                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 1);
7731
7732                tiTemp.setLocation(x, y);
7733                tiArray.add(tiTemp);
7734
7735            }
7736        }
7737
7738
7739        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)||
7740                modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
7741        {
7742            modifierValue = "";
7743            String mx = "",
7744                    mp = "";
7745
7746            if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
7747            {
7748                modifierValue = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
7749            }
7750
7751            if (modifiers.containsKey(Modifiers.P_IFF_SIF_AIS))
7752            {
7753                modifierValue += " " + modifiers.get(Modifiers.P_IFF_SIF_AIS);
7754            }
7755
7756            modifierValue = modifierValue.trim();
7757
7758            if(modifierValue != null && modifierValue.equals("") == false)
7759            {
7760                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7761                labelBounds = tiTemp.getTextBounds();
7762                labelWidth = labelBounds.width();
7763
7764                //on right
7765                x = (int)getLabelXPosition(bounds, labelWidth, true);
7766                //below vertical center
7767                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -1);
7768
7769                tiTemp.setLocation(x, y);
7770                tiArray.add(tiTemp);
7771
7772            }
7773        }
7774
7775
7776
7777        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS) ||
7778                modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
7779        {
7780            modifierValue = "";
7781            String mg = "",
7782                    mh = "";
7783
7784            if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
7785            {
7786                mg += modifiers.get(Modifiers.G_STAFF_COMMENTS);
7787            }
7788
7789            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
7790            {
7791                mh += modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
7792            }
7793
7794            modifierValue = mg + " " + mh;
7795
7796            modifierValue = modifierValue.trim();
7797
7798            if(modifierValue.equals("")==false)
7799            {
7800                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7801                labelBounds = tiTemp.getTextBounds();
7802                labelWidth = labelBounds.width();
7803
7804                //on right
7805                x = (int)getLabelXPosition(bounds, labelWidth, true);
7806                //below P
7807                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -2);
7808
7809                tiTemp.setLocation(x, y);
7810                tiArray.add(tiTemp);
7811
7812            }
7813        }
7814
7815
7816        if (modifiers.containsKey(Modifiers.Y_LOCATION)
7817                || modifiers.containsKey(Modifiers.Z_SPEED))//
7818        {
7819            modifierValue = null;
7820
7821            String ym = "",
7822                    zm = "";
7823
7824            if (modifiers.containsKey(Modifiers.Y_LOCATION))
7825            {
7826                ym = modifiers.get(Modifiers.Y_LOCATION);
7827            }
7828            if (modifiers.containsKey(Modifiers.Z_SPEED))
7829            {
7830                zm = modifiers.get(Modifiers.Z_SPEED);
7831            }
7832
7833            modifierValue = ym + " " + zm;
7834
7835            modifierValue = modifierValue.trim();
7836
7837
7838            if (modifierValue.length() > 2 && modifierValue.charAt(0) == ' ')
7839            {
7840                modifierValue = modifierValue.substring(1);
7841            }
7842
7843            modifierValue = modifierValue.trim();
7844
7845            if(modifierValue.equals("")==false)
7846            {
7847                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7848                labelBounds = tiTemp.getTextBounds();
7849                labelWidth = labelBounds.width();
7850
7851                //on right
7852                x = (int)getLabelXPosition(bounds, labelWidth, true);
7853                //below G/H
7854                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -3);
7855
7856
7857                tiTemp.setLocation(x, y);
7858                tiArray.add(tiTemp);
7859
7860            }
7861
7862        }
7863
7864        if (modifiers.containsKey(Modifiers.AR_SPECIAL_DESIGNATOR))
7865        {
7866            modifierValue = modifiers.get(Modifiers.AR_SPECIAL_DESIGNATOR);
7867
7868            if(modifierValue != null)
7869            {
7870                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7871                labelBounds = tiTemp.getTextBounds();
7872                labelWidth = labelBounds.width();
7873
7874                /*//on left
7875                x = bounds.left - labelWidth - bufferXL;
7876                //oppoiste AS unless that's higher than the top of the symbol
7877                y = (int)(bounds.top + ((bounds.height() / 2) - bufferText - descent - (labelHeight * 2)));
7878                if(y <= bounds.top + labelHeight)
7879                {
7880                    y = (int)bounds.top + labelHeight - descent;
7881                }//*/
7882
7883                //on left
7884                x = (int)getLabelXPosition(bounds, labelWidth, false);
7885                //below top left
7886                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
7887
7888
7889                tiTemp.setLocation(x, y);
7890                tiArray.add(tiTemp);
7891            }
7892        }
7893
7894        if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
7895        {
7896            modifierValue = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
7897
7898            if(modifierValue != null && !modifierValue.equals(""))
7899            {
7900                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7901                labelBounds = tiTemp.getTextBounds();
7902                labelWidth = (int)labelBounds.width();
7903
7904                //on left
7905                x = (int)getLabelXPosition(bounds, labelWidth, false);
7906                //below top left
7907                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
7908
7909                tiTemp.setLocation(x, y);
7910                tiArray.add(tiTemp);
7911
7912            }
7913        }
7914
7915        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
7916                modifiers.containsKey(Modifiers.AS_COUNTRY))
7917        {
7918            modifierValue = null;
7919            String E = null,
7920                    AS = null;
7921
7922            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
7923            {
7924                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
7925                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
7926            }
7927            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
7928            {
7929                AS = modifiers.get(Modifiers.AS_COUNTRY);
7930            }
7931
7932
7933            if (E != null && E.equals("") == false)
7934            {
7935                modifierValue = E;
7936            }
7937
7938            if (AS != null && AS.equals("") == false)
7939            {
7940                if (modifierValue != null && modifierValue.equals("") == false)
7941                {
7942                    modifierValue = modifierValue + " " + AS;
7943                }
7944                else
7945                {
7946                    modifierValue = AS;
7947                }
7948            }
7949
7950            if(modifierValue != null)
7951            {
7952                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7953                labelBounds = tiTemp.getTextBounds();
7954                labelWidth = labelBounds.width();
7955
7956                //on right
7957                x = (int)getLabelXPosition(bounds, labelWidth, true);
7958                //top right
7959                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 3);
7960
7961                tiTemp.setLocation(x, y);
7962                tiArray.add(tiTemp);
7963            }
7964        }
7965
7966        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
7967        {
7968            modifierValue = null;
7969
7970            if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
7971            {
7972                modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
7973            }
7974
7975            if(modifierValue != null && modifierValue.equals("") == false)
7976            {
7977                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
7978                labelBounds = tiTemp.getTextBounds();
7979                labelWidth = labelBounds.width();
7980
7981                //on right
7982                x = (int)getLabelXPosition(bounds, labelWidth, true);
7983                //top right
7984                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
7985
7986                tiTemp.setLocation(x, y);
7987                tiArray.add(tiTemp);
7988
7989            }
7990        }
7991
7992
7993        // </editor-fold>
7994
7995        //Shift Points and Draw
7996        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
7997
7998        // <editor-fold defaultstate="collapsed" desc="Cleanup">
7999        tiArray = null;
8000        tiTemp = null;
8001        //tempShape = null;
8002        //ctx = null;
8003        //buffer = null;
8004        // </editor-fold>
8005
8006        return newsdi;
8007    }
8008
8009    public static SymbolDimensionInfo  processActivitiesTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
8010    {
8011        int bufferXL = 7;
8012        int bufferXR = 7;
8013        int bufferY = 2;
8014        int bufferText = 2;
8015        int x = 0;
8016        int y = 0;//best y
8017        SymbolDimensionInfo newsdi = null;
8018
8019        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
8020
8021        int descent = (int) (_modifierFontDescent + 0.5);
8022
8023        Rect labelBounds = null;
8024        int labelWidth, labelHeight;
8025
8026        Rect bounds = new Rect(sdi.getSymbolBounds());
8027        Rect imageBounds = new Rect(sdi.getImageBounds());
8028
8029        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
8030        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
8031
8032        labelHeight = (int) (_modifierFontHeight + 0.5);
8033
8034        //Affiliation Modifier being drawn as a display modifier
8035        String affiliationModifier = null;
8036        if (RS.getDrawAffiliationModifierAsLabel() == true)
8037        {
8038            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
8039        }
8040        if (affiliationModifier != null)
8041        {   //Set affiliation modifier
8042            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
8043            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
8044        }//*/
8045
8046        //Check for Valid Country Code
8047        int cc = SymbolID.getCountryCode(symbolID);
8048        String scc = "";
8049        if(cc > 0)
8050        {
8051            scc = GENCLookup.getInstance().get3CharCode(cc);
8052        }
8053        if(!scc.isEmpty())
8054            modifiers.put(Modifiers.AS_COUNTRY, scc);
8055
8056        //            int y0 = 0;//W            E/AS
8057        //            int y1 = 0;//Y            G
8058        //            int y2 =                  H
8059        //            int y3 = 0;//             J
8060        //            int y4 = 0;//
8061        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
8062        String modifierValue = null;
8063        TextInfo tiTemp = null;
8064
8065
8066        if (modifiers.containsKey(Modifiers.Y_LOCATION))
8067        {
8068            modifierValue = null;
8069
8070            if (modifiers.containsKey(Modifiers.Y_LOCATION))
8071            {
8072                modifierValue = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
8073            }
8074
8075            if(modifierValue != null)
8076            {
8077                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8078                labelBounds = tiTemp.getTextBounds();
8079                labelWidth = labelBounds.width();
8080
8081                //on left
8082                x = (int)getLabelXPosition(bounds, labelWidth, false);
8083                //above center
8084                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 1);
8085
8086                tiTemp.setLocation(x, y);
8087                tiArray.add(tiTemp);
8088            }
8089        }
8090
8091        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
8092        {
8093            modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
8094
8095            if(modifierValue != null)
8096            {
8097                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8098                labelBounds = tiTemp.getTextBounds();
8099                labelWidth = labelBounds.width();
8100
8101                //on right
8102                x = (int)getLabelXPosition(bounds, labelWidth, true);
8103                //above center
8104                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 1);
8105
8106                tiTemp.setLocation(x, y);
8107                tiArray.add(tiTemp);
8108
8109            }
8110        }
8111
8112
8113        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
8114        {
8115            modifierValue = null;
8116
8117            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
8118            {
8119                modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
8120            }
8121
8122            if(modifierValue != null && modifierValue.equals("") == false)
8123            {
8124                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8125                labelBounds = tiTemp.getTextBounds();
8126                labelWidth = labelBounds.width();
8127
8128                //on right
8129                x = (int)getLabelXPosition(bounds, labelWidth, true);
8130                //below center
8131                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -1);
8132
8133                tiTemp.setLocation(x, y);
8134                tiArray.add(tiTemp);
8135
8136            }
8137        }
8138
8139        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))//
8140        {
8141            modifierValue = null;
8142
8143            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
8144            {
8145                modifierValue = modifiers.get(Modifiers.J_EVALUATION_RATING);
8146            }
8147
8148
8149            if(modifierValue.equals("")==false)
8150            {
8151                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8152                labelBounds = tiTemp.getTextBounds();
8153                labelWidth = labelBounds.width();
8154
8155                //on right
8156                x = (int)getLabelXPosition(bounds, labelWidth, true);
8157                //below H
8158                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, -2);
8159
8160
8161                tiTemp.setLocation(x, y);
8162                tiArray.add(tiTemp);
8163
8164            }
8165
8166        }
8167
8168        if (modifiers.containsKey(Modifiers.W_DTG_1))
8169        {
8170            modifierValue = modifiers.get(Modifiers.W_DTG_1);
8171
8172            if(modifierValue != null)
8173            {
8174                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8175                labelBounds = tiTemp.getTextBounds();
8176                labelWidth = labelBounds.width();
8177
8178                //on left
8179                x = (int)getLabelXPosition(bounds, labelWidth, false);
8180                //above Y
8181                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
8182
8183
8184                tiTemp.setLocation(x, y);
8185                tiArray.add(tiTemp);
8186            }
8187        }
8188
8189        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
8190                modifiers.containsKey(Modifiers.AS_COUNTRY))
8191        {
8192            modifierValue = null;
8193            String E = "",
8194                    AS = "";
8195
8196            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
8197            {
8198                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
8199                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
8200            }
8201            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
8202            {
8203                AS = modifiers.get(Modifiers.AS_COUNTRY);
8204            }
8205
8206            modifierValue = E + " " + AS;
8207            modifierValue = modifierValue.trim();
8208
8209            if(modifierValue != null)
8210            {
8211                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8212                labelBounds = tiTemp.getTextBounds();
8213                labelWidth = labelBounds.width();
8214
8215                //on right
8216                x = (int)getLabelXPosition(bounds, labelWidth, true);
8217                //above G
8218                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, false, 2);
8219
8220
8221                tiTemp.setLocation(x, y);
8222                tiArray.add(tiTemp);
8223
8224            }
8225        }
8226
8227
8228        // </editor-fold>
8229
8230        //Shift Points and Draw
8231        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
8232
8233        // <editor-fold defaultstate="collapsed" desc="Cleanup">
8234        tiArray = null;
8235        tiTemp = null;
8236        //tempShape = null;
8237        //ctx = null;
8238        //buffer = null;
8239        // </editor-fold>
8240
8241        return newsdi;
8242    }
8243
8244    public static SymbolDimensionInfo  processActivitiesTextModifiersE(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
8245    {
8246        int bufferXL = 7;
8247        int bufferXR = 7;
8248        int bufferY = 2;
8249        int bufferText = 2;
8250        int x = 0;
8251        int y = 0;//best y
8252        SymbolDimensionInfo newsdi = null;
8253
8254
8255        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
8256
8257        int descent = (int) (_modifierFontDescent + 0.5);
8258
8259        Rect labelBounds = null;
8260        int labelWidth, labelHeight;
8261
8262        Rect bounds = new Rect(sdi.getSymbolBounds());
8263        Rect imageBounds = new Rect(sdi.getImageBounds());
8264
8265        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
8266        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
8267
8268        labelHeight = (int) (_modifierFontHeight + 0.5);
8269
8270        //Affiliation Modifier being drawn as a display modifier
8271        String affiliationModifier = null;
8272        if (RS.getDrawAffiliationModifierAsLabel() == true)
8273        {
8274            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
8275        }
8276        if (affiliationModifier != null)
8277        {   //Set affiliation modifier
8278            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
8279            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
8280        }//*/
8281
8282        //Check for Valid Country Code
8283        int cc = SymbolID.getCountryCode(symbolID);
8284        String scc = "";
8285        if(cc > 0)
8286        {
8287            scc = GENCLookup.getInstance().get3CharCode(cc);
8288        }
8289        if(!scc.isEmpty())
8290            modifiers.put(Modifiers.AS_COUNTRY, scc);
8291
8292        //            int y0 = 0;//W            E/AS
8293        //            int y1 = 0;//Y            T
8294        //            int y2 =                  G
8295        //            int y3 = 0;//             H
8296        //            int y4 = 0;//             J
8297        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
8298        String modifierValue = null;
8299        TextInfo tiTemp = null;
8300
8301
8302        if (modifiers.containsKey(Modifiers.Y_LOCATION))
8303        {
8304            modifierValue = null;
8305
8306            if (modifiers.containsKey(Modifiers.Y_LOCATION))
8307            {
8308                modifierValue = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
8309            }
8310
8311            if(modifierValue != null)
8312            {
8313                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8314                labelBounds = tiTemp.getTextBounds();
8315                labelWidth = labelBounds.width();
8316
8317                //on left
8318                x = (int)getLabelXPosition(bounds, labelWidth, false);
8319                //above vertical center
8320                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
8321
8322                tiTemp.setLocation(x, y);
8323                tiArray.add(tiTemp);
8324            }
8325        }
8326
8327        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
8328        {
8329            modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
8330
8331            if(modifierValue != null)
8332            {
8333                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8334                labelBounds = tiTemp.getTextBounds();
8335                labelWidth = (int)labelBounds.width();
8336
8337                //on right
8338                x = (int)getLabelXPosition(bounds, labelWidth, true);
8339                //above vertical center
8340                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
8341
8342                tiTemp.setLocation(x, y);
8343                tiArray.add(tiTemp);
8344
8345            }
8346        }
8347
8348        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
8349        {
8350            modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
8351
8352            if(modifierValue != null)
8353            {
8354                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8355                labelBounds = tiTemp.getTextBounds();
8356                labelWidth = labelBounds.width();
8357
8358                //on right
8359                x = (int)getLabelXPosition(bounds, labelWidth, true);
8360                //above vertical center
8361                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
8362
8363                tiTemp.setLocation(x, y);
8364                tiArray.add(tiTemp);
8365
8366            }
8367        }
8368
8369
8370        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
8371        {
8372            modifierValue = null;
8373
8374            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
8375            {
8376                modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
8377            }
8378
8379            if(modifierValue != null && modifierValue.equals("") == false)
8380            {
8381                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8382                labelBounds = tiTemp.getTextBounds();
8383                labelWidth = labelBounds.width();
8384
8385                //on right
8386                x = (int)getLabelXPosition(bounds, labelWidth, true);
8387                //below G
8388                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
8389
8390                tiTemp.setLocation(x, y);
8391                tiArray.add(tiTemp);
8392
8393            }
8394        }
8395
8396        if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))//
8397        {
8398            modifierValue = null;
8399
8400            if (modifiers.containsKey(Modifiers.J_EVALUATION_RATING))
8401            {
8402                modifierValue = modifiers.get(Modifiers.J_EVALUATION_RATING);
8403            }
8404
8405
8406            if(modifierValue.equals("")==false)
8407            {
8408                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8409                labelBounds = tiTemp.getTextBounds();
8410                labelWidth = labelBounds.width();
8411
8412                //on right
8413                x = (int)getLabelXPosition(bounds, labelWidth, true);
8414                //below H
8415                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
8416
8417
8418                tiTemp.setLocation(x, y);
8419                tiArray.add(tiTemp);
8420
8421            }
8422
8423        }
8424
8425        if (modifiers.containsKey(Modifiers.W_DTG_1))
8426        {
8427            modifierValue = modifiers.get(Modifiers.W_DTG_1);
8428
8429            if(modifierValue != null)
8430            {
8431                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8432                labelBounds = tiTemp.getTextBounds();
8433                labelWidth = labelBounds.width();
8434
8435                //on left
8436                x = (int)getLabelXPosition(bounds, labelWidth, false);
8437                //above Y
8438                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
8439
8440
8441                tiTemp.setLocation(x, y);
8442                tiArray.add(tiTemp);
8443            }
8444        }
8445
8446        if (modifiers.containsKey(Modifiers.C_QUANTITY))
8447        {
8448            modifierValue = modifiers.get(Modifiers.C_QUANTITY);
8449
8450            if(modifierValue != null)
8451            {
8452                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8453                labelBounds = tiTemp.getTextBounds();
8454                labelWidth = labelBounds.width();
8455
8456                //on left
8457                x = (int)getLabelXPosition(bounds, labelWidth, false);
8458                //above Y
8459                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
8460
8461
8462                tiTemp.setLocation(x, y);
8463                tiArray.add(tiTemp);
8464            }
8465        }
8466
8467        if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
8468                modifiers.containsKey(Modifiers.AS_COUNTRY))
8469        {
8470            modifierValue = null;
8471            String E = "",
8472                    AS = "";
8473
8474            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
8475            {
8476                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
8477                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
8478            }
8479            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
8480            {
8481                AS = modifiers.get(Modifiers.AS_COUNTRY);
8482            }
8483
8484            modifierValue = E + " " + AS;
8485            modifierValue = modifierValue.trim();
8486
8487            if(modifierValue != null)
8488            {
8489                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8490                labelBounds = tiTemp.getTextBounds();
8491                labelWidth = labelBounds.width();
8492
8493                //on right
8494                x = (int)getLabelXPosition(bounds, labelWidth, true);
8495                //below H
8496                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
8497
8498
8499                tiTemp.setLocation(x, y);
8500                tiArray.add(tiTemp);
8501
8502            }
8503        }
8504
8505
8506        // </editor-fold>
8507
8508        //Shift Points and Draw
8509        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
8510
8511        // <editor-fold defaultstate="collapsed" desc="Cleanup">
8512        tiArray = null;
8513        tiTemp = null;
8514        //tempShape = null;
8515        //ctx = null;
8516        //buffer = null;
8517        // </editor-fold>
8518
8519        return newsdi;
8520    }
8521
8522    public static SymbolDimensionInfo  processCyberSpaceTextModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
8523    {
8524        int bufferXL = 7;
8525        int bufferXR = 7;
8526        int bufferY = 2;
8527        int bufferText = 2;
8528        int x = 0;
8529        int y = 0;//best y
8530        SymbolDimensionInfo newsdi = null;
8531
8532        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
8533
8534        int descent = (int) (_modifierFontDescent + 0.5);
8535
8536        Rect labelBounds = null;
8537        int labelWidth, labelHeight;
8538
8539        Rect bounds = new Rect(sdi.getSymbolBounds());
8540        Rect imageBounds = new Rect(sdi.getImageBounds());
8541
8542        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
8543        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
8544
8545        labelHeight = (int) (_modifierFontHeight + 0.5);
8546
8547        //Affiliation Modifier being drawn as a display modifier
8548        String affiliationModifier = null;
8549        if (RS.getDrawAffiliationModifierAsLabel() == true)
8550        {
8551            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
8552        }
8553        if (affiliationModifier != null)
8554        {   //Set affiliation modifier
8555            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
8556            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
8557        }//*/
8558
8559        //Check for Valid Country Code
8560        int cc = SymbolID.getCountryCode(symbolID);
8561        String scc = "";
8562        if(cc > 0)
8563        {
8564            scc = GENCLookup.getInstance().get3CharCode(cc);
8565        }
8566        if(!scc.isEmpty())
8567            modifiers.put(Modifiers.AS_COUNTRY, scc);
8568
8569        //            int y0 = 0;//W            E/F/AS
8570        //            int y1 = 0;//Y            G
8571        //            int y2 =     V            H
8572        //            int y3 = 0;//T            M
8573        //            int y4 = 0;//             K/L
8574        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
8575        String modifierValue = null;
8576        TextInfo tiTemp = null;
8577
8578
8579        if (modifiers.containsKey(Modifiers.Y_LOCATION))
8580        {
8581            modifierValue = null;
8582
8583            if (modifiers.containsKey(Modifiers.Y_LOCATION))
8584            {
8585                modifierValue = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
8586            }
8587
8588            if(modifierValue != null)
8589            {
8590                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8591                labelBounds = tiTemp.getTextBounds();
8592                labelWidth = labelBounds.width();
8593
8594                //on left
8595                x = (int)getLabelXPosition(bounds, labelWidth, false);
8596                //above center V
8597                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
8598
8599                tiTemp.setLocation(x, y);
8600                tiArray.add(tiTemp);
8601            }
8602        }
8603
8604        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
8605        {
8606            modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
8607
8608            if(modifierValue != null)
8609            {
8610                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8611                labelBounds = tiTemp.getTextBounds();
8612                labelWidth = labelBounds.width();
8613
8614                //on right
8615                x = (int)getLabelXPosition(bounds, labelWidth, true);
8616                //above center V
8617                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
8618
8619                tiTemp.setLocation(x, y);
8620                tiArray.add(tiTemp);
8621
8622            }
8623        }
8624
8625
8626        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
8627        {
8628            modifierValue = null;
8629
8630            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
8631            {
8632                modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
8633            }
8634
8635            if(modifierValue != null && modifierValue.equals("") == false)
8636            {
8637                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8638                labelBounds = tiTemp.getTextBounds();
8639                labelWidth = labelBounds.width();
8640
8641                //on right
8642                x = (int)getLabelXPosition(bounds, labelWidth, true);
8643                //center
8644                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
8645
8646                tiTemp.setLocation(x, y);
8647                tiArray.add(tiTemp);
8648
8649            }
8650        }
8651
8652        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) ||
8653                modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
8654        {
8655            String tm = null,
8656                    vm = null;
8657
8658            if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
8659            {
8660                tm = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
8661            }
8662            if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
8663            {
8664                vm = modifiers.get(Modifiers.V_EQUIP_TYPE);
8665            }
8666
8667            modifierValue = tm + " " + vm;
8668            modifierValue = modifierValue.trim();
8669
8670            if(modifierValue != null)
8671            {
8672                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8673                labelBounds = tiTemp.getTextBounds();
8674                labelWidth = labelBounds.width();
8675
8676                //on left
8677                x = (int)getLabelXPosition(bounds, labelWidth, false);
8678                //below center V
8679                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
8680
8681
8682                tiTemp.setLocation(x, y);
8683                tiArray.add(tiTemp);
8684            }
8685        }
8686
8687        if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
8688        {
8689            modifierValue = "";
8690
8691            if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
8692            {
8693                modifierValue += modifiers.get(Modifiers.M_HIGHER_FORMATION);
8694            }
8695
8696            if(modifierValue.equals("")==false)
8697            {
8698                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8699                labelBounds = tiTemp.getTextBounds();
8700                labelWidth = labelBounds.width();
8701
8702                //on right
8703                x = (int)getLabelXPosition(bounds, labelWidth, true);
8704                //below center H
8705                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
8706
8707                tiTemp.setLocation(x, y);
8708                tiArray.add(tiTemp);
8709
8710            }
8711        }
8712
8713        if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
8714                || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP))//
8715        {
8716            modifierValue = null;
8717
8718            String km = null,
8719                    lm = null;
8720
8721            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS))
8722            {
8723                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
8724            }
8725            if (modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP))
8726            {
8727                lm = modifiers.get(Modifiers.L_SIGNATURE_EQUIP);
8728            }
8729
8730            modifierValue = km + " " + lm;
8731            modifierValue = modifierValue.trim();
8732
8733            if(modifierValue.equals("")==false)
8734            {
8735                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8736                labelBounds = tiTemp.getTextBounds();
8737                labelWidth = labelBounds.width();
8738
8739                //on right
8740                x = (int)getLabelXPosition(bounds, labelWidth, true);
8741                //below M
8742                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
8743
8744
8745                tiTemp.setLocation(x, y);
8746                tiArray.add(tiTemp);
8747
8748            }
8749
8750        }
8751
8752        if (modifiers.containsKey(Modifiers.W_DTG_1))
8753        {
8754            modifierValue = modifiers.get(Modifiers.W_DTG_1);
8755
8756            if(modifierValue != null)
8757            {
8758                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8759                labelBounds = tiTemp.getTextBounds();
8760                labelWidth = labelBounds.width();
8761
8762                //on left
8763                x = (int)getLabelXPosition(bounds, labelWidth, false);
8764                //above Y
8765                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
8766
8767
8768                tiTemp.setLocation(x, y);
8769                tiArray.add(tiTemp);
8770            }
8771        }
8772
8773        if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) ||
8774                modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
8775                modifiers.containsKey(Modifiers.AS_COUNTRY))
8776        {
8777            modifierValue = null;
8778            String E = null,
8779                    F = null,
8780                    AS = null;
8781
8782            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
8783            {
8784                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
8785                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
8786            }
8787            if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED))
8788            {
8789                F = modifiers.get(Modifiers.F_REINFORCED_REDUCED);
8790            }
8791            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
8792            {
8793                AS = modifiers.get(Modifiers.AS_COUNTRY);
8794            }
8795
8796            if (E != null && E.equals("") == false)
8797            {
8798                modifierValue = E;
8799            }
8800
8801            if (F != null && F.equals("") == false)
8802            {
8803                if (F.toUpperCase(Locale.US) == ("R"))
8804                {
8805                    F = "(+)";
8806                }
8807                else if (F.toUpperCase(Locale.US) == ("D"))
8808                {
8809                    F = "(-)";
8810                }
8811                else if (F.toUpperCase(Locale.US) == ("RD"))
8812                {
8813                    F = "(" + (char) (177) + ")";
8814                }
8815            }
8816
8817            if (F != null && F.equals("") == false)
8818            {
8819                if (modifierValue != null && modifierValue.equals("") == false)
8820                {
8821                    modifierValue = modifierValue + " " + F;
8822                }
8823                else
8824                {
8825                    modifierValue = F;
8826                }
8827            }
8828
8829            if (AS != null && AS.equals("") == false)
8830            {
8831                if (modifierValue != null && modifierValue.equals("") == false)
8832                {
8833                    modifierValue = modifierValue + " " + AS;
8834                }
8835                else
8836                {
8837                    modifierValue = AS;
8838                }
8839            }
8840
8841            if(modifierValue != null)
8842            {
8843                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8844                labelBounds = tiTemp.getTextBounds();
8845                labelWidth = labelBounds.width();
8846
8847                //on right
8848                x = (int)getLabelXPosition(bounds, labelWidth, true);
8849                //top right
8850                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
8851
8852
8853                tiTemp.setLocation(x, y);
8854                tiArray.add(tiTemp);
8855
8856            }
8857        }
8858
8859
8860
8861        // </editor-fold>
8862
8863        //Shift Points and Draw
8864        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
8865
8866        // <editor-fold defaultstate="collapsed" desc="Cleanup">
8867        tiArray = null;
8868        tiTemp = null;
8869        //tempShape = null;
8870        //ctx = null;
8871        //buffer = null;
8872        // </editor-fold>
8873
8874        return newsdi;
8875    }
8876
8877    public static SymbolDimensionInfo  processCyberSpaceTextModifiersE(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes)
8878    {
8879        int bufferXL = 7;
8880        int bufferXR = 7;
8881        int bufferY = 2;
8882        int bufferText = 2;
8883        int x = 0;
8884        int y = 0;//best y
8885        SymbolDimensionInfo newsdi = null;
8886
8887        ArrayList<TextInfo> tiArray = new ArrayList<TextInfo>(modifiers.size());
8888
8889        int descent = (int) (_modifierFontDescent + 0.5);
8890
8891        Rect labelBounds = null;
8892        int labelWidth, labelHeight;
8893
8894        Rect bounds = new Rect(sdi.getSymbolBounds());
8895        Rect imageBounds = new Rect(sdi.getImageBounds());
8896
8897        //adjust width of bounds for mobility/echelon/engagement bar which could be wider than the symbol
8898        bounds = RectUtilities.makeRect(imageBounds.left, bounds.top, imageBounds.width(), bounds.height());
8899
8900        labelHeight = (int) (_modifierFontHeight + 0.5);
8901
8902        //Affiliation Modifier being drawn as a display modifier
8903        String affiliationModifier = null;
8904        if (RS.getDrawAffiliationModifierAsLabel() == true)
8905        {
8906            affiliationModifier = SymbolUtilities.getStandardIdentityModifier(symbolID);
8907        }
8908        if (affiliationModifier != null)
8909        {   //Set affiliation modifier
8910            modifiers.put(Modifiers.E_FRAME_SHAPE_MODIFIER, affiliationModifier);
8911            //modifiers[Modifiers.E_FRAME_SHAPE_MODIFIER] = affiliationModifier;
8912        }//*/
8913
8914        //Check for Valid Country Code
8915        int cc = SymbolID.getCountryCode(symbolID);
8916        String scc = "";
8917        if(cc > 0)
8918        {
8919            scc = GENCLookup.getInstance().get3CharCode(cc);
8920        }
8921        if(!scc.isEmpty())
8922            modifiers.put(Modifiers.AS_COUNTRY, scc);
8923
8924        //            int y0 = 0;//W            E/F/AS
8925        //            int y1 = 0;//Y            G
8926        //            int y2 =     V            H
8927        //            int y3 = 0;//T            M
8928        //            int y4 = 0;//             K/L
8929        // <editor-fold defaultstate="collapsed" desc="Build Modifiers">
8930        String modifierValue = null;
8931        TextInfo tiTemp = null;
8932
8933
8934        if (modifiers.containsKey(Modifiers.Y_LOCATION))
8935        {
8936            modifierValue = null;
8937
8938            if (modifiers.containsKey(Modifiers.Y_LOCATION))
8939            {
8940                modifierValue = modifiers.get(Modifiers.Y_LOCATION);// ym = modifiers.Y;
8941            }
8942
8943            if(modifierValue != null)
8944            {
8945                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8946                labelBounds = tiTemp.getTextBounds();
8947                labelWidth = labelBounds.width();
8948
8949                //on left
8950                x = (int)getLabelXPosition(bounds, labelWidth, false);
8951                //above center V
8952                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
8953
8954                tiTemp.setLocation(x, y);
8955                tiArray.add(tiTemp);
8956            }
8957        }
8958
8959        if (modifiers.containsKey(Modifiers.G_STAFF_COMMENTS))
8960        {
8961            modifierValue = modifiers.get(Modifiers.G_STAFF_COMMENTS);
8962
8963            if(modifierValue != null)
8964            {
8965                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8966                labelBounds = tiTemp.getTextBounds();
8967                labelWidth = labelBounds.width();
8968
8969                //on right
8970                x = (int)getLabelXPosition(bounds, labelWidth, true);
8971                //above center V
8972                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 1);
8973
8974                tiTemp.setLocation(x, y);
8975                tiArray.add(tiTemp);
8976
8977            }
8978        }
8979
8980
8981        if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
8982        {
8983            modifierValue = null;
8984
8985            if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
8986            {
8987                modifierValue = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
8988            }
8989
8990            if(modifierValue != null && modifierValue.equals("") == false)
8991            {
8992                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
8993                labelBounds = tiTemp.getTextBounds();
8994                labelWidth = labelBounds.width();
8995
8996                //on right
8997                x = (int)getLabelXPosition(bounds, labelWidth, true);
8998                //center
8999                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
9000
9001                tiTemp.setLocation(x, y);
9002                tiArray.add(tiTemp);
9003
9004            }
9005        }
9006
9007        if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
9008        {
9009            modifierValue = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9010
9011            if(modifierValue != null)
9012            {
9013                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
9014                labelBounds = tiTemp.getTextBounds();
9015                labelWidth = labelBounds.width();
9016
9017                //on left
9018                x = (int)getLabelXPosition(bounds, labelWidth, false);
9019                //below center V
9020                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
9021
9022
9023                tiTemp.setLocation(x, y);
9024                tiArray.add(tiTemp);
9025            }
9026        }
9027
9028        if (modifiers.containsKey(Modifiers.V_EQUIP_TYPE))
9029        {
9030            modifierValue = modifiers.get(Modifiers.V_EQUIP_TYPE);
9031
9032            if(modifierValue != null)
9033            {
9034                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
9035                labelBounds = tiTemp.getTextBounds();
9036                labelWidth = labelBounds.width();
9037
9038                //on left
9039                x = (int)getLabelXPosition(bounds, labelWidth, false);
9040                //below center V
9041                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 0);
9042
9043
9044                tiTemp.setLocation(x, y);
9045                tiArray.add(tiTemp);
9046            }
9047        }
9048
9049        if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
9050        {
9051            modifierValue = "";
9052
9053            if (modifiers.containsKey(Modifiers.M_HIGHER_FORMATION))
9054            {
9055                modifierValue += modifiers.get(Modifiers.M_HIGHER_FORMATION);
9056            }
9057
9058            if(modifierValue.equals("")==false)
9059            {
9060                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
9061                labelBounds = tiTemp.getTextBounds();
9062                labelWidth = labelBounds.width();
9063
9064                //on right
9065                x = (int)getLabelXPosition(bounds, labelWidth, true);
9066                //below center H
9067                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -1);
9068
9069                tiTemp.setLocation(x, y);
9070                tiArray.add(tiTemp);
9071
9072            }
9073        }
9074
9075        if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS)//
9076                || modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP))//
9077        {
9078            modifierValue = null;
9079
9080            String km = null,
9081                    lm = null;
9082
9083            if (modifiers.containsKey(Modifiers.K_COMBAT_EFFECTIVENESS))
9084            {
9085                km = modifiers.get(Modifiers.K_COMBAT_EFFECTIVENESS);
9086            }
9087            if (modifiers.containsKey(Modifiers.L_SIGNATURE_EQUIP))
9088            {
9089                lm = modifiers.get(Modifiers.L_SIGNATURE_EQUIP);
9090            }
9091
9092            modifierValue = km + " " + lm;
9093            modifierValue = modifierValue.trim();
9094
9095            if(modifierValue.equals("")==false)
9096            {
9097                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
9098                labelBounds = tiTemp.getTextBounds();
9099                labelWidth = labelBounds.width();
9100
9101                //on right
9102                x = (int)getLabelXPosition(bounds, labelWidth, true);
9103                //below M
9104                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, -2);
9105
9106
9107                tiTemp.setLocation(x, y);
9108                tiArray.add(tiTemp);
9109
9110            }
9111
9112        }
9113
9114        if (modifiers.containsKey(Modifiers.W_DTG_1))
9115        {
9116            modifierValue = modifiers.get(Modifiers.W_DTG_1);
9117
9118            if(modifierValue != null)
9119            {
9120                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
9121                labelBounds = tiTemp.getTextBounds();
9122                labelWidth = labelBounds.width();
9123
9124                //on left
9125                x = (int)getLabelXPosition(bounds, labelWidth, false);
9126                //above Y
9127                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
9128
9129
9130                tiTemp.setLocation(x, y);
9131                tiArray.add(tiTemp);
9132            }
9133        }
9134
9135        if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED) ||
9136                modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER) ||
9137                modifiers.containsKey(Modifiers.AS_COUNTRY))
9138        {
9139            modifierValue = null;
9140            String E = null,
9141                    F = null,
9142                    AS = null;
9143
9144            if (modifiers.containsKey(Modifiers.E_FRAME_SHAPE_MODIFIER))
9145            {
9146                E = modifiers.get(Modifiers.E_FRAME_SHAPE_MODIFIER);
9147                modifiers.remove(Modifiers.E_FRAME_SHAPE_MODIFIER);
9148            }
9149            if (modifiers.containsKey(Modifiers.F_REINFORCED_REDUCED))
9150            {
9151                F = modifiers.get(Modifiers.F_REINFORCED_REDUCED);
9152            }
9153            if (modifiers.containsKey(Modifiers.AS_COUNTRY))
9154            {
9155                AS = modifiers.get(Modifiers.AS_COUNTRY);
9156            }
9157
9158            if (E != null && E.equals("") == false)
9159            {
9160                modifierValue = E;
9161            }
9162
9163            if (F != null && F.equals("") == false)
9164            {
9165                if (F.toUpperCase(Locale.US) == ("R"))
9166                {
9167                    F = "(+)";
9168                }
9169                else if (F.toUpperCase(Locale.US) == ("D"))
9170                {
9171                    F = "(-)";
9172                }
9173                else if (F.toUpperCase(Locale.US) == ("RD"))
9174                {
9175                    F = "(" + (char) (177) + ")";
9176                }
9177            }
9178
9179            if (F != null && F.equals("") == false)
9180            {
9181                if (modifierValue != null && modifierValue.equals("") == false)
9182                {
9183                    modifierValue = modifierValue + " " + F;
9184                }
9185                else
9186                {
9187                    modifierValue = F;
9188                }
9189            }
9190
9191            if (AS != null && AS.equals("") == false)
9192            {
9193                if (modifierValue != null && modifierValue.equals("") == false)
9194                {
9195                    modifierValue = modifierValue + " " + AS;
9196                }
9197                else
9198                {
9199                    modifierValue = AS;
9200                }
9201            }
9202
9203            if(modifierValue != null)
9204            {
9205                tiTemp = new TextInfo(modifierValue, 0, 0, _modifierFont);
9206                labelBounds = tiTemp.getTextBounds();
9207                labelWidth = labelBounds.width();
9208
9209                //on right
9210                x = (int)getLabelXPosition(bounds, labelWidth, true);
9211                //top right
9212                y = (int)getLabelYPosition(bounds, labelHeight, descent, bufferText, true, 2);
9213
9214
9215                tiTemp.setLocation(x, y);
9216                tiArray.add(tiTemp);
9217
9218            }
9219        }
9220
9221
9222
9223        // </editor-fold>
9224
9225        //Shift Points and Draw
9226        newsdi = shiftUnitPointsAndDraw(tiArray,sdi,attributes);
9227
9228        // <editor-fold defaultstate="collapsed" desc="Cleanup">
9229        tiArray = null;
9230        tiTemp = null;
9231        //tempShape = null;
9232        //ctx = null;
9233        //buffer = null;
9234        // </editor-fold>
9235
9236        return newsdi;
9237    }
9238
9239    public static SymbolDimensionInfo ProcessTGSPWithSpecialModifierLayout(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes, Color lineColor)
9240    {
9241        ImageInfo ii = null;
9242        SVGSymbolInfo ssi = null;
9243
9244        int bufferXL = 6;
9245        int bufferXR = 4;
9246        int bufferY = 2;
9247        int bufferText = 2;
9248        int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel
9249        int x = 0;
9250        int y = 0;
9251        int x2 = 0;
9252        int y2 = 0;
9253
9254        int outlineOffset = RS.getTextOutlineWidth();
9255        int labelHeight = 0;
9256        int labelWidth = 0;
9257        int alpha = -1;
9258        SymbolDimensionInfo newsdi = null;
9259        Color textColor = lineColor;
9260        Color textBackgroundColor = null;
9261        int ss = SymbolID.getSymbolSet(symbolID);
9262        int ec = SymbolID.getEntityCode(symbolID);
9263        int e = SymbolID.getEntity(symbolID);
9264        int et = SymbolID.getEntityType(symbolID);
9265        int est = SymbolID.getEntitySubtype(symbolID);
9266
9267        //Feint Dummy Indicator variables
9268        Rect fdiBounds = null;
9269        Point fdiTop = null;
9270        Point fdiLeft = null;
9271        Point fdiRight = null;
9272
9273        ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>();
9274        boolean duplicate = false;
9275
9276        Rect bounds = new Rect(sdi.getSymbolBounds());
9277        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
9278        Point centerPoint = new Point(sdi.getCenterPoint());
9279        Rect imageBounds = new Rect(sdi.getImageBounds());
9280
9281        if (attributes.containsKey(MilStdAttributes.Alpha))
9282        {
9283            alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha));
9284            textColor.setAlpha(alpha);
9285        }
9286
9287        centerPoint = new Point(Math.round(sdi.getCenterPoint().x), Math.round(sdi.getCenterPoint().y));
9288
9289        boolean byLabelHeight = false;
9290        labelHeight = (int) (_modifierFontHeight + 0.5f);
9291
9292        int maxHeight = (symbolBounds.height());
9293        if ((labelHeight * 3) > maxHeight)
9294        {
9295            byLabelHeight = true;
9296        }
9297
9298        int descent = (int) (_modifierFontDescent + 0.5f);
9299        int yForY = -1;
9300
9301        Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0);
9302        Rect labelBounds2 = null;
9303        String strText = "";
9304        String strText1 = "";
9305        String strText2 = "";
9306        TextInfo text1 = null;
9307        TextInfo text2 = null;
9308
9309
9310        if (outlineOffset > 2)
9311        {
9312            outlineOffset = ((outlineOffset - 1) / 2);
9313        }
9314        else
9315        {
9316            outlineOffset = 0;
9317        }
9318
9319
9320        // <editor-fold defaultstate="collapsed" desc="Process Special Modifiers">
9321        TextInfo ti = null;
9322        if (SymbolUtilities.isCBRNEvent(symbolID))//chemical
9323        {
9324            if ((labelHeight * 3) > bounds.height())
9325            {
9326                byLabelHeight = true;
9327            }
9328        }
9329
9330        if(ss == SymbolID.SymbolSet_ControlMeasure) {
9331            if (ec == 130500 //contact point
9332                    || ec == 130700) //decision point
9333            {
9334                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9335                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9336                    if (strText != null) {
9337                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9338                        labelWidth = Math.round(ti.getTextBounds().width());
9339                        //One modifier symbols and modifier goes in center
9340                        x = bounds.left + (int) (bounds.width() * 0.5f);
9341                        x = x - (int) (labelWidth * 0.5f);
9342                        y = bounds.top + (int) (bounds.height() * 0.4f);
9343                        y = y + (int) (labelHeight * 0.5f);
9344
9345                        ti.setLocation(Math.round(x), Math.round(y));
9346                        arrMods.add(ti);
9347                    }
9348                }
9349            } else if (ec == 212800)//harbor
9350            {
9351                if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) {
9352                    strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
9353                    if (strText != null) {
9354                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9355                        labelWidth = Math.round(ti.getTextBounds().width());
9356                        //One modifier symbols and modifier goes in center
9357                        x = bounds.left + (int) (bounds.width() * 0.5f);
9358                        x = x - (int) (labelWidth * 0.5f);
9359                        y = bounds.top + (int) (bounds.height() * 0.5f);
9360                        y = y + (int) (labelHeight * 0.5f);
9361
9362                        ti.setLocation(Math.round(x), Math.round(y));
9363                        arrMods.add(ti);
9364                    }
9365                }
9366            } else if (ec == 131300)//point of interest
9367            {
9368                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9369                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9370                    if (strText != null) {
9371                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9372                        labelWidth = Math.round(ti.getTextBounds().width());
9373                        //One modifier symbols, top third & center
9374                        x = bounds.left + (int) (bounds.width() * 0.5f);
9375                        x = x - (int) (labelWidth * 0.5f);
9376                        y = bounds.top + (int) (bounds.height() * 0.25f);
9377                        y = y + (int) (labelHeight * 0.5f);
9378
9379                        ti.setLocation(Math.round(x), Math.round(y));
9380                        arrMods.add(ti);
9381                    }
9382                }
9383            } else if (ec == 131800//waypoint
9384                    || ec == 240900)//fire support station
9385            {
9386                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9387                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9388                    if (strText != null) {
9389                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9390
9391                        //One modifier symbols and modifier goes right of center
9392                        if (ec == 131800)
9393                            x = bounds.left + (int) (bounds.width() * 0.75f);
9394                        else
9395                            x = bounds.left + (bounds.width());
9396                        y = bounds.top + (int) (bounds.height() * 0.5f);
9397                        y = y + (int) ((labelHeight - descent) * 0.5f);
9398
9399                        ti.setLocation(Math.round(x), Math.round(y));
9400                        arrMods.add(ti);
9401                    }
9402                }
9403            }
9404            else if (ec == 131900)//Airfield (AEGIS Only)
9405            {
9406                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9407                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9408                    if (strText != null) {
9409                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9410
9411                        //One modifier symbols and modifier goes right of symbol
9412
9413                        x = bounds.left + (bounds.width() + bufferXR);
9414
9415                        y = bounds.top + (int) (bounds.height() * 0.5f);
9416                        y = y + (int) ((labelHeight - descent) * 0.5f);
9417
9418                        ti.setLocation(Math.round(x), Math.round(y));
9419                        arrMods.add(ti);
9420                    }
9421                }
9422            }
9423            else if (ec == 180100 //Air Control point
9424                    || ec == 180200) //Communications Check point
9425            {
9426                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9427                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9428                    if (strText != null) {
9429                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9430                        labelWidth = ti.getTextBounds().width();
9431                        //One modifier symbols and modifier goes just below of center
9432                        x = bounds.left + (int) (bounds.width() * 0.5);
9433                        x = x - (int) (labelWidth * 0.5);
9434                        y = bounds.top + (int) (bounds.height() * 0.5f);
9435                        y = y + (int) (((bounds.height() * 0.5f) - labelHeight) / 2) + labelHeight - descent;
9436
9437                        ti.setLocation(Math.round(x), Math.round(y));
9438                        arrMods.add(ti);
9439                    }
9440                }
9441            } else if (ec == 160300 || //T (target reference point)
9442                    ec == 132000 || //T (Target Handover)
9443                    ec == 240601 || //ap,ap1,x,h (Point/Single Target)
9444                    ec == 240602) //ap (nuclear target)
9445            { //Targets with special modifier positions
9446                if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)
9447                        && ec == 240601)//H //point single target
9448                {
9449                    strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
9450                    if (strText != null) {
9451                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9452
9453                        x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f);
9454                        y = bounds.top + (int) (bounds.height() * 0.75f);
9455                        y = y + (int) (labelHeight * 0.5f);
9456
9457                        ti.setLocation(Math.round(x), Math.round(y));
9458                        arrMods.add(ti);
9459                    }
9460                }
9461                if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)
9462                        && ec == 240601)//X point or single target
9463                {
9464                    strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
9465                    if (strText != null) {
9466                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9467                        labelWidth = Math.round(ti.getTextBounds().width());
9468                        x = RectUtilities.getCenterX(bounds) - (int) (bounds.width() * 0.15f);
9469                        x = x - (labelWidth);
9470                        y = bounds.top + (int) (bounds.height() * 0.75f);
9471                        y = y + (int) (labelHeight * 0.5f);
9472
9473                        ti.setLocation(Math.round(x), Math.round(y));
9474                        arrMods.add(ti);
9475                    }
9476                }
9477                strText = null;
9478                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1) && (ec == 160300 || ec == 132000)) {
9479                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9480                    if (strText != null) {
9481                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9482
9483                        x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f);
9484                        y = bounds.top + (int) (bounds.height() * 0.25f);
9485                        y = y + (int) (labelHeight * 0.5f);
9486
9487                        ti.setLocation(Math.round(x), Math.round(y));
9488                        arrMods.add(ti);
9489                    }
9490                }
9491                if (ec == 240601 || ec == 240602)
9492                {
9493                    if (modifiers.containsKey(Modifiers.AP_TARGET_NUMBER)) {
9494                        strText = modifiers.get(Modifiers.AP_TARGET_NUMBER);
9495                    }
9496                    if (ec == 240601 && modifiers.containsKey(Modifiers.AP1_TARGET_NUMBER_EXTENSION)) {
9497                        if (strText != null)
9498                            strText = strText + "  " + modifiers.get(Modifiers.AP1_TARGET_NUMBER_EXTENSION);
9499                        else
9500                            strText = modifiers.get(Modifiers.AP1_TARGET_NUMBER_EXTENSION);
9501                    }
9502                    if (strText != null) {
9503                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9504
9505                        x = RectUtilities.getCenterX(bounds) + (int) (bounds.width() * 0.15f);
9506                        y = bounds.top + (int) (bounds.height() * 0.25f);
9507                        y = y + (int) (labelHeight * 0.5f);
9508
9509                        ti.setLocation(Math.round(x), Math.round(y));
9510                        arrMods.add(ti);
9511                    }
9512                }
9513            }
9514            else if (ec == 132100)//Key Terrain
9515            {
9516                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9517                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9518                    if (strText != null) {
9519                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9520
9521                        //One modifier symbols and modifier goes right of symbol
9522
9523                        x = bounds.left + (int)(bounds.width() * 0.5) + bufferXL;
9524
9525                        y = bounds.top + (int) (bounds.height() * 0.5f);
9526                        y = y + (int) ((labelHeight - descent) * 0.5f);
9527
9528                        ti.setLocation(Math.round(x), Math.round(y));
9529                        arrMods.add(ti);
9530                    }
9531                }
9532            }
9533            else if(ec == 182600)//Isolated Personnel Location
9534            {
9535                if (modifiers.containsKey(Modifiers.C_QUANTITY)) {
9536                    strText = modifiers.get(Modifiers.C_QUANTITY);
9537                    if (strText != null) {
9538                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9539                        labelWidth = (int)Math.round(ti.getTextBounds().width());
9540                        //subset of NBC, just nuclear
9541                        x = (int)(bounds.left + (bounds.width() * 0.5));
9542                        x = x - (int) (labelWidth * 0.5);
9543                        y = (int)bounds.top - descent;
9544                        ti.setLocation(Math.round(x), Math.round(y));
9545                        arrMods.add(ti);
9546                    }
9547                }
9548                if (modifiers.containsKey(Modifiers.W_DTG_1)) {
9549                    strText = modifiers.get(Modifiers.W_DTG_1);
9550                    if (strText != null) {
9551                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9552                        labelWidth = (int)Math.round(ti.getTextBounds().width());
9553
9554                        x = (int)bounds.left - labelWidth - bufferXL;
9555                        if (!byLabelHeight) {
9556                            y = (int)bounds.top + labelHeight - descent;
9557                        } else {
9558                            //y = bounds.y + ((bounds.getHeight * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText));
9559                            y = (int)(bounds.top + ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText)));
9560                        }
9561
9562                        ti.setLocation(Math.round(x), Math.round(y));
9563                        arrMods.add(ti);
9564                    }
9565                }
9566                if (modifiers.containsKey(Modifiers.W1_DTG_2)) {
9567                    strText = modifiers.get(Modifiers.W1_DTG_2);
9568                    if (strText != null) {
9569                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9570                        labelWidth = (int)Math.round(ti.getTextBounds().width());
9571
9572                        x = (int)bounds.left - labelWidth - bufferXL;
9573                        if (!byLabelHeight) {
9574                            y = (int)bounds.top + labelHeight - descent;
9575                        } else {
9576                            //y = bounds.y + ((bounds.getHeight * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText));
9577                            y = (int)(bounds.top + ((bounds.height() * 0.5) - (((labelHeight * 2) - descent) * 0.5) + (-descent - bufferText)));
9578                        }
9579
9580                        ti.setLocation(Math.round(x), Math.round(y));
9581                        arrMods.add(ti);
9582                    }
9583                }
9584            }
9585            else if (SymbolUtilities.isCBRNEvent(symbolID)) //CBRN
9586            {
9587                if (modifiers.containsKey(Modifiers.N_HOSTILE)) {
9588                    strText = modifiers.get(Modifiers.N_HOSTILE);
9589                    if (strText != null) {
9590                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9591
9592                        x = bounds.left + bounds.width() + bufferXR;
9593
9594                        if (!byLabelHeight) {
9595                            y = bounds.top + bounds.height();
9596                        } else {
9597                            y = bounds.top + (int) ((bounds.height() * 0.5f) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText));
9598                        }
9599
9600                        ti.setLocation(Math.round(x), Math.round(y));
9601                        arrMods.add(ti);
9602                    }
9603
9604                }
9605                if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) {
9606                    strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
9607                    if (strText != null) {
9608                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9609
9610                        x = bounds.left + bounds.width() + bufferXR;
9611                        if (!byLabelHeight) {
9612                            y = bounds.top + labelHeight - descent;
9613                        } else {
9614                            //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText));
9615                            y = bounds.top + (int) ((bounds.height() * 0.5f) - ((labelHeight - descent) * 0.5) + (-descent - bufferText));
9616                        }
9617
9618                        ti.setLocation(Math.round(x), Math.round(y));
9619                        arrMods.add(ti);
9620                    }
9621                }
9622                if (modifiers.containsKey(Modifiers.W_DTG_1)) {
9623                    strText = modifiers.get(Modifiers.W_DTG_1);
9624                    if (strText != null) {
9625                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9626                        labelWidth = Math.round(ti.getTextBounds().width());
9627
9628                        x = bounds.left - labelWidth - bufferXL;
9629                        if (!byLabelHeight) {
9630                            y = bounds.top + labelHeight - descent;
9631                        } else {
9632                            //y = bounds.y + ((bounds.height * 0.5) + (labelHeight * 0.5) - (labelHeight + bufferText));
9633                            y = bounds.top + (int) ((bounds.height() * 0.5) - ((labelHeight - descent) * 0.5) + (-descent - bufferText));
9634                        }
9635
9636                        ti.setLocation(Math.round(x), Math.round(y));
9637                        arrMods.add(ti);
9638                    }
9639                }
9640                if ((ec == 281500 || ec == 281600) && modifiers.containsKey(Modifiers.V_EQUIP_TYPE)) {//nuclear event or nuclear fallout producing event
9641                    strText = modifiers.get(Modifiers.V_EQUIP_TYPE);
9642                    if (strText != null) {
9643                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9644
9645                        //subset of nbc, just nuclear
9646                        labelWidth = Math.round(ti.getTextBounds().width());
9647                        x = bounds.left - labelWidth - bufferXL;
9648                        y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5));//((bounds.height / 2) - (labelHeight/2));
9649
9650                        ti.setLocation(Math.round(x), Math.round(y));
9651                        arrMods.add(ti);
9652                    }
9653                }
9654                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9655                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9656                    if (strText != null) {
9657                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9658                        labelWidth = Math.round(ti.getTextBounds().width());
9659                        x = bounds.left - labelWidth - bufferXL;
9660                        if (!byLabelHeight) {
9661                            y = bounds.top + bounds.height();
9662                        } else {
9663                            //y = bounds.y + ((bounds.height * 0.5) + ((labelHeight-descent) * 0.5) + (labelHeight + bufferText));
9664                            y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + (labelHeight - descent + bufferText));
9665                        }
9666                        ti.setLocation(Math.round(x), Math.round(y));
9667                        arrMods.add(ti);
9668                    }
9669                }
9670                if (modifiers.containsKey(Modifiers.Y_LOCATION)) {
9671                    strText = modifiers.get(Modifiers.Y_LOCATION);
9672                    if (strText != null) {
9673                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9674                        labelWidth = Math.round(ti.getTextBounds().width());
9675                        //just NBC
9676                        //x = bounds.left + (bounds.width() * 0.5);
9677                        //x = x - (labelWidth * 0.5);
9678                        x = bounds.left + (int) (bounds.width() * 0.5f);
9679                        x = x - (int) (labelWidth * 0.5f);
9680
9681                        if (!byLabelHeight) {
9682                            y = bounds.top + bounds.height() + labelHeight - descent + bufferY;
9683                        } else {
9684                            y = bounds.top + (int) ((bounds.height() * 0.5) + ((labelHeight - descent) * 0.5) + ((labelHeight + bufferText) * 2) - descent);
9685
9686                        }
9687                        yForY = y + descent; //so we know where to start the DOM arrow.
9688                        ti.setLocation(Math.round(x), Math.round(y));
9689                        arrMods.add(ti);
9690                    }
9691
9692                }
9693                if (modifiers.containsKey(Modifiers.C_QUANTITY)) {
9694                    strText = modifiers.get(Modifiers.C_QUANTITY);
9695                    if (strText != null) {
9696                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9697                        labelWidth = Math.round(ti.getTextBounds().width());
9698                        //subset of NBC, just nuclear
9699                        x = bounds.left + (int) (bounds.width() * 0.5);
9700                        x = x - (int) (labelWidth * 0.5);
9701                        y = bounds.top - descent;
9702                        ti.setLocation(Math.round(x), Math.round(y));
9703                        arrMods.add(ti);
9704                    }
9705
9706                }
9707            }
9708            else if (ec == 270701)//static depiction
9709            {
9710                if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) {
9711                    strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
9712                    if (strText != null) {
9713                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9714                        labelWidth = Math.round(ti.getTextBounds().width());
9715                        x = bounds.left + (int) (bounds.width() * 0.5);
9716                        x = x - (int) (labelWidth * 0.5);
9717                        y = bounds.top - descent;// + (bounds.height * 0.5);
9718                        //y = y + (labelHeight * 0.5);
9719
9720                        ti.setLocation(Math.round(x), Math.round(y));
9721                        arrMods.add(ti);
9722                    }
9723
9724                }
9725                if (modifiers.containsKey(Modifiers.W_DTG_1)) {
9726                    strText = modifiers.get(Modifiers.W_DTG_1);
9727                    if (strText != null) {
9728                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9729                        labelWidth = Math.round(ti.getTextBounds().width());
9730                        x = bounds.left + (int) (bounds.width() * 0.5);
9731                        x = x - (int) (labelWidth * 0.5);
9732                        y = bounds.top + (bounds.height());
9733                        y = y + (labelHeight);
9734
9735                        ti.setLocation(Math.round(x), Math.round(y));
9736                        arrMods.add(ti);
9737                    }
9738                }
9739                if (modifiers.containsKey(Modifiers.N_HOSTILE)) {
9740                    strText = modifiers.get(Modifiers.N_HOSTILE);
9741                    if (strText != null) {
9742                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9743                        TextInfo ti2 = new TextInfo(strText, 0, 0, _modifierFont);
9744                        labelWidth = Math.round(ti.getTextBounds().width());
9745                        x = bounds.left + (bounds.width()) + bufferXR;//right
9746                        //x = x + labelWidth;//- (labelBounds.width * 0.75);
9747
9748                        duplicate = true;
9749
9750                        x2 = bounds.left;//left
9751                        x2 = x2 - labelWidth - bufferXL;// - (labelBounds.width * 0.25);
9752
9753                        y = bounds.top + (int) (bounds.height() * 0.5);//center
9754                        y = y + (int) ((labelHeight - descent) * 0.5);
9755
9756                        y2 = y;
9757
9758                        ti.setLocation(Math.round(x), Math.round(y));
9759                        ti2.setLocation(Math.round(x2), Math.round(y2));
9760                        arrMods.add(ti);
9761                        arrMods.add(ti2);
9762                    }
9763                }
9764
9765            }
9766            else if(e == 21 && et == 35)//sonobuoys
9767            {
9768                //H sitting on center of circle to the right
9769                //T above H
9770                centerPoint = SymbolUtilities.getCMSymbolAnchorPoint(symbolID,RectUtilities.makeRectFFromRect(bounds));
9771                if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) {
9772                    strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
9773                    if (strText != null) {
9774                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9775                        TextInfo ti2 = new TextInfo(strText, 0, 0, _modifierFont);
9776                        labelWidth = Math.round(ti.getTextBounds().width());
9777                        x = bounds.left + (bounds.width()) + bufferXR;//right
9778                        y = centerPoint.y;
9779
9780                        ti.setLocation(Math.round(x), Math.round(y));
9781                        arrMods.add(ti);
9782                    }
9783                }
9784                if (est == 0 || est == 1 || est == 4 || est == 7 || est == 8 || est == 15) {
9785                    if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9786                        strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9787                        if (strText != null) {
9788                            ti = new TextInfo(strText, 0, 0, _modifierFont);
9789                            TextInfo ti2 = new TextInfo(strText, 0, 0, _modifierFont);
9790                            labelWidth = Math.round(ti.getTextBounds().width());
9791                            x = bounds.left + (bounds.width()) + bufferXR;//right
9792                            y = centerPoint.y - labelHeight;
9793
9794                            ti.setLocation(Math.round(x), Math.round(y));
9795                            arrMods.add(ti);
9796                        }
9797                    }
9798                }
9799            }
9800            else if(ec == 282001 || //tower, low
9801                    ec == 282002)   //tower, high
9802            {
9803                if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) {
9804                    strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
9805                    if (strText != null) {
9806                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9807                        labelWidth = Math.round(ti.getTextBounds().width());
9808                        x = bounds.left + (int) (bounds.width() * 0.7);
9809                        y = bounds.top + labelHeight;// + (bounds.height * 0.5);
9810                        //y = y + (labelHeight * 0.5);
9811
9812                        ti.setLocation(Math.round(x), Math.round(y));
9813                        arrMods.add(ti);
9814                    }
9815
9816                }
9817            }
9818            else if(ec == 180600)//TACAN
9819            {
9820                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9821                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9822                    if (strText != null) {
9823                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9824                        labelWidth = Math.round(ti.getTextBounds().width());
9825                        x = bounds.left + bounds.width() + bufferXR;
9826                        y = bounds.top + labelHeight;// + (bounds.height * 0.5);
9827                        //y = y + (labelHeight * 0.5);
9828
9829                        ti.setLocation(Math.round(x), Math.round(y));
9830                        arrMods.add(ti);
9831                    }
9832
9833                }
9834            }
9835            else if(ec == 210300)//Defended Asset
9836            {
9837                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9838                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9839                    if (strText != null) {
9840                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9841                        labelWidth = Math.round(ti.getTextBounds().width());
9842                        x = bounds.left - labelWidth - bufferXL;
9843                        y = bounds.top + labelHeight;// + (bounds.height * 0.5);
9844                        //y = y + (labelHeight * 0.5);
9845
9846                        ti.setLocation(Math.round(x), Math.round(y));
9847                        arrMods.add(ti);
9848                    }
9849
9850                }
9851            }
9852            else if(ec == 210600)//Air Detonation
9853            {
9854                if (modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH)) {
9855                    strText = modifiers.get(Modifiers.X_ALTITUDE_DEPTH);
9856                    if (strText != null) {
9857                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9858                        labelWidth = Math.round(ti.getTextBounds().width());
9859                        x = bounds.left + (bounds.width() + bufferXR);
9860                        y = bounds.top + labelHeight;// + (bounds.height * 0.5);
9861                        //y = y + (labelHeight * 0.5);
9862
9863                        ti.setLocation(Math.round(x), Math.round(y));
9864                        arrMods.add(ti);
9865                    }
9866
9867                }
9868            }
9869            else if(ec == 210800)//Impact Point
9870            {
9871                if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) {
9872                    strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
9873                    if (strText != null) {
9874                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9875                        labelWidth = Math.round(ti.getTextBounds().width());
9876                        x = bounds.left + (int) (bounds.width() * 0.65f);
9877//                  x = x - (labelBounds.width * 0.5);
9878                        y = bounds.top + (int) (bounds.height() * 0.25f);
9879                        y = y + (int) (labelHeight * 0.5f);
9880                        //y = y + (labelHeight * 0.5);
9881
9882                        ti.setLocation(Math.round(x), Math.round(y));
9883                        arrMods.add(ti);
9884                    }
9885
9886                }
9887            }
9888            else if(ec == 211000)//Launched Torpedo
9889            {
9890                if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) {
9891                    strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
9892                    if (strText != null) {
9893                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9894                        labelWidth = Math.round(ti.getTextBounds().width());
9895                        x = (int)(bounds.left + (bounds.width() * 0.5) - (labelWidth/2));
9896                        y = bounds.top - bufferY;
9897
9898                        ti.setLocation(Math.round(x), Math.round(y));
9899                        arrMods.add(ti);
9900                    }
9901
9902                }
9903            }
9904            else if(ec == 214900 || ec == 215600)//General Sea SubSurface Station & General Sea Surface Station
9905            {
9906                if (modifiers.containsKey(Modifiers.W_DTG_1)) {
9907                    strText = modifiers.get(Modifiers.W_DTG_1);
9908                    if (strText != null) {
9909                        ti = new TextInfo(strText + " - ", 0, 0, _modifierFont);
9910                        x = bounds.left + (bounds.width() + bufferXR);
9911                        y = bounds.top + labelHeight;
9912
9913                        ti.setLocation(Math.round(x), Math.round(y));
9914                        arrMods.add(ti);
9915                    }
9916
9917                }
9918                if (modifiers.containsKey(Modifiers.W1_DTG_2)) {
9919                    strText = modifiers.get(Modifiers.W1_DTG_2);
9920                    if (strText != null) {
9921                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9922                        x = bounds.left + (bounds.width() + bufferXR);
9923                        y = bounds.top + (labelHeight * 2);
9924
9925                        ti.setLocation(Math.round(x), Math.round(y));
9926                        arrMods.add(ti);
9927                    }
9928
9929                }
9930                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9931                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9932                    if (strText != null) {
9933                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9934                        x = bounds.left + (bounds.width() + bufferXR);
9935                        y = bounds.top + (labelHeight * 3);
9936
9937                        ti.setLocation(Math.round(x), Math.round(y));
9938                        arrMods.add(ti);
9939                    }
9940
9941                }
9942            }
9943            else if(ec == 217000)//Shore Control Station
9944            {
9945                if (modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1)) {
9946                    strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
9947                    if (strText != null) {
9948                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9949                        labelWidth = Math.round(ti.getTextBounds().width());
9950                        x = (int)(bounds.left + (bounds.width() * 0.5) - (labelWidth/2));
9951                        y = bounds.top + bounds.height() + labelHeight + bufferY;
9952
9953                        ti.setLocation(Math.round(x), Math.round(y));
9954                        arrMods.add(ti);
9955                    }
9956
9957                }
9958            }
9959            else if(ec == 250600)//Known Point
9960            {
9961                if (modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1)) {
9962                    strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
9963                    if (strText != null) {
9964                        ti = new TextInfo(strText, 0, 0, _modifierFont);
9965                        labelWidth = Math.round(ti.getTextBounds().width());
9966                        x = bounds.left + (bounds.width() + bufferXR);
9967//                  x = x - (labelBounds.width * 0.5);
9968                        y = bounds.top + (int) (bounds.height() * 0.25f);
9969                        y = y + (int) (labelHeight * 0.5f);
9970                        //y = y + (labelHeight * 0.5);
9971
9972                        ti.setLocation(Math.round(x), Math.round(y));
9973                        arrMods.add(ti);
9974                    }
9975
9976                }
9977            }
9978        }
9979        else if(ss == SymbolID.SymbolSet_Atmospheric)
9980        {
9981            String modX = null;
9982            if(modifiers.containsKey(Modifiers.X_ALTITUDE_DEPTH))
9983                modX = (modifiers.get(Modifiers.X_ALTITUDE_DEPTH));
9984
9985            if(ec == 162300)//Freezing Level
9986            {
9987                strText = "0" + (char)(176) + ":";
9988                if(modX != null)
9989                    strText += modX;
9990                else
9991                    strText += "?";
9992
9993                ti = new TextInfo(strText, 0, 0, _modifierFont);
9994                labelWidth = Math.round(ti.getTextBounds().width());
9995                //One modifier symbols and modifier goes in center
9996                x = bounds.left + (int) (bounds.width() * 0.5f);
9997                x = x - (int) (labelWidth * 0.5f);
9998                y = bounds.top + (int) (bounds.height() * 0.5f);
9999                y = y + (int) ((labelHeight - _modifierFontDescent) * 0.5f);
10000
10001                ti.setLocation(Math.round(x), Math.round(y));
10002                arrMods.add(ti);
10003            }
10004            else if(ec == 162200)//tropopause Level
10005            {
10006                strText = "X?";
10007                if(modX != null)
10008                    strText = modX;
10009
10010                ti = new TextInfo(strText, 0, 0, _modifierFont);
10011                labelWidth = Math.round(ti.getTextBounds().width());
10012                //One modifier symbols and modifier goes in center
10013                x = bounds.left + (int) (bounds.width() * 0.5f);
10014                x = x - (int) (labelWidth * 0.5f);
10015                y = bounds.top + (int) (bounds.height() * 0.5f);
10016                y = y + (int) ((labelHeight - _modifierFontDescent) * 0.5f);
10017
10018                ti.setLocation(Math.round(x), Math.round(y));
10019                arrMods.add(ti);
10020            }
10021            else if(ec == 110102)//tropopause Low
10022            {
10023                strText = "X?";
10024                if(modX != null)
10025                    strText = modX;
10026
10027                ti = new TextInfo(strText, 0, 0, _modifierFont);
10028                labelWidth = Math.round(ti.getTextBounds().width());
10029                //One modifier symbols and modifier goes in center
10030                x = bounds.left + (int) (bounds.width() * 0.5f);
10031                x = x - (int) (labelWidth * 0.5f);
10032                y = bounds.top + (int) (bounds.height() * 0.5f);
10033                y = y - descent;
10034
10035                ti.setLocation(Math.round(x), Math.round(y));
10036                arrMods.add(ti);
10037            }
10038            else if(ec == 110202)//tropopause High
10039            {
10040                strText = "X?";
10041                if(modX != null)
10042                    strText = modX;
10043
10044                ti = new TextInfo(strText, 0, 0, _modifierFont);
10045                labelWidth = Math.round(ti.getTextBounds().width());
10046                //One modifier symbols and modifier goes in center
10047                x = bounds.left + (int) (bounds.width() * 0.5f);
10048                x = x - (int) (labelWidth * 0.5f);
10049                y = bounds.top + (int) (bounds.height() * 0.5f);
10050                //y = y + (int) ((labelHeight * 0.5f) + (labelHeight/2));
10051                y = y + (int) (((labelHeight * 0.5f) - (labelHeight/2)) + labelHeight - descent);
10052
10053                ti.setLocation(Math.round(x), Math.round(y));
10054                arrMods.add(ti);
10055            }
10056        }
10057        // </editor-fold>
10058
10059        // <editor-fold defaultstate="collapsed" desc="DOM Arrow">
10060        Point[] domPoints = null;
10061        Rect domBounds = null;
10062
10063        if (modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT) &&
10064                SymbolUtilities.isCBRNEvent(symbolID))//CBRN events
10065        {
10066            strText = modifiers.get(Modifiers.Q_DIRECTION_OF_MOVEMENT);
10067            if(strText != null && SymbolUtilities.isNumber(strText))
10068            {
10069                    float q = Float.parseFloat(strText);
10070                    Rect tempBounds = new Rect(bounds);
10071                    tempBounds.union(RectUtilities.getCenterX(bounds), yForY);
10072        
10073                    domPoints = createDOMArrowPoints(symbolID, tempBounds, sdi.getCenterPoint(), q, false);
10074        
10075                    domBounds = RectUtilities.makeRect(domPoints[0].x, domPoints[0].y, 1, 1);
10076        
10077                    Point temp = null;
10078                    for (int i = 1; i < 6; i++)
10079                    {
10080                        temp = domPoints[i];
10081                        if (temp != null)
10082                        {
10083                            domBounds.union(temp.x, temp.y);
10084                        }
10085                    }
10086                    imageBounds.union(domBounds);
10087            }
10088        }
10089        // </editor-fold>
10090
10091        // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator">
10092        if (SymbolUtilities.hasFDI(symbolID))
10093        {
10094            //create feint indicator /\
10095            fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top);
10096            fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top);
10097            fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f)));
10098
10099
10100            fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1);
10101            fdiBounds.union(fdiTop.x, fdiTop.y);
10102            fdiBounds.union(fdiRight.x, fdiRight.y);
10103
10104            float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f);
10105            RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2));
10106
10107            ti = new TextInfo("TEST",0,0,_modifierFont);
10108            if (ti != null && SymbolUtilities.isCBRNEvent(symbolID))
10109            {
10110                int shiftY = Math.round(symbolBounds.top - ti.getTextBounds().height() - 2);
10111                fdiLeft.offset(0, shiftY);
10112                fdiTop.offset(0, shiftY);
10113                fdiRight.offset(0, shiftY);
10114                fdiBounds.offset(0, shiftY);
10115            }
10116
10117            imageBounds.union(fdiBounds);
10118
10119        }
10120        // </editor-fold>
10121
10122        // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw">
10123        Rect modifierBounds = null;
10124        if (arrMods != null && arrMods.size() > 0)
10125        {
10126
10127            //build modifier bounds/////////////////////////////////////////
10128            modifierBounds = arrMods.get(0).getTextOutlineBounds();
10129            int size = arrMods.size();
10130            TextInfo tempShape = null;
10131            for (int i = 1; i < size; i++)
10132            {
10133                tempShape = arrMods.get(i);
10134                modifierBounds.union(tempShape.getTextOutlineBounds());
10135            }
10136
10137        }
10138
10139        if (modifierBounds != null || domBounds != null || fdiBounds != null)
10140        {
10141
10142            if (modifierBounds != null)
10143            {
10144                imageBounds.union(modifierBounds);
10145            }
10146            if (domBounds != null)
10147            {
10148                imageBounds.union(domBounds);
10149            }
10150            if (fdiBounds != null)
10151            {
10152                imageBounds.union(fdiBounds);
10153            }
10154
10155            //shift points if needed////////////////////////////////////////
10156            if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0))
10157            {
10158                int shiftX = Math.abs(imageBounds.left);
10159                int shiftY = Math.abs(imageBounds.top);
10160
10161                //shift mobility points
10162                int size = arrMods.size();
10163                TextInfo tempShape = null;
10164                for (int i = 0; i < size; i++)
10165                {
10166                    tempShape = arrMods.get(i);
10167                    tempShape.shift(shiftX, shiftY);
10168                }
10169                if(modifierBounds != null)
10170                    modifierBounds.offset(shiftX, shiftY);
10171
10172                if (domBounds != null)
10173                {
10174                    for (int i = 0; i < 6; i++)
10175                    {
10176                        Point temp = domPoints[i];
10177                        if (temp != null)
10178                        {
10179                            temp.offset(shiftX, shiftY);
10180                        }
10181                    }
10182                    domBounds.offset(shiftX, shiftY);
10183                }
10184
10185                //If there's an FDI
10186                if (fdiBounds != null)
10187                {
10188                    fdiBounds.offset(shiftX, shiftY);
10189                    fdiLeft.offset(shiftX, shiftY);
10190                    fdiTop.offset(shiftX, shiftY);
10191                    fdiRight.offset(shiftX, shiftY);
10192                }
10193
10194                //shift image points
10195                centerPoint.offset(shiftX, shiftY);
10196                symbolBounds.offset(shiftX, shiftY);
10197                imageBounds.offset(shiftX, shiftY);
10198            }
10199
10200
10201            if (attributes.containsKey(MilStdAttributes.TextColor))
10202            {
10203                textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor));
10204                if(alpha > -1)
10205                    textColor.setAlpha(alpha);
10206            }
10207            if (attributes.containsKey(MilStdAttributes.TextBackgroundColor))
10208            {
10209                textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor));
10210                if(alpha > -1)
10211                    textBackgroundColor.setAlpha(alpha);
10212            }
10213
10214            if(sdi instanceof ImageInfo) {
10215                ii = (ImageInfo)sdi;
10216                //Render modifiers//////////////////////////////////////////////////
10217                Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888);
10218                Canvas ctx = new Canvas(bmp);
10219
10220                //render////////////////////////////////////////////////////////
10221                //draw original icon with potential modifiers.
10222                ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null);
10223                //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top);
10224
10225
10226                renderText(ctx, arrMods, textColor, textBackgroundColor);
10227
10228                //draw DOM arrow
10229                if (domBounds != null)
10230                {
10231                    drawDOMArrow(ctx, domPoints, alpha, lineColor);
10232                }
10233
10234                //<editor-fold defaultstate="collapsed" desc="Draw FDI">
10235                if (fdiBounds != null) {
10236
10237                    Paint fdiPaint = new Paint();
10238                    fdiPaint.setAntiAlias(true);
10239                    fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0);
10240                    if (alpha > -1)
10241                        fdiPaint.setAlpha(alpha);
10242                    fdiPaint.setStyle(Style.STROKE);
10243
10244                    int dpi = RendererSettings.getInstance().getDeviceDPI();
10245                    int lineLength = dpi / 96 * 6;
10246                    int lineGap = dpi / 96 * 4;
10247
10248                    /// ///////////////////////////////////
10249                    //Divide line in 14 parts. line is 3 parts to 2 parts gap
10250                    float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft);
10251                    //distance = distance / 14f;
10252                    lineGap = (int)((distance / 14f) * 2);
10253                    lineLength = (int)((distance / 14f) * 3);
10254                    /// //////////////////////////////////
10255
10256                    fdiPaint.setPathEffect(new DashPathEffect(new float[]
10257                            {
10258                                    lineLength, lineGap
10259                            }, 0));
10260
10261                    float fdiStrokeWidth = Math.round(dpi / 96f);
10262                    if (fdiStrokeWidth < 2)
10263                        fdiStrokeWidth = 2;
10264
10265                    fdiPaint.setStrokeCap(Cap.ROUND);
10266                    fdiPaint.setStrokeJoin(Join.MITER);
10267                    fdiPaint.setStrokeWidth(fdiStrokeWidth);
10268
10269                    Path fdiPath = new Path();
10270
10271                    fdiPath.moveTo(fdiTop.x, fdiTop.y);
10272                    fdiPath.lineTo(fdiLeft.x, fdiLeft.y);
10273                    fdiPath.moveTo(fdiTop.x, fdiTop.y);
10274                    fdiPath.lineTo(fdiRight.x, fdiRight.y);
10275                    ctx.drawPath(fdiPath, fdiPaint);
10276
10277                    fdiBounds = null;
10278
10279                }
10280                //</editor-fold>
10281
10282                newsdi = new ImageInfo(bmp, centerPoint, symbolBounds);
10283                ctx = null;
10284            }
10285            else if(sdi instanceof SVGSymbolInfo)
10286            {
10287                float strokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f);
10288                if(strokeWidth < 1)
10289                    strokeWidth=1;
10290                String svgStroke = RendererUtilities.colorToHexString(lineColor,false);
10291                String svgStrokeWidth = String.valueOf(strokeWidth);//"3";
10292
10293                ssi = (SVGSymbolInfo)sdi;
10294                StringBuilder sbSVG = new StringBuilder();
10295                sbSVG.append(ssi.getSVG());
10296                sbSVG.append(renderTextElements(arrMods,textColor,textBackgroundColor));
10297
10298                // <editor-fold defaultstate="collapsed" desc="DOM arrow">
10299                if (domBounds != null && domPoints.length == 6)
10300                {
10301                    SVGPath domPath = new SVGPath() ;
10302
10303                    domPath.moveTo(domPoints[0].x, domPoints[0].y);
10304                    if (domPoints[1] != null)
10305                    {
10306                        domPath.lineTo(domPoints[1].x, domPoints[1].y);
10307                    }
10308                    if (domPoints[2] != null)
10309                    {
10310                        domPath.lineTo(domPoints[2].x, domPoints[2].y);
10311                    }
10312                    sbSVG.append(domPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,null));
10313
10314                    domPath = new SVGPath();
10315
10316                    domPath.moveTo(domPoints[3].x, domPoints[3].y);
10317                    domPath.lineTo(domPoints[4].x, domPoints[4].y);
10318                    domPath.lineTo(domPoints[5].x, domPoints[5].y);
10319                    sbSVG.append(domPath.toSVGElement(null,0f,svgStroke,1f,1f,null));
10320
10321                    domBounds = null;
10322                    domPoints = null;
10323                }
10324                // </editor-fold>
10325
10326                //<editor-fold defaultstate="collapsed" desc="Draw FDI">
10327                if (fdiBounds != null)
10328                {
10329
10330                    /*int dpi = RendererSettings.getInstance().getDeviceDPI();
10331                    int lineLength = dpi / 96 * 6;
10332                    int lineGap = dpi / 96 * 4;
10333                    String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/
10334
10335                    /// ///////////////////////////////////
10336                    //Divide line in 14 parts. line is 3 parts to 2 parts gap
10337                    float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft);
10338                    //distance = distance / 14f;
10339                    int lineGap = (int)((distance / 14f) * 2);
10340                    int lineLength = (int)((distance / 14f) * 3);
10341                    String svgFDIDashArray = "" + lineLength + " " + lineGap;
10342                    /// //////////////////////////////////
10343
10344                    SVGPath fdiPath = new SVGPath();
10345                    fdiPath.moveTo(fdiTop.x, fdiTop.y);
10346                    fdiPath.lineTo(fdiLeft.x, fdiLeft.y);
10347                    fdiPath.moveTo(fdiTop.x, fdiTop.y);
10348                    fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/
10349
10350                    fdiPath.setLineDash(svgFDIDashArray);
10351
10352                    sbSVG.append(fdiPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,"round"));
10353                    //sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray));
10354                }
10355                //</editor-fold>
10356
10357                newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds);
10358            }
10359
10360
10361
10362
10363            // <editor-fold defaultstate="collapsed" desc="Cleanup">
10364            //ctx = null;
10365            // </editor-fold>
10366
10367            return newsdi;
10368
10369        }
10370        else
10371        {
10372            return null;
10373        }
10374        // </editor-fold>
10375
10376    }
10377
10378    /**
10379     * Process modifiers for action points
10380     */
10381    public static SymbolDimensionInfo ProcessTGSPModifiers(SymbolDimensionInfo sdi, String symbolID, Map<String,String> modifiers, Map<String,String> attributes, Color lineColor)
10382    {
10383
10384        // <editor-fold defaultstate="collapsed" desc="Variables">
10385        ImageInfo ii = null;
10386        SVGSymbolInfo ssi = null;
10387
10388        int bufferXL = 6;
10389        int bufferXR = 4;
10390        int bufferY = 2;
10391        int bufferText = 2;
10392        int centerOffset = 1; //getCenterX/Y function seems to go over by a pixel
10393        int x = 0;
10394        int y = 0;
10395        int x2 = 0;
10396        int y2 = 0;
10397
10398        //Feint Dummy Indicator variables
10399        Rect fdiBounds = null;
10400        Point fdiTop = null;
10401        Point fdiLeft = null;
10402        Point fdiRight = null;
10403
10404        int outlineOffset = RS.getTextOutlineWidth();
10405        int labelHeight = 0;
10406        int labelWidth = 0;
10407        int alpha = -1;
10408        SymbolDimensionInfo newsdi = null;
10409        
10410        Color textColor = lineColor;
10411        Color textBackgroundColor = null;
10412
10413        ArrayList<TextInfo> arrMods = new ArrayList<TextInfo>();
10414        boolean duplicate = false;
10415
10416        MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID);
10417
10418
10419        if (attributes.containsKey(MilStdAttributes.Alpha))
10420        {
10421            alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha));
10422        }
10423
10424        Rect bounds = new Rect(sdi.getSymbolBounds());
10425        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
10426        Point centerPoint = new Point(sdi.getCenterPoint());
10427        Rect imageBounds = new Rect(sdi.getImageBounds());
10428
10429        centerPoint = new Point(Math.round(sdi.getCenterPoint().x), Math.round(sdi.getCenterPoint().y));
10430
10431        boolean byLabelHeight = false;
10432
10433        labelHeight = Math.round(_modifierFontHeight + 0.5f);
10434        int maxHeight = (symbolBounds.height());
10435        if ((labelHeight * 3) > maxHeight)
10436        {
10437            byLabelHeight = true;
10438        }
10439
10440        int descent = (int) (_modifierFontDescent + 0.5f);
10441        int yForY = -1;
10442
10443        Rect labelBounds1 = null;//text.getPixelBounds(null, 0, 0);
10444        Rect labelBounds2 = null;
10445        String strText = "";
10446        String strText1 = "";
10447        String strText2 = "";
10448        TextInfo text1 = null;
10449        TextInfo text2 = null;
10450
10451        String basicID = SymbolUtilities.getBasicSymbolID(symbolID);
10452
10453        if (outlineOffset > 2)
10454        {
10455            outlineOffset = ((outlineOffset - 1) / 2);
10456        }
10457        else
10458        {
10459            outlineOffset = 0;
10460        }
10461
10462        /*bufferXL += outlineOffset;
10463         bufferXR += outlineOffset;
10464         bufferY += outlineOffset;
10465         bufferText += outlineOffset;*/
10466        // </editor-fold>
10467        // <editor-fold defaultstate="collapsed" desc="Process Modifiers">
10468        TextInfo ti = null;
10469
10470        {
10471            if (msi.getModifiers().contains(Modifiers.N_HOSTILE) && modifiers.containsKey(Modifiers.N_HOSTILE))
10472            {
10473                strText = modifiers.get(Modifiers.N_HOSTILE);
10474                if(strText != null)
10475                {
10476                        ti = new TextInfo(strText, 0, 0, _modifierFont);
10477        
10478                        x = bounds.left + bounds.width() + bufferXR;
10479        
10480                        if (!byLabelHeight)
10481                        {
10482                            y = ((bounds.height() / 3) * 2);//checkpoint, get box above the point
10483                            y = bounds.top + y;
10484                        }
10485                        else
10486                        {
10487                            //y = ((labelHeight + bufferText) * 3);
10488                            //y = bounds.y + y - descent;
10489                            y = bounds.top + bounds.height();
10490                        }
10491        
10492                        ti.setLocation(x, y);
10493                        arrMods.add(ti);
10494                }
10495
10496            }
10497            if (msi.getModifiers().contains(Modifiers.H_ADDITIONAL_INFO_1) && modifiers.containsKey(Modifiers.H_ADDITIONAL_INFO_1))
10498            {
10499                strText = modifiers.get(Modifiers.H_ADDITIONAL_INFO_1);
10500                if(strText != null)
10501                {
10502                        ti = new TextInfo(strText, 0, 0, _modifierFont);
10503                        labelWidth = Math.round(ti.getTextBounds().width());
10504        
10505                        x = bounds.left + (int) (bounds.width() * 0.5f);
10506                        x = x - (int) (labelWidth * 0.5f);
10507                        y = bounds.top - descent;
10508        
10509                        ti.setLocation(x, y);
10510                        arrMods.add(ti);
10511                }
10512            }
10513            if (msi.getModifiers().contains(Modifiers.H1_ADDITIONAL_INFO_2) && modifiers.containsKey(Modifiers.H1_ADDITIONAL_INFO_2))
10514            {
10515                strText = modifiers.get(Modifiers.H1_ADDITIONAL_INFO_2);
10516                if(strText != null)
10517                {
10518                        ti = new TextInfo(strText, 0, 0, _modifierFont);
10519                        labelWidth = Math.round(ti.getTextBounds().width());
10520        
10521                        x = bounds.left + (int) (bounds.width() * 0.5);
10522                        x = x - (int) (labelWidth * 0.5);
10523                    y = bounds.top + labelHeight - descent + (int) (bounds.height() * 0.07);
10524        
10525                        ti.setLocation(x, y);
10526                        arrMods.add(ti);
10527                }
10528            }
10529            if (msi.getModifiers().contains(Modifiers.A_SYMBOL_ICON))
10530            {
10531                if(modifiers.containsKey(Modifiers.A_SYMBOL_ICON))
10532                    strText = modifiers.get(Modifiers.A_SYMBOL_ICON);
10533                else if(SymbolID.getEntityCode(symbolID)==321706)//NATO Multiple Supply Class Point
10534                    strText = "ALL?";//make it clear the required 'A' value wasn't set for this symbol.
10535
10536                if(strText != null)
10537                {
10538                    ti = new TextInfo(strText, 0, 0, _modifierFont);
10539                    labelWidth = Math.round(ti.getTextBounds().width());
10540
10541                    x = bounds.left + (int) (bounds.width() * 0.5);
10542                    x = x - (int) (labelWidth * 0.5);
10543                    y = bounds.top + labelHeight - descent + (int) (bounds.height() * 0.07);
10544
10545                    ti.setLocation(x, y);
10546                    arrMods.add(ti);
10547                }
10548            }
10549            if (msi.getModifiers().contains(Modifiers.W_DTG_1) && modifiers.containsKey(Modifiers.W_DTG_1))
10550            {
10551                strText = modifiers.get(Modifiers.W_DTG_1);
10552                if(strText != null)
10553                {
10554                        ti = new TextInfo(strText, 0, 0, _modifierFont);
10555                        labelWidth = Math.round(ti.getTextBounds().width());
10556        
10557                        x = bounds.left - labelWidth - bufferXL;
10558                        y = bounds.top + labelHeight - descent;
10559        
10560                        ti.setLocation(x, y);
10561                        arrMods.add(ti);
10562                }
10563            }
10564            if (msi.getModifiers().contains(Modifiers.W1_DTG_2) && modifiers.containsKey(Modifiers.W1_DTG_2))
10565            {
10566                strText = modifiers.get(Modifiers.W1_DTG_2);
10567                if(strText != null)
10568                {
10569                        ti = new TextInfo(strText, 0, 0, _modifierFont);
10570                        labelWidth = Math.round(ti.getTextBounds().width());
10571        
10572                        x = bounds.left - labelWidth - bufferXL;
10573        
10574                        y = ((labelHeight - descent + bufferText) * 2);
10575                        y = bounds.top + y;
10576        
10577                        ti.setLocation(x, y);
10578                        arrMods.add(ti);
10579                }
10580            }
10581            if (msi.getModifiers().contains(Modifiers.T_UNIQUE_DESIGNATION_1) && modifiers.containsKey(Modifiers.T_UNIQUE_DESIGNATION_1))
10582            {
10583                strText = modifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1);
10584                if(strText != null)
10585                {
10586                        ti = new TextInfo(strText, 0, 0, _modifierFont);
10587        
10588                        x = bounds.left + bounds.width() + bufferXR;
10589                        y = bounds.top + labelHeight - descent;
10590        
10591                        ti.setLocation(x, y);
10592                        arrMods.add(ti);
10593                }
10594            }
10595            if (msi.getModifiers().contains(Modifiers.T1_UNIQUE_DESIGNATION_2) && modifiers.containsKey(Modifiers.T1_UNIQUE_DESIGNATION_2))
10596            {
10597                strText = modifiers.get(Modifiers.T1_UNIQUE_DESIGNATION_2);
10598                if(strText != null)
10599                {
10600                        ti = new TextInfo(strText, 0, 0, _modifierFont);
10601                        labelWidth = Math.round(ti.getTextBounds().width());
10602        
10603                        //points
10604                        x = bounds.left + (int) (bounds.width() * 0.5);
10605                        x = x - (int) (labelWidth * 0.5);
10606                        //y = bounds.y + (bounds.height * 0.5);
10607        
10608                        y = (int) ((bounds.height() * 0.55));//633333333
10609                        y = bounds.top + y;
10610        
10611                        ti.setLocation(x, y);
10612                        arrMods.add(ti);
10613                }
10614            }
10615            // <editor-fold defaultstate="collapsed" desc="Build Feint Dummy Indicator">
10616            if (SymbolUtilities.hasFDI(symbolID))
10617            {
10618                //create feint indicator /\
10619                fdiLeft = new Point((int) symbolBounds.left, (int) symbolBounds.top);
10620                fdiRight = new Point((int) (symbolBounds.left + symbolBounds.width()), (int) symbolBounds.top);
10621                fdiTop = new Point(Math.round(RectUtilities.getCenterX(symbolBounds)), Math.round(symbolBounds.top - (symbolBounds.width() * .5f)));
10622
10623
10624                fdiBounds = RectUtilities.makeRect(fdiLeft.x, fdiLeft.y, 1, 1);
10625                fdiBounds.union(fdiTop.x, fdiTop.y);
10626                fdiBounds.union(fdiRight.x, fdiRight.y);
10627
10628                float fdiStrokeWidth = Math.round(RendererSettings.getInstance().getDeviceDPI() / 96f);
10629                RectUtilities.grow(fdiBounds,Math.round(fdiStrokeWidth/2));
10630
10631                ti = new TextInfo("TEST",0,0,_modifierFont);
10632                if (ti != null)
10633                {
10634                    int shiftY = Math.round(symbolBounds.top - ti.getTextBounds().height() - 2);
10635                    fdiLeft.offset(0, shiftY);
10636                    fdiTop.offset(0, shiftY);
10637                    fdiRight.offset(0, shiftY);
10638                    fdiBounds.offset(0, shiftY);
10639                }
10640
10641                imageBounds.union(fdiBounds);
10642
10643            }
10644            // </editor-fold>
10645        }
10646
10647        // </editor-fold>
10648        // <editor-fold defaultstate="collapsed" desc="Shift Points and Draw">
10649        Rect modifierBounds = null;
10650        if (arrMods != null && arrMods.size() > 0)
10651        {
10652
10653            //build modifier bounds/////////////////////////////////////////
10654            modifierBounds = arrMods.get(0).getTextOutlineBounds();
10655            int size = arrMods.size();
10656            TextInfo tempShape = null;
10657            for (int i = 1; i < size; i++)
10658            {
10659                tempShape = arrMods.get(i);
10660                modifierBounds.union(tempShape.getTextOutlineBounds());
10661            }
10662
10663        }
10664
10665        if(fdiBounds != null)
10666        {
10667            if(modifierBounds != null)
10668                modifierBounds.union(fdiBounds);
10669            else
10670                modifierBounds = fdiBounds;
10671        }
10672
10673        if (modifierBounds != null)
10674        {
10675
10676            imageBounds.union(modifierBounds);
10677
10678            //shift points if needed////////////////////////////////////////
10679            if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0))
10680            {
10681                int shiftX = Math.abs(imageBounds.left);
10682                int shiftY = Math.abs(imageBounds.top);
10683
10684                //shift mobility points
10685                int size = arrMods.size();
10686                TextInfo tempShape = null;
10687                for (int i = 0; i < size; i++)
10688                {
10689                    tempShape = arrMods.get(i);
10690                    tempShape.shift(shiftX, shiftY);
10691                }
10692                modifierBounds.offset(shiftX, shiftY);
10693
10694                //shift image points
10695                centerPoint.offset(shiftX, shiftY);
10696                symbolBounds.offset(shiftX, shiftY);
10697                imageBounds.offset(shiftX, shiftY);
10698
10699                //If there's an FDI
10700                if (fdiBounds != null)
10701                {
10702                    fdiBounds.offset(shiftX, shiftY);
10703                    fdiLeft.offset(shiftX, shiftY);
10704                    fdiTop.offset(shiftX, shiftY);
10705                    fdiRight.offset(shiftX, shiftY);
10706                }
10707            }
10708
10709            if (attributes.containsKey(MilStdAttributes.TextColor))
10710            {
10711                textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor));
10712                if(alpha > -1)
10713                    textColor.setAlpha(alpha);
10714            }
10715            if (attributes.containsKey(MilStdAttributes.TextBackgroundColor))
10716            {
10717                textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor));
10718                if(alpha > -1)
10719                    textBackgroundColor.setAlpha(alpha);
10720            }
10721
10722            if(sdi instanceof ImageInfo)
10723            {
10724                ii = (ImageInfo) sdi;
10725                //Render modifiers//////////////////////////////////////////////////
10726                Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888);
10727                Canvas ctx = new Canvas(bmp);
10728
10729                //draw original icon with potential modifiers.
10730                ctx.drawBitmap(ii.getImage(), symbolBounds.left, symbolBounds.top, null);
10731                //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top);
10732
10733
10734                renderText(ctx, arrMods, textColor, textBackgroundColor);
10735
10736                //<editor-fold defaultstate="collapsed" desc="Draw FDI">
10737                if (fdiBounds != null) {
10738
10739                    Paint fdiPaint = new Paint();
10740                    fdiPaint.setAntiAlias(true);
10741                    fdiPaint.setColor(lineColor.toInt());/// setARGB(255, 0, 0, 0);
10742                    if (alpha > -1)
10743                        fdiPaint.setAlpha(alpha);
10744                    fdiPaint.setStyle(Style.STROKE);
10745
10746                    int dpi = RendererSettings.getInstance().getDeviceDPI();
10747                    int lineLength = dpi / 96 * 6;
10748                    int lineGap = dpi / 96 * 4;
10749
10750                    /// ///////////////////////////////////
10751                    //Divide line in 14 parts. line is 3 parts to 2 parts gap
10752                    float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft);
10753                    //distance = distance / 14f;
10754                    lineGap = (int)((distance / 14f) * 2);
10755                    lineLength = (int)((distance / 14f) * 3);
10756                    /// //////////////////////////////////
10757
10758                    fdiPaint.setPathEffect(new DashPathEffect(new float[]
10759                            {
10760                                    lineLength, lineGap
10761                            }, 0));
10762
10763                    float fdiStrokeWidth = Math.round(dpi / 96f);
10764                    if (fdiStrokeWidth < 2)
10765                        fdiStrokeWidth = 2;
10766
10767                    fdiPaint.setStrokeCap(Cap.ROUND);
10768                    fdiPaint.setStrokeJoin(Join.MITER);
10769                    fdiPaint.setStrokeWidth(fdiStrokeWidth);
10770
10771                    Path fdiPath = new Path();
10772
10773                    fdiPath.moveTo(fdiTop.x, fdiTop.y);
10774                    fdiPath.lineTo(fdiLeft.x, fdiLeft.y);
10775                    fdiPath.moveTo(fdiTop.x, fdiTop.y);
10776                    fdiPath.lineTo(fdiRight.x, fdiRight.y);
10777                    ctx.drawPath(fdiPath, fdiPaint);
10778
10779                    fdiBounds = null;
10780
10781                }
10782                //</editor-fold>
10783
10784                newsdi = new ImageInfo(bmp, centerPoint, symbolBounds);
10785            }
10786            else if(sdi instanceof SVGSymbolInfo)
10787            {
10788                String svgStroke = RendererUtilities.colorToHexString(lineColor,false);
10789                String svgStrokeWidth = "3";
10790                String svgAlpha = null;
10791                if(alpha > -1)
10792                    svgAlpha = String.valueOf(alpha);
10793                ssi = (SVGSymbolInfo)sdi;
10794                StringBuilder sbSVG = new StringBuilder();
10795                sbSVG.append(ssi.getSVG());
10796                sbSVG.append(renderTextElements(arrMods,textColor,textBackgroundColor));
10797
10798                //<editor-fold defaultstate="collapsed" desc="Draw FDI">
10799                if (fdiBounds != null)
10800                {
10801                    /*int dpi = RendererSettings.getInstance().getDeviceDPI();
10802                    int lineLength = dpi / 96 * 6;
10803                    int lineGap = dpi / 96 * 4;
10804                    String svgFDIDashArray = "" + lineLength + " " + lineGap;//*/
10805
10806                    /// ///////////////////////////////////
10807                    //Divide line in 14 parts. line is 3 parts to 2 parts gap
10808                    float distance = RendererUtilities.getDistanceBetweenPoints(fdiTop,fdiLeft);
10809                    //distance = distance / 14f;
10810                    int lineGap = (int)((distance / 14f) * 2);
10811                    int lineLength = (int)((distance / 14f) * 3);
10812                    String svgFDIDashArray = "" + lineLength + " " + lineGap;
10813                    /// //////////////////////////////////
10814
10815                    SVGPath fdiPath = new SVGPath();
10816                    fdiPath.moveTo(fdiTop.x, fdiTop.y);
10817                    fdiPath.lineTo(fdiLeft.x, fdiLeft.y);
10818                    fdiPath.moveTo(fdiTop.x, fdiTop.y);
10819                    fdiPath.lineTo(fdiRight.x, fdiRight.y);//*/
10820
10821                    fdiPath.setLineDash(svgFDIDashArray);
10822                    sbSVG.append(fdiPath.toSVGElement(svgStroke,Float.parseFloat(svgStrokeWidth),null,1f,1f,"round"));
10823                    //sbSVG.append(Shape2SVG.Convert(fdiPath, svgStroke, null, svgStrokeWidth, svgAlpha, svgAlpha, svgFDIDashArray));
10824                }
10825                //</editor-fold>
10826
10827                newsdi = new SVGSymbolInfo(sbSVG.toString(),centerPoint,symbolBounds,imageBounds);
10828            }
10829
10830            // <editor-fold defaultstate="collapsed" desc="Cleanup">
10831            //ctx = null;
10832
10833            // </editor-fold>
10834        }
10835        // </editor-fold>
10836        return newsdi;
10837
10838    }
10839
10840    private static SymbolDimensionInfo shiftUnitPointsAndDraw(ArrayList<TextInfo> tiArray, SymbolDimensionInfo sdi, Map<String,String> attributes)
10841    {
10842        ImageInfo ii = null;
10843        SVGSymbolInfo ssi = null;
10844        SymbolDimensionInfo newsdi = null;
10845
10846        int alpha = -1;
10847
10848
10849        if (attributes != null && attributes.containsKey(MilStdAttributes.Alpha))
10850        {
10851            alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha));
10852        }
10853
10854        Color textColor = Color.BLACK;
10855        Color textBackgroundColor = null;
10856
10857        Rect symbolBounds = new Rect(sdi.getSymbolBounds());
10858        Point centerPoint = new Point(sdi.getCenterPoint());
10859        Rect imageBounds = new Rect(sdi.getImageBounds());
10860        Rect imageBoundsOld = new Rect(sdi.getImageBounds());
10861
10862        Rect modifierBounds = null;
10863        if (tiArray != null && tiArray.size() > 0)
10864        {
10865
10866            //build modifier bounds/////////////////////////////////////////
10867            modifierBounds = tiArray.get(0).getTextOutlineBounds();
10868            int size = tiArray.size();
10869            TextInfo tempShape = null;
10870            for (int i = 1; i < size; i++)
10871            {
10872                tempShape = tiArray.get(i);
10873                modifierBounds.union(tempShape.getTextOutlineBounds());
10874            }
10875
10876        }
10877
10878        if (modifierBounds != null)
10879        {
10880
10881            imageBounds.union(modifierBounds);
10882
10883            //shift points if needed////////////////////////////////////////
10884            if (sdi instanceof ImageInfo && (imageBounds.left < 0 || imageBounds.top < 0))
10885            {
10886                int shiftX = Math.round(Math.abs(imageBounds.left)),
10887                        shiftY = Math.round(Math.abs(imageBounds.top));
10888
10889                //shift mobility points
10890                int size = tiArray.size();
10891                TextInfo tempShape = null;
10892                for (int i = 0; i < size; i++)
10893                {
10894                    tempShape = tiArray.get(i);
10895                    tempShape.shift(shiftX, shiftY);
10896                }
10897                RectUtilities.shift(modifierBounds, shiftX, shiftY);
10898                //modifierBounds.shift(shiftX,shiftY);
10899
10900                //shift image points
10901                centerPoint.offset(shiftX, shiftY);
10902                RectUtilities.shift(symbolBounds, shiftX, shiftY);
10903                RectUtilities.shift(imageBounds, shiftX, shiftY);
10904                RectUtilities.shift(imageBoundsOld, shiftX, shiftY);
10905                /*centerPoint.shift(shiftX, shiftY);
10906                 symbolBounds.shift(shiftX, shiftY);
10907                 imageBounds.shift(shiftX, shiftY);
10908                 imageBoundsOld.shift(shiftX, shiftY);//*/
10909            }
10910
10911            if (attributes != null && attributes.containsKey(MilStdAttributes.TextColor))
10912            {
10913                textColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextColor));
10914                if(alpha > -1)
10915                    textColor.setAlpha(alpha);
10916            }
10917            if (attributes != null && attributes.containsKey(MilStdAttributes.TextBackgroundColor))
10918            {
10919                textBackgroundColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.TextBackgroundColor));
10920                if(alpha > -1)
10921                    textBackgroundColor.setAlpha(alpha);
10922            }
10923
10924            if(sdi instanceof ImageInfo)
10925            {
10926                ii = (ImageInfo) sdi;
10927
10928                Bitmap bmp = Bitmap.createBitmap(imageBounds.width(), imageBounds.height(), Config.ARGB_8888);
10929                Canvas ctx = new Canvas(bmp);
10930
10931                //render////////////////////////////////////////////////////////
10932                //draw original icon with potential modifiers.
10933                ctx.drawBitmap(ii.getImage(), imageBoundsOld.left, imageBoundsOld.top, null);
10934                //ctx.drawImage(ii.getImage(),imageBoundsOld.left,imageBoundsOld.top);
10935
10936                renderText(ctx, tiArray, textColor, textBackgroundColor);
10937
10938                newsdi = new ImageInfo(bmp, centerPoint, symbolBounds);
10939            }
10940            else if(sdi instanceof SVGSymbolInfo)
10941            {
10942                ssi = (SVGSymbolInfo)sdi;
10943                StringBuilder sb = new StringBuilder();
10944                sb.append(ssi.getSVG());
10945                sb.append(renderTextElements(tiArray,textColor,textBackgroundColor));
10946                newsdi = new SVGSymbolInfo(sb.toString(),centerPoint,symbolBounds,imageBounds);
10947            }
10948        }
10949
10950        if(newsdi == null)
10951            newsdi = sdi;
10952
10953        return newsdi;
10954    }
10955    private static String renderTextElement(ArrayList<TextInfo> tiArray, Color color, Color backgroundColor)
10956    {
10957        StringBuilder sbSVG = new StringBuilder();
10958
10959        String svgStroke = RendererUtilities.colorToHexString(RendererUtilities.getIdealOutlineColor(color),false);
10960        if(backgroundColor != null)
10961            svgStroke = RendererUtilities.colorToHexString(backgroundColor,false);
10962
10963        String svgFill = RendererUtilities.colorToHexString(color,false);
10964        String svgStrokeWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth());
10965        for (TextInfo ti : tiArray) {
10966            sbSVG.append(Shape2SVG.Convert(ti, svgStroke,svgFill,svgStrokeWidth,null,null,null));
10967            sbSVG.append("\n");
10968        }
10969
10970        return sbSVG.toString();
10971    }
10972
10973    private static String renderTextElements(ArrayList<TextInfo> tiArray, Color color, Color backgroundColor)
10974    {
10975        String style = null;
10976        String name = RendererSettings.getInstance().getModiferFontProps()[0] + ", sans-serif";//"SansSerif";
10977        String size = RendererSettings.getInstance().getModiferFontProps()[2];
10978        String weight = null;
10979        String anchor = null;//"start";
10980        if(RendererSettings.getInstance().getModiferFont().getTypeface().isBold())
10981            weight = "bold";
10982        StringBuilder sbSVG = new StringBuilder();
10983
10984        String svgStroke = RendererUtilities.colorToHexString(RendererUtilities.getIdealOutlineColor(color),false);
10985        if(backgroundColor != null)
10986            svgStroke = RendererUtilities.colorToHexString(backgroundColor,false);
10987
10988        String svgFill = RendererUtilities.colorToHexString(color,false);
10989        String svgStrokeWidth = String.valueOf(RendererSettings.getInstance().getTextOutlineWidth());
10990        sbSVG.append("\n<g");
10991        sbSVG.append(" font-family=\"" + name + '"');
10992        sbSVG.append(" font-size=\"" + size + "px\"");
10993        if(weight != null)
10994            sbSVG.append(" font-weight=\"" + weight + "\"");
10995        sbSVG.append(" alignment-baseline=\"alphabetic\"");//
10996        sbSVG.append(">");
10997
10998        for (TextInfo ti : tiArray) {
10999            sbSVG.append(Shape2SVG.ConvertForGroup(ti, svgStroke,svgFill,svgStrokeWidth,null,null,null));
11000            sbSVG.append("\n");
11001        }
11002        sbSVG.append("</g>\n");
11003
11004        return sbSVG.toString();
11005    }
11006    private static void renderText(Canvas ctx, ArrayList<TextInfo> tiArray, Color color, Color backgroundColor)
11007    {
11008        ModifierRenderer.renderText(ctx, (TextInfo[]) tiArray.toArray(new TextInfo[0]), color, backgroundColor);
11009    }
11010
11011    /**
11012     * 
11013     * @param ctx
11014     * @param tiArray
11015     * @param color
11016     * @param backgroundColor 
11017     */
11018    public static void renderText(Canvas ctx, TextInfo[] tiArray, Color color, Color backgroundColor)
11019    {
11020        /*for (TextInfo textInfo : tiArray) 
11021         {
11022         ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont);   
11023         }*/
11024
11025        int size = tiArray.length;
11026
11027        int tbm = RS.getTextBackgroundMethod();
11028        int outlineWidth = RS.getTextOutlineWidth();
11029
11030        if (color == null)
11031        {
11032            color = Color.BLACK;
11033        }
11034
11035        Color outlineColor = null;
11036        
11037        if(backgroundColor != null)
11038            outlineColor = backgroundColor;
11039        else
11040            outlineColor = RendererUtilities.getIdealOutlineColor(color);
11041
11042        if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE_QUICK)
11043        {
11044            synchronized (_ModifierFontMutex) {
11045                //draw text outline
11046                _modifierFont.setStyle(Style.FILL);
11047                _modifierFont.setStrokeWidth(RS.getTextOutlineWidth());
11048                _modifierFont.setColor(outlineColor.toInt());
11049
11050                if (outlineWidth > 2)
11051                    outlineWidth = 2;
11052
11053                if (outlineWidth > 0) {
11054                    for (int i = 0; i < size; i++) {
11055                        TextInfo textInfo = tiArray[i];
11056                        if (outlineWidth > 0) {
11057                            for (int j = 1; j <= outlineWidth; j++) {
11058                                if (j == 1) {
11059                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, _modifierFont);
11060                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, _modifierFont);
11061                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, _modifierFont);
11062                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, _modifierFont);
11063
11064                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, _modifierFont);
11065                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, _modifierFont);
11066
11067                                } else {
11068                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y - j, _modifierFont);
11069                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y - j, _modifierFont);
11070                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y + j, _modifierFont);
11071                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y + j, _modifierFont);
11072
11073                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x - j, textInfo.getLocation().y, _modifierFont);
11074                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x + j, textInfo.getLocation().y, _modifierFont);
11075
11076                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y + j, _modifierFont);
11077                                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y - j, _modifierFont);
11078                                }
11079
11080                            }
11081
11082                        }
11083
11084                    }
11085                }
11086                //draw text
11087                _modifierFont.setColor(color.toInt());
11088
11089                for (int j = 0; j < size; j++) {
11090                    TextInfo textInfo = tiArray[j];
11091                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont);
11092                /*Paint outline = new Paint();
11093                 outline.setStyle(Style.STROKE);
11094                 outline.setColor(Color.red.toInt());
11095                 outline.setAlpha(155);
11096                 outline.setStrokeWidth(1f);
11097                 ctx.drawRect(textInfo.getTextBounds(), outline);
11098                 outline.setColor(Color.blue.toInt());
11099                 ctx.drawRect(textInfo.getTextOutlineBounds(), outline);//*/
11100                }
11101            }
11102        }
11103        else if (tbm == RendererSettings.TextBackgroundMethod_OUTLINE)
11104        {
11105            synchronized (_ModifierFontMutex) {
11106                //draw text outline
11107                //draw text outline
11108                _modifierFont.setStyle(Style.STROKE);
11109                _modifierFont.setStrokeWidth(RS.getTextOutlineWidth());
11110                _modifierFont.setColor(outlineColor.toInt());
11111                if (outlineWidth > 0) {
11112                    for (int i = 0; i < size; i++) {
11113                        TextInfo textInfo = tiArray[i];
11114                        ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont);
11115                    }
11116                }
11117                //draw text
11118                _modifierFont.setColor(color.toInt());
11119                _modifierFont.setStyle(Style.FILL);
11120                for (int j = 0; j < size; j++) {
11121                    TextInfo textInfo = tiArray[j];
11122                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont);
11123                }
11124            }
11125        }
11126        else if (tbm == RendererSettings.TextBackgroundMethod_COLORFILL)
11127        {
11128            synchronized (_ModifierFontMutex) {
11129                Paint rectFill = new Paint();
11130                rectFill.setStyle(Paint.Style.FILL);
11131                rectFill.setColor(outlineColor.toARGB());
11132
11133
11134                //draw rectangle
11135                for (int k = 0; k < size; k++) {
11136                    TextInfo textInfo = tiArray[k];
11137                    ctx.drawRect(textInfo.getTextOutlineBounds(), rectFill);
11138                }
11139                //draw text
11140                _modifierFont.setColor(color.toInt());
11141                _modifierFont.setStyle(Style.FILL);
11142                for (int j = 0; j < size; j++) {
11143                    TextInfo textInfo = tiArray[j];
11144                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont);
11145                }
11146            }
11147        }
11148        else if (tbm == RendererSettings.TextBackgroundMethod_NONE)
11149        {
11150            synchronized (_ModifierFontMutex) {
11151                _modifierFont.setColor(color.toInt());
11152                _modifierFont.setStyle(Style.FILL);
11153                for (int j = 0; j < size; j++) {
11154                    TextInfo textInfo = tiArray[j];
11155                    ctx.drawText(textInfo.getText(), textInfo.getLocation().x, textInfo.getLocation().y, _modifierFont);
11156                }
11157            }
11158        }
11159    }
11160
11161    /**
11162     *
11163     * @param bounds bounds of the core icon
11164     * @param labelWidth height of the label to be placed
11165     * @param onRight if true, label on right side of symbol. On left if false.
11166     * @returns
11167     */
11168    private static double getLabelXPosition(Rect bounds, int labelWidth, boolean onRight)
11169    {
11170        int buffer = (int)_modifierFontHeight/2;
11171
11172        double x = 0;
11173        if(onRight)
11174        {
11175            x = bounds.left + bounds.width() + buffer;
11176        }
11177        else//left
11178        {
11179            x = bounds.left - labelWidth - buffer;
11180        }
11181        return x;
11182    }
11183
11184    /**
11185     *
11186     * @param bounds bounds of the core icon
11187     * @param labelHeight height of the label to be placed
11188     * @param descent descent of the label to be placed
11189     * @param bufferText spacing buffer if desired
11190     * @param centered if true, there will be a center label location identified by 0
11191     * @param location positive 1, 2, 3 to be above symbol mid-point or negative values to be below
11192     * @returns y position
11193     */
11194    private static double getLabelYPosition(Rect bounds, int labelHeight, int descent, int bufferText, boolean centered, int location) {
11195        double y = 0;
11196        if (bounds != null && !bounds.isEmpty())
11197        {
11198            if(centered)
11199            {
11200                switch (location)
11201                {
11202                    case 3://3 above center
11203                        y = (bounds.height());
11204                        y = ((y * 0.5) + (labelHeight * 0.5));
11205                        y = y - ((labelHeight + bufferText) * 3);
11206                        y = bounds.top + y;
11207                        break;
11208                    case 2://2 above center
11209                        y = (bounds.height());
11210                        y = ((y * 0.5) + (labelHeight * 0.5));
11211                        y = y - ((labelHeight + bufferText) * 2);
11212                        y = bounds.top + y;
11213                        break;
11214                    case 1://1 above center
11215                        y = (bounds.height());
11216                        y = ((y * 0.5) + (labelHeight * 0.5));
11217                        y = y - ((labelHeight + bufferText));
11218                        y = bounds.top + y;
11219                        break;
11220                    case 0: //centered
11221                        y = (bounds.height());
11222                        y = ((y * 0.5) + ((labelHeight - descent) * 0.5));
11223                        y = bounds.top + y;
11224                        break;
11225                    case -1://1 below center
11226                        y = (bounds.height());
11227                        y = ((y * 0.5) + (labelHeight * 0.5));
11228                        y = y + ((labelHeight + bufferText - descent));
11229                        y = bounds.top + y;
11230                        break;
11231                    case -2://2 below center
11232                        y = (bounds.height());
11233                        y = ((y * 0.5) + (labelHeight * 0.5));
11234                        y = y + ((labelHeight + bufferText) * 2) - (descent);
11235                        y = bounds.top + y;
11236                        break;
11237                }
11238            }
11239            else//split between top and bottom
11240            {
11241                switch (location)
11242                {
11243                    case 3:
11244                        y = (bounds.top + ((bounds.height() / 2) - descent - labelHeight*2 - bufferText));
11245                        break;
11246                    case 2:
11247                        y = (bounds.top + ((bounds.height() / 2) - descent - labelHeight - bufferText));
11248                        break;
11249                    case 1:
11250                        y = (bounds.top + ((bounds.height() / 2) - descent));
11251                        break;
11252                    case -1:
11253                        y = (bounds.top + (bounds.height() / 2) + (labelHeight - descent + bufferText));
11254                        break;
11255                    case -2:
11256                        y = (bounds.top + (bounds.height() / 2) + ((labelHeight*2 - descent + bufferText)));
11257                        break;
11258                    case -3:
11259                        y = (bounds.top + (bounds.height() / 2) + ((labelHeight*3 - descent + bufferText)));
11260                        break;
11261                }
11262            }
11263        }
11264        return y;
11265    }
11266
11267    private static boolean isCOnTop(String symbolID)
11268    {
11269        boolean onTop = false;
11270
11271        int version = SymbolID.getVersion(symbolID);
11272        int ss = SymbolID.getSymbolSet(symbolID);
11273        char frame = SymbolID.getFrameShape(symbolID);
11274
11275        if(SymbolUtilities.hasModifier(symbolID,Modifiers.C_QUANTITY)) {
11276            if (frame == SymbolID.FrameShape_Air || frame == SymbolID.FrameShape_Space)
11277                onTop = true;
11278            else if(frame == '0')
11279            {
11280                if (ss == SymbolID.SymbolSet_Air ||
11281                        ss == SymbolID.SymbolSet_AirMissile ||
11282                        ss == SymbolID.SymbolSet_Space ||
11283                        ss == SymbolID.SymbolSet_SpaceMissile ||
11284                        ss == SymbolID.SymbolSet_SignalsIntelligence_Air ||
11285                        (ss == SymbolID.SymbolSet_LandEquipment && version <= SymbolID.Version_2525Dch1)) {
11286                    onTop = true;
11287                }
11288            }
11289        }
11290        return onTop;
11291    }
11292    public static boolean hasDisplayModifiers(String symbolID, Map<String,String> modifiers)
11293    {
11294        boolean hasModifiers = false;
11295        int ss = SymbolID.getSymbolSet(symbolID);
11296        int status = SymbolID.getStatus(symbolID);
11297        int context = SymbolID.getContext(symbolID);
11298
11299        if(ss == SymbolID.SymbolSet_ControlMeasure)//check control measure
11300        {
11301            if (SymbolUtilities.isCBRNEvent(symbolID) == true && modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT))
11302            {
11303                hasModifiers = true;
11304            }
11305            else if(SymbolUtilities.hasFDI(symbolID))
11306                hasModifiers = true;
11307        }
11308        else if(ss != SymbolID.SymbolSet_Atmospheric &&
11309                ss != SymbolID.SymbolSet_Oceanographic &&
11310                ss != SymbolID.SymbolSet_MeteorologicalSpace)
11311        {//checking units
11312
11313            if(context > 0) //Exercise or Simulation
11314                hasModifiers = true;
11315
11316            //echelon or mobility,
11317            if (SymbolID.getAmplifierDescriptor(symbolID) > 0 || modifiers.containsKey(Modifiers.Q_DIRECTION_OF_MOVEMENT))
11318                hasModifiers = true;
11319
11320            if(modifiers.containsKey(Modifiers.AO_ENGAGEMENT_BAR))
11321                hasModifiers = true;
11322
11323            //HQ/Taskforce
11324            if(SymbolID.getHQTFD(symbolID) > 0)
11325                hasModifiers = true;
11326
11327            if(status > 1)//Fully capable, damaged, destroyed
11328                hasModifiers = true;
11329        }//no display modifiers for single point weather
11330
11331
11332
11333        return hasModifiers;
11334    }
11335
11336    public static boolean hasTextModifiers(String symbolID, Map<String,String> modifiers)
11337    {
11338
11339        int ss = SymbolID.getSymbolSet(symbolID);
11340        int ec = SymbolID.getEntityCode(symbolID);
11341        if(ss == SymbolID.SymbolSet_Atmospheric)
11342        {
11343            switch(ec)
11344            {
11345                case 110102: //tropopause low
11346                case 110202: //tropopause high
11347                case 162200: //tropopause level ?
11348                case 162300: //freezing level ?
11349                    return true;
11350                default:
11351                        return false;
11352            }
11353        }
11354        else if(ss == SymbolID.SymbolSet_Oceanographic || ss == SymbolID.SymbolSet_MeteorologicalSpace)
11355        {
11356            return false;
11357        }
11358        else if (ss == SymbolID.SymbolSet_ControlMeasure)
11359        {
11360            MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID);
11361
11362            if( msi.getModifiers().size() > 0 && modifiers != null && modifiers.size() > 0)
11363                return true;
11364            else
11365                return false;
11366        }
11367        else
11368        {
11369
11370            if (SymbolUtilities.getStandardIdentityModifier(symbolID) != null)
11371            {
11372                return true;
11373            }
11374
11375            int cc = SymbolID.getCountryCode(symbolID);
11376            if (cc > 0 && !GENCLookup.getInstance().get3CharCode(cc).isEmpty())
11377            {
11378                return true;
11379            }//*/
11380
11381            else if (modifiers.size() > 0)
11382            {
11383                return true;
11384            }
11385        }
11386        return false;
11387    }
11388
11389}