001package armyc2.c2sd.renderer;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import android.graphics.Bitmap;
007import android.graphics.Bitmap.Config;
008import android.graphics.Canvas;
009import android.graphics.Matrix;
010import android.graphics.Paint;
011import android.graphics.Point;
012import android.graphics.PointF;
013import android.graphics.Rect;
014import android.graphics.RectF;
015import android.graphics.Paint.Align;
016import android.graphics.Paint.FontMetrics;
017import android.graphics.Typeface;
018
019import android.util.Log;
020import android.util.SparseArray;
021
022import armyc2.c2sd.renderer.utilities.Color;
023import armyc2.c2sd.renderer.utilities.ErrorLogger;
024import armyc2.c2sd.renderer.utilities.ImageInfo;
025import armyc2.c2sd.renderer.utilities.MilStdAttributes;
026import armyc2.c2sd.renderer.utilities.ModifierInfo;
027import armyc2.c2sd.renderer.utilities.ModifiersTG;
028import armyc2.c2sd.renderer.utilities.RendererSettings;
029import armyc2.c2sd.renderer.utilities.SVGPath;
030import armyc2.c2sd.renderer.utilities.SinglePointLookup;
031import armyc2.c2sd.renderer.utilities.SinglePointLookupInfo;
032import armyc2.c2sd.renderer.utilities.SymbolDef;
033import armyc2.c2sd.renderer.utilities.SymbolDimensions;
034import armyc2.c2sd.renderer.utilities.SymbolUtilities;
035import armyc2.c2sd.renderer.utilities.UnitFontLookup;
036import armyc2.c2sd.renderer.utilities.UnitFontLookupInfo;
037import armyc2.c2sd.renderer.utilities.UnitSVGTable;
038
039public class SinglePointSVGRenderer
040{
041
042        private String TAG = "armyc2.c2sd.singlepointrenderer.SinglePointRenderer";
043        private static SinglePointSVGRenderer _instance = null;
044        // private static Bitmap dimensionsBMP = Bitmap.createBitmap(10, 10,
045        // Config.ARGB_8888);
046
047        private Typeface _tfUnits = null;
048        private Typeface _tfSP = null;
049        private Typeface _tfTG = null;
050
051        private SinglePointSVGRenderer()
052        {
053
054        }
055
056        public static synchronized SinglePointSVGRenderer getInstance()
057        {
058                if (_instance == null)
059                {
060                        _instance = new SinglePointSVGRenderer();
061                }
062
063                return _instance;
064        }
065
066        /**
067         * 
068         * @param symbolID
069         * @param modifiers
070         * @return
071         */
072        public ImageInfo RenderUnit(String symbolID, SparseArray<String> modifiers,
073                        SparseArray<String> attributes)
074        {
075                // L 1.5 = 2650 pixel units in the svg font file
076                //100& normal font size
077                //double L1_5 = 2650;
078                //50% normal font size
079                double L1_5 = 1325;
080                Bitmap finalBmp = null;
081
082                Bitmap coreBMP = null;
083                try
084                {
085                        Canvas g = null;// new Canvas(dimensionsBMP);
086
087                        // get font character indexes
088                        int fillIndex = -1;
089                        int frameIndex = -1;
090                        int symbol1Index = -1;
091                        int symbol2Index = -1;
092                        int frameAssumeIndex = -1;
093                        SVGPath svgFill = null;
094                        SVGPath svgFrame = null;
095                        SVGPath svgSymbol1 = null;
096                        SVGPath svgSymbol2 = null;
097
098                        // get attributes
099                        int alpha = 255;
100                        Boolean drawAsIcon = false;
101                        Boolean keepUnitRatio = true;
102                        int pixelSize = 0;
103                        Color fillColor = SymbolUtilities
104                                        .getFillColorOfAffiliation(symbolID);
105                        Color lineColor = SymbolUtilities
106                                        .getLineColorOfAffiliation(symbolID);
107
108                        boolean hasDisplayModifiers = false;
109                        boolean hasTextModifiers = false;
110                        boolean icon = false;
111                        int symStd = RendererSettings.getInstance().getSymbologyStandard();
112
113                        try
114                        {
115
116                                // get MilStdAttributes
117                                if (attributes.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0)
118                                {
119                                        symStd = Integer.parseInt(attributes
120                                                        .get(MilStdAttributes.SymbologyStandard));
121                                }
122
123                                if (symStd > RendererSettings.Symbology_2525B)
124                                {
125                                        char affiliation = symbolID.charAt(1);
126                                        switch (affiliation)
127                                        {
128                                        case 'P':
129                                        case 'A':
130                                        case 'S':
131                                        case 'G':
132                                        case 'M':
133                                                frameAssumeIndex = fillIndex + 2;
134                                                break;
135                                        }
136                                        /*
137                                         * if (frameAssumeIndex > 0) { frameAssume = (char)
138                                         * (frameAssumeIndex); }
139                                         */
140                                }
141
142                                if (attributes.indexOfKey(MilStdAttributes.PixelSize) >= 0)
143                                {
144                                        pixelSize = Integer.parseInt(attributes
145                                                        .get(MilStdAttributes.PixelSize));
146                                }
147                                else
148                                {
149                                        pixelSize = RendererSettings.getInstance()
150                                                        .getDefaultPixelSize();
151                                }
152
153                                if (attributes.indexOfKey(MilStdAttributes.KeepUnitRatio) >= 0)
154                                {
155                                        keepUnitRatio = Boolean.parseBoolean(attributes
156                                                        .get(MilStdAttributes.KeepUnitRatio));
157                                }
158
159                                if (attributes.indexOfKey(MilStdAttributes.DrawAsIcon) >= 0)
160                                {
161                                        icon = Boolean.parseBoolean(attributes
162                                                        .get(MilStdAttributes.DrawAsIcon));
163                                }
164
165                                if (icon)// icon won't show modifiers or display icons
166                                {
167                                        keepUnitRatio = false;
168                                        hasDisplayModifiers = false;
169                                        hasTextModifiers = false;
170                                        symbolID = symbolID.substring(0, 10) + "-----";
171                                }
172                                else
173                                {
174                                        hasDisplayModifiers = ModifierRenderer.hasDisplayModifiers(
175                                                        symbolID, modifiers);
176                                        hasTextModifiers = ModifierRenderer.hasTextModifiers(
177                                                        symbolID, modifiers, attributes);
178                                }
179
180                                if (attributes.indexOfKey(MilStdAttributes.LineColor) >= 0)
181                                {
182                                        lineColor = new Color(
183                                                        attributes.get(MilStdAttributes.LineColor));
184                                }
185                                if (attributes.indexOfKey(MilStdAttributes.FillColor) >= 0)
186                                {
187                                        fillColor = new Color(
188                                                        attributes.get(MilStdAttributes.FillColor));
189                                }
190
191                        }
192                        catch (Exception excModifiers)
193                        {
194                                ErrorLogger.LogException("MilStdIconRenderer", "RenderUnit",
195                                                excModifiers);
196                        }
197
198                        UnitFontLookupInfo ufli = UnitFontLookup.getInstance()
199                                        .getLookupInfo(symbolID, 0);
200                        fillIndex = UnitFontLookup.getFillCode(symbolID,symStd);
201                        frameIndex = UnitFontLookup.getFrameCode(symbolID, fillIndex);
202                        if (ufli != null)
203                        {
204                                symbol1Index = ufli.getMapping1(symbolID);
205                                symbol2Index = ufli.getMapping2();
206                        }
207
208                        if (fillIndex > 0)
209                        {
210                                svgFill = UnitSVGTable.getInstance().getSVGPath(
211                                                String.valueOf(fillIndex));
212                        }
213                        if (frameIndex > 0)
214                        {
215                                svgFrame = UnitSVGTable.getInstance().getSVGPath(
216                                                String.valueOf(frameIndex));
217                        }
218                        if (symbol1Index > 0)
219                        {
220                                svgSymbol1 = UnitSVGTable.getInstance().getSVGPath(
221                                                String.valueOf(symbol1Index));
222                        }
223                        if (symbol2Index > 0)
224                        {
225                                svgSymbol2 = UnitSVGTable.getInstance().getSVGPath(
226                                                String.valueOf(symbol2Index));
227                        }
228
229                        // get dimensions for this symbol given the font size & fill index
230                        Matrix matrix = null;
231                        double heightL = 1;
232                        double widthL = 1;
233
234                        if (keepUnitRatio)
235                        {
236                                RectF rectFrame = svgFrame.getBounds();
237                                double ratio = pixelSize / L1_5 / 1.5;
238                                widthL = UnitFontLookup.getUnitRatioWidth(fillIndex);
239                                heightL = UnitFontLookup.getUnitRatioHeight(fillIndex);
240                                if (widthL > heightL)
241                                {
242                                        ratio = ratio * widthL;
243                                }
244                                else
245                                {
246                                        ratio = ratio * heightL;
247                                }
248                                pixelSize = (int) ((ratio * L1_5) + 0.5);
249
250                        }
251
252                        matrix = svgFrame.TransformToFitDimensions(pixelSize, pixelSize);
253
254                        RectF rectF = svgFrame.getBounds();
255
256                        int w = (int) (rectF.width() + 1.5f);
257                        int h = (int) (rectF.height() + 1.5f);
258                        coreBMP = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
259                        Point centerPoint = new Point(w / 2, h / 2);
260
261                        // draw location
262                        PointF location = new PointF(0, 0);
263                        location.x = (rectF.width() / 2.0f);// +0.5f;//use 0.5f to round up
264                        location.y = -(rectF.height() / 2.0f);
265
266                        // get & setup graphics object for destination BMP
267                        g = new Canvas(coreBMP);
268
269                        // draw symbol to BMP
270                        if (svgFill != null)
271                        {
272                                svgFill.Transform(matrix);
273                                svgFill.Draw(g, null, 0, fillColor, null);
274                        }
275                        if (svgFrame != null)
276                        {
277                                svgFrame.Draw(g, null, 0, lineColor, null);
278                        }
279                        if (svgSymbol2 != null)
280                        {
281                                svgSymbol2.Draw(g, null, 0, ufli.getColor2(), matrix);
282                        }
283                        if (svgSymbol1 != null)
284                        {
285                                svgSymbol1.Draw(g, null, 0, ufli.getColor1(), matrix);
286                        }
287
288                        RectF coreDimensions = new RectF(0, 0, w, h);
289                        Rect finalDimensions = new Rect(0, 0, w, h);
290
291                        // adjust centerpoint for HQStaff if present
292                        if (SymbolUtilities.isHQ(symbolID))
293                        {
294                                Point point1 = new Point();
295                                Point point2 = new Point();
296                                String affiliation = symbolID.substring(1, 2);
297                                if (affiliation == ("F") || affiliation == ("A")
298                                                || affiliation == ("D") || affiliation == ("M")
299                                                || affiliation == ("J") || affiliation == ("K")
300                                                || affiliation == ("N") || affiliation == ("L"))
301                                {
302                                        point1.x = 0;
303                                        point1.y = (coreBMP.getHeight());
304                                        point2.x = point1.x;
305                                        point2.y = point1.y + coreBMP.getHeight();
306                                }
307                                else
308                                {
309                                        point1.x = 1;
310                                        point1.y = (coreBMP.getHeight() / 2);
311                                        point2.x = point1.x;
312                                        point2.y = point1.y + coreBMP.getHeight();
313                                }
314                                centerPoint = point2;
315                        }
316
317                        // process display modifiers
318                        // List<PathInfo> shapes = null;// new
319                        // List<SECRendererUtils.PathInfo>();
320                        // shapes = ProcessUnitDisplayModifiers(symbolID, bmp, modifiers,
321                        // attributes);
322                        // process label modifiers
323                        finalBmp = Bitmap.createBitmap(finalDimensions.right,
324                                        finalDimensions.bottom, Bitmap.Config.ARGB_8888);
325                        Canvas dest = new Canvas(finalBmp);
326
327                        dest.drawBitmap(coreBMP, new Matrix(), null);
328                        // bool success = GDI.CopyImage(coreBMP, finalBmp,
329                        // (int)(coreDimensions.X), (int)(coreDimensions.Y));
330
331                        Rect symbolBounds = new Rect(0, 0, finalBmp.getWidth(),
332                                        finalBmp.getHeight());
333                        ImageInfo ii = new ImageInfo(finalBmp, new Point(centerPoint.x,
334                                        centerPoint.y), symbolBounds);
335
336                        // test
337                        // ////
338                        // return ii;
339
340                        // //////////////////////////////////////////////////////////////////
341                        ImageInfo iinew = null;
342                        // process display modifiers
343                        if (hasDisplayModifiers)
344                        {
345                                iinew = ModifierRenderer.processUnitDisplayModifiers(ii,
346                                                symbolID, modifiers, hasTextModifiers, attributes);
347                        }
348
349                        if (iinew != null)
350                        {
351                                ii = iinew;
352                        }
353                        iinew = null;
354
355                        // process text modifiers
356                        if (hasTextModifiers)
357                        {
358                                iinew = ModifierRenderer.processUnitTextModifiers(ii, symbolID,modifiers, attributes);
359                        }
360
361                        if (iinew != null)
362                        {
363                                ii = iinew;
364                        }
365                        iinew = null;
366
367                        // cleanup///////////////////////////////////////////////////////////
368                        // bmp.recycle();
369
370                        // //////////////////////////////////////////////////////////////////
371
372                        if (icon == true)
373                        {
374                                return ii.getSquareImageInfo();
375                        }
376                        else
377                        {
378                                return ii;
379                        }
380                }
381                catch (Exception exc)
382                {
383                        ErrorLogger.LogException("SinglePointSVGRenderer", "RenderUnit",
384                                        exc);
385                        return null;
386                }
387        }
388
389        /**
390         * 
391         * @param symbolID
392         * @param modifiers
393         * @return
394         */
395        @SuppressWarnings("unused")
396        public ImageInfo RenderSP(String symbolID, SparseArray<String> modifiers)
397        {
398                ImageInfo temp = null;
399                String basicSymbolID = null;
400                float fontSize = RendererSettings.getInstance().getSPFontSize();
401                Color lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID);
402                Color fillColor = null;// SymbolUtilities.getFillColorOfAffiliation(symbolID);
403                int alpha = -1;
404
405                int symStd = RendererSettings.getInstance().getSymbologyStandard();
406                // fill character
407                int charFillIndex = -1;
408                // frame character
409                int charFrameIndex = -1;
410
411                SymbolDef sd = null;
412
413                Paint fillPaint = null;
414                Paint framePaint = null;
415
416                SinglePointLookupInfo lookup = null;
417
418                Rect symbolBounds = null;
419                RectF fullBounds = null;
420                Bitmap fullBMP = null;
421
422                try
423                {
424                        if (modifiers == null)
425                        {
426                                modifiers = new SparseArray<String>();
427                        }
428                        // get MilStdAttributes
429                        if (modifiers.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0)
430                        {
431                                symStd = Integer.parseInt(modifiers
432                                                .get(MilStdAttributes.SymbologyStandard));
433                        }
434
435                        // get symbol info
436                        basicSymbolID = SymbolUtilities.getBasicSymbolID(symbolID);
437                        lookup = SinglePointLookup.getInstance().getSPLookupInfo(
438                                        basicSymbolID, symStd);
439                        if (lookup == null)// if lookup fails, fix code/use unknown symbol
440                                                                // code.
441                        {
442                                // if symbolID bad, do best to find a workable code
443                                if (modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1) != null)
444                                {
445                                        modifiers.put(ModifiersTG.H1_ADDITIONAL_INFO_2,
446                                                        modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1));
447                                }
448                                modifiers.put(ModifiersTG.H_ADDITIONAL_INFO_1,
449                                                symbolID.substring(0, 10));
450
451                                symbolID = "G" + SymbolUtilities.getAffiliation(symbolID) + "G"
452                                                + SymbolUtilities.getStatus(symbolID) + "GPP---****X";
453                                lookup = SinglePointLookup.getInstance().getSPLookupInfo(
454                                                basicSymbolID, symStd);
455                                lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID);
456                                fillColor = null;// SymbolUtilities.getFillColorOfAffiliation(symbolID);
457                        }
458
459                        if (modifiers.indexOfKey(MilStdAttributes.LineColor) >= 0)
460                        {
461                                lineColor = new Color(modifiers.get(MilStdAttributes.LineColor));
462                        }
463                        if (modifiers.indexOfKey(MilStdAttributes.FillColor) >= 0)
464                        {
465                                lineColor = new Color(modifiers.get(MilStdAttributes.FillColor));
466                        }
467
468                        if (SymbolUtilities.isTGSPWithFill(symbolID) && fillColor != null)
469                        {
470                                fillPaint = new Paint();
471                                fillPaint.setStyle(Paint.Style.FILL);
472                                fillPaint.setColor(fillColor.toARGB());
473                                fillPaint.setTextSize(fontSize);
474                                fillPaint.setAntiAlias(true);
475                                fillPaint.setTextAlign(Align.CENTER);
476                                fillPaint.setTypeface(_tfSP);
477                        }
478
479                        framePaint = new Paint();
480                        framePaint.setStyle(Paint.Style.FILL);
481                        framePaint.setColor(lineColor.toARGB());
482                        framePaint.setTextSize(fontSize);
483                        framePaint.setAntiAlias(true);
484                        framePaint.setTextAlign(Align.CENTER);
485                        framePaint.setTypeface(_tfSP);
486
487                        // Check if we need to set 'N' to "ENY"
488                        if (symbolID.charAt(1) == 'H'
489                                        && modifiers.indexOfKey(MilStdAttributes.DrawAsIcon) >= 0
490                                        && (Boolean.parseBoolean(modifiers
491                                                        .get(MilStdAttributes.DrawAsIcon)) == false))
492                        {
493                                modifiers.put(ModifiersTG.N_HOSTILE, "ENY");
494                        }
495
496                }
497                catch (Exception excModifiers)
498                {
499                        ErrorLogger.LogException("MilStdIconRenderer", "RenderUnit",
500                                        excModifiers);
501                }
502
503                try
504                {
505                        // get fill character
506                        // get frame character
507                        // get symbol info
508                        charFrameIndex = -1;// SinglePointLookup.instance.getCharCodeFromSymbol(symbolID);
509                        charFillIndex = -1;
510
511                        if (SymbolUtilities.getStatus(symbolID).equals("A"))
512                        {
513                                charFrameIndex = lookup.getMappingA();
514                        }
515                        else
516                        {
517                                charFrameIndex = lookup.getMappingP();
518                        }
519
520                        if (SymbolUtilities.isTGSPWithFill(symbolID) && fillColor != null)
521                        {
522                                String fillID = SymbolUtilities.getTGFillSymbolCode(symbolID);
523                                if (fillID != null)
524                                {
525                                        charFillIndex = SinglePointLookup.getInstance()
526                                                        .getCharCodeFromSymbol(fillID, symStd);
527                                }
528                        }
529
530                        // dimensions of the unit at specified font size
531                        RectF rect = new RectF(0, 0, lookup.getWidth(), lookup.getHeight());
532
533                        if (fontSize != 60.0)// adjust boundaries ratio if font size is not
534                                                                        // at the default setting.
535                        {
536                                double ratio = fontSize / 60;
537
538                                rect = new RectF(0, 0, Math.round(rect.width() * ratio),
539                                                Math.round(rect.height() * ratio));
540                        }
541
542                        boolean symbolOutlineEnabled = false;
543                        int symbolOutlineSize = RendererSettings.getInstance()
544                                        .getSinglePointSymbolOutlineWidth();
545                        if (symbolOutlineEnabled == false)
546                        {
547                                symbolOutlineSize = 0;
548                        }
549
550                        // matrix to place the symbol centered in the MilStdBmp
551                        Matrix matrix = new Matrix();
552                        Point centerPoint = null;
553                        centerPoint = SymbolDimensions.getSymbolCenter(
554                                        lookup.getBasicSymbolID(), rect);
555                        matrix.postTranslate(centerPoint.x, centerPoint.y);
556
557                        if (symbolOutlineEnabled)
558                        { // adjust matrix and centerpoint to account for outline if present
559                                matrix.postTranslate(symbolOutlineSize, symbolOutlineSize);
560                                centerPoint.offset(symbolOutlineSize, symbolOutlineSize);
561                                rect = new RectF(0, 0,
562                                                (rect.width() + (symbolOutlineSize * 2)),
563                                                (rect.height() + (symbolOutlineSize * 2)));
564                        }
565
566                        // Draw glyphs to bitmap
567                        Bitmap bmp = Bitmap.createBitmap((int) (rect.width() + 0.5),
568                                        (int) (rect.height() + 0.5), Config.ARGB_8888);
569                        Canvas canvas = new Canvas(bmp);
570
571                        symbolBounds = new Rect(0, 0, bmp.getWidth(), bmp.getHeight());
572
573                        String strFill = null;
574                        String strFrame = null;
575                        if (charFillIndex > 0)
576                        {
577                                strFill = String.valueOf((char) charFillIndex);
578                        }
579                        if (charFrameIndex > 0)
580                        {
581                                strFrame = String.valueOf((char) charFrameIndex);
582                        }
583
584                        canvas.setMatrix(matrix);
585                        if (strFill != null)
586                        {
587                                canvas.drawText(strFill, 0, 0, fillPaint);
588                        }
589                        if (strFrame != null)
590                        {
591                                canvas.drawText(strFrame, 0, 0, framePaint);
592                        }
593                        ImageInfo ii = new ImageInfo(bmp, centerPoint, symbolBounds);
594
595                        List<ModifierInfo> shapes = new ArrayList<ModifierInfo>();
596                        ModifierInfo miTemp = null;
597
598                        // process integral text
599                        if (modifiers != null
600                                        && modifiers.indexOfKey(MilStdAttributes.DrawAsIcon) >= 0
601                                        && (Boolean.parseBoolean(modifiers
602                                                        .get(MilStdAttributes.DrawAsIcon)) == false))// if
603                                                                                                                                                        // drawAsIcon,
604                                                                                                                                                        // don't
605                                                                                                                                                        // draw.
606                        {
607                                /*
608                                 * miTemp = CreateTGSPIntegralText(symbolID, symbolBounds,
609                                 * lineColor); if(miTemp != null) shapes.addAll(miTemp); miTemp
610                                 * = null//
611                                 */
612                        }
613
614                        // draw modifiers
615                        /*
616                         * if(SymbolUtilities.isTGSPWithSpecialModifierLayout(symbolID)) {
617                         * miTemp = ProcessSPTGSpecialModifiers(symbolID, symbolBounds,
618                         * modifiers,lineColor);
619                         * 
620                         * } else { miTemp = ProcessSPTGModifiers(symbolID, symbolBounds,
621                         * modifiers,lineColor); } if(miTemp != null) shapes.addAll(miTemp);
622                         * miTemp = null
623                         * 
624                         * //draw direction of movement arrow if(modifiers != null &&
625                         * modifiers[ModifiersUnits.Q_DIRECTION_OF_MOVEMENT] != null) {
626                         * miTemp = CreateDirectionOfMovementArrow(symbolID, symbolBounds,
627                         * modifiers); if(miTemp != null) shapes.addItem(miTemp); }//
628                         */
629                        // get full bounds
630                        // draw modifiers
631                        // get full bounds
632                        float ULX = 0;
633                        float ULY = 0;
634                        float LRX = symbolBounds.width();
635                        float LRY = symbolBounds.height();
636                        int offset = 0;
637                        int outlineSize = RendererSettings.getInstance()
638                                        .getTextOutlineWidth();
639                        int shapesLength = shapes.size();
640
641                        if (shapes != null && shapesLength > 0)
642                        {
643                                for (int i = 0; i < shapesLength; i++)
644                                {
645                                        if (shapes.get(i).getText() != null)
646                                        {
647                                                miTemp = shapes.get(i);
648                                                if (miTemp.getKey() == "shadow")
649                                                {
650                                                        offset = outlineSize;
651                                                }
652                                                else
653                                                {
654                                                        offset = 0;
655                                                }
656
657                                                RectF rTemp = miTemp.getBounds();
658                                                Paint pTemp = miTemp.getPaint();
659
660                                                if ((rTemp.left - offset) < ULX)
661                                                {
662                                                        ULX = rTemp.left - offset;
663                                                }
664                                                if (rTemp.top - rTemp.height() - offset < ULY)
665                                                {
666                                                        ULY = rTemp.top - rTemp.height() - offset;
667                                                }
668                                                if (rTemp.left + rTemp.width() + offset > LRX)
669                                                {
670                                                        LRX = Math.round(rTemp.left) + rTemp.width()
671                                                                        + offset;
672                                                }
673                                                if (rTemp.top + offset > LRY)
674                                                {
675                                                        LRY = Math.round(rTemp.top) + pTemp.descent()
676                                                                        + offset;
677                                                }
678                                        }
679                                        else if (shapes.get(i).getShape() != null)
680                                        {
681                                                miTemp = shapes.get(i);
682                                                RectF rTemp = miTemp.getBounds();
683                                                if (rTemp.left < ULX)
684                                                {
685                                                        ULX = Math.round(rTemp.left);
686                                                }
687                                                if (rTemp.top < ULY)
688                                                {
689                                                        ULY = Math.round(rTemp.top);
690                                                }
691                                                if (rTemp.left + rTemp.width() > LRX)
692                                                {
693                                                        LRX = Math.round(rTemp.left + rTemp.width());
694                                                }
695                                                if (rTemp.top + rTemp.height() > LRY)
696                                                {
697                                                        LRY = Math.round(rTemp.top + rTemp.height());
698                                                }
699                                        }
700                                }
701                        }
702
703                        fullBounds = new RectF(0, 0, LRX - ULX, LRY - ULY);
704                        Matrix centerMatrix = new Matrix();
705
706                        int transX = 0;
707                        int transY = 0;
708                        if (ULX < 0)
709                        {
710                                transX = (int) (ULX * -1);
711                        }
712                        if (ULY < 0)
713                        {
714                                transY = (int) (ULY * -1);
715                        }
716                        centerMatrix = new Matrix();
717                        centerMatrix.reset();
718                        centerMatrix.postTranslate(transX, transY);
719
720                        fullBMP = Bitmap.createBitmap((int) fullBounds.width(),
721                                        (int) fullBounds.height(), Config.ARGB_8888);
722                        Canvas fullCanvas = new Canvas(fullBMP);
723                        Matrix tempMatrix = null;
724
725                        if (shapes != null && shapesLength > 0)
726                        {
727                                for (int j = 0; j < shapesLength; j++)
728                                {
729                                        tempMatrix = new Matrix();
730                                        tempMatrix.reset();
731                                        if (shapes.get(j).getText() != null)
732                                        {
733
734                                                miTemp = shapes.get(j);
735                                                PointF drawPoint = miTemp.getDrawPoint();
736                                                tempMatrix.postTranslate((int) drawPoint.x,
737                                                                (int) drawPoint.y);
738                                                tempMatrix.postTranslate(transX, transY);
739                                                if (miTemp.getKey().equals("shadow"))
740                                                {
741                                                        // DrawOutline(fullBMP, miTemp, tempMatrix);
742                                                }
743                                                else
744                                                {
745                                                        fullCanvas.setMatrix(tempMatrix);// matrix handles
746                                                                                                                                // positioning.
747                                                        fullCanvas.drawText(miTemp.getText(), 0, 0,
748                                                                        miTemp.getPaint());
749                                                }
750                                        }
751                                        else if (shapes.get(j).getShape() != null)
752                                        {
753                                                miTemp = shapes.get(j);
754
755                                                tempMatrix.postTranslate((int) transX, (int) transY);
756
757                                                fullCanvas.setMatrix(tempMatrix);// matrix handles
758                                                                                                                        // positioning.
759                                                miTemp.getShape().draw(fullCanvas, miTemp.getPaint());
760                                        }
761                                }
762                        }
763
764                        Paint ptCopy = new Paint();
765                        ptCopy.setAntiAlias(false);
766                        fullCanvas.drawBitmap(bmp, transX, transY, ptCopy);
767
768                        centerPoint.x = centerPoint.x + transX;
769                        centerPoint.y = centerPoint.y + transY;
770                        symbolBounds = new Rect(transX, transY, symbolBounds.width(),
771                                        symbolBounds.height());
772
773                        ii = new ImageInfo(fullBMP, centerPoint, symbolBounds);
774
775                        // cleanup
776                        bmp.recycle();
777                        bmp = null;
778                        canvas = null;
779                        symbolBounds = null;
780                        fullBMP = null;
781                        fullBounds = null;
782                        fullCanvas = null;
783                        centerPoint = null;
784                        fillPaint = null;
785                        framePaint = null;
786
787                        lookup = null;
788
789                        return ii;
790
791                }
792                catch (Exception exc)
793                {
794                        ErrorLogger.LogException("MilStdIconRenderer", "RenderSP", exc);
795                }
796                return temp;
797        }
798
799        /**
800         * Tries to get a valid UnitFontLookupInfo object when the symbolID is
801         * poorly formed or there's no match in the lookup. Use this if you get a
802         * null return value from:
803         * "UnitFontLookupC.getInstance().getLookupInfo(symbolID)" or "CanRender"
804         * returns false.
805         * 
806         * @param symbolID
807         * @return
808         */
809        private UnitFontLookupInfo ResolveUnitFontLookupInfo(String symbolID,
810                        int symStd)
811        {
812                String id = symbolID;
813                UnitFontLookupInfo lookup = null;
814                String affiliation = "";
815                String status = "";
816                if (id != null && id.length() >= 10)// if lookup fails, fix code/use
817                                                                                        // unknown symbol code.
818                {
819                        StringBuilder sb = new StringBuilder("");
820                        sb.append(id.charAt(0));
821
822                        if (SymbolUtilities.hasValidAffiliation(id) == false)
823                        {
824                                sb.append('U');
825                                affiliation = "U";
826                        }
827                        else
828                        {
829                                sb.append(id.charAt(1));
830                                affiliation = id.substring(1, 2);
831                        }
832
833                        if (SymbolUtilities.hasValidBattleDimension(id) == false)
834                        {
835                                sb.append('Z');
836                                sb.replace(0, 1, "S");
837                        }
838                        else
839                        {
840                                sb.append(id.charAt(2));
841                        }
842
843                        if (SymbolUtilities.hasValidStatus(id) == false)
844                        {
845                                sb.append('P');
846                                status = "P";
847                        }
848                        else
849                        {
850                                sb.append(id.charAt(3));
851                                status = id.substring(3, 4);
852                        }
853
854                        sb.append("------");
855                        if (id.length() >= 15)
856                        {
857                                sb.append(id.substring(10, 15));
858                        }
859                        else
860                        {
861                                sb.append("*****");
862                        }
863                        id = sb.toString();
864
865                        lookup = UnitFontLookup.getInstance().getLookupInfo(id, symStd);
866                }
867                else if (symbolID == null || symbolID.equals(""))
868                {
869                        lookup = UnitFontLookup.getInstance().getLookupInfo(
870                                        "SUZP------*****", symStd);
871                }
872                return lookup;
873        }
874
875        public Bitmap getTestSymbol()
876        {
877                Bitmap temp = null;
878                try
879                {
880                        temp = Bitmap.createBitmap(70, 70, Config.ARGB_8888);
881
882                        Canvas canvas = new Canvas(temp);
883
884                        if (canvas.isHardwareAccelerated())
885                        {
886                                System.out.println("HW acceleration supported");
887                        }
888                        // canvas.drawColor(Color.WHITE);
889
890                        // Typeface tf = Typeface.createFromAsset(_am,
891                        // "fonts/unitfonts.ttf");
892                        Typeface tf = _tfUnits;
893
894                        Paint fillPaint = new Paint();
895                        fillPaint.setStyle(Paint.Style.FILL);
896                        fillPaint.setColor(Color.CYAN.toInt());
897                        fillPaint.setTextSize(50);
898                        fillPaint.setAntiAlias(true);
899                        fillPaint.setTextAlign(Align.CENTER);
900                        fillPaint.setTypeface(tf);
901
902                        Paint framePaint = new Paint();
903                        framePaint.setStyle(Paint.Style.FILL);
904                        framePaint.setColor(Color.BLACK.toInt());
905                        framePaint.setTextSize(50);
906                        framePaint.setAntiAlias(true);
907                        framePaint.setTextAlign(Align.CENTER);
908                        framePaint.setTypeface(tf);
909
910                        Paint symbolPaint = new Paint();
911                        symbolPaint.setStyle(Paint.Style.FILL);
912                        symbolPaint.setColor(Color.BLACK.toInt());
913                        symbolPaint.setTextSize(50);
914                        symbolPaint.setAntiAlias(true);
915                        symbolPaint.setTextAlign(Align.CENTER);
916                        symbolPaint.setTypeface(tf);
917
918                        String strFill = String.valueOf((char) 800);
919                        String strFrame = String.valueOf((char) 801);
920                        String strSymbol = String.valueOf((char) 1121);
921
922                        canvas.drawText(strFill, 35, 35, fillPaint);
923                        canvas.drawText(strFrame, 35, 35, framePaint);
924                        canvas.drawText(strSymbol, 35, 35, symbolPaint);
925
926                        FontMetrics mf = framePaint.getFontMetrics();
927                        float height = mf.bottom - mf.top;
928                        float width = fillPaint.measureText(strFrame);
929
930                        Log.i(TAG, "top: " + String.valueOf(mf.top));
931                        Log.i(TAG, "bottom: " + String.valueOf(mf.bottom));
932                        Log.i(TAG, "ascent: " + String.valueOf(mf.ascent));
933                        Log.i(TAG, "descent: " + String.valueOf(mf.descent));
934                        Log.i(TAG, "leading: " + String.valueOf(mf.leading));
935                        Log.i(TAG, "width: " + String.valueOf(width));
936                        Log.i(TAG, "height: " + String.valueOf(height));
937
938                }
939                catch (Exception exc)
940                {
941                        Log.e(TAG, exc.getMessage());
942                        Log.e(TAG, getStackTrace(exc));
943                }
944
945                return temp;
946        }// */
947
948        public void logError(String tag, Throwable thrown)
949        {
950                if (tag == null || tag == "")
951                {
952                        tag = "singlePointRenderer";
953                }
954
955                String message = thrown.getMessage();
956                String stack = getStackTrace(thrown);
957                if (message != null)
958                {
959                        Log.e(tag, message);
960                }
961                if (stack != null)
962                {
963                        Log.e(tag, stack);
964                }
965        }
966
967        public String getStackTrace(Throwable thrown)
968        {
969                try
970                {
971                        if (thrown != null)
972                        {
973                                if (thrown.getStackTrace() != null)
974                                {
975                                        String eol = System.getProperty("line.separator");
976                                        StringBuilder sb = new StringBuilder();
977                                        sb.append(thrown.toString());
978                                        sb.append(eol);
979                                        for (StackTraceElement element : thrown.getStackTrace())
980                                        {
981                                                sb.append("        at ");
982                                                sb.append(element);
983                                                sb.append(eol);
984                                        }
985                                        return sb.toString();
986                                }
987                                else
988                                {
989                                        return thrown.getMessage() + "- no stack trace";
990                                }
991                        }
992                        else
993                        {
994                                return "no stack trace";
995                        }
996                }
997                catch (Exception exc)
998                {
999                        Log.e("getStackTrace", exc.getMessage());
1000                }
1001                return thrown.getMessage();
1002        }// */
1003        /*
1004         * private static String PrintList(ArrayList list) { String message = "";
1005         * for(Object item : list) {
1006         * 
1007         * message += item.toString() + "\n"; } return message; }//
1008         */
1009        /*
1010         * private static String PrintObjectMap(Map<String, Object> map) {
1011         * Iterator<Object> itr = map.values().iterator(); String message = "";
1012         * String temp = null; while(itr.hasNext()) { temp =
1013         * String.valueOf(itr.next()); if(temp != null) message += temp + "\n"; }
1014         * //ErrorLogger.LogMessage(message); return message; }//
1015         */
1016
1017}