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