001package armyc2.c2sd.renderer;
002
003import android.graphics.Bitmap;
004import android.graphics.Bitmap.Config;
005import android.graphics.Canvas;
006import android.graphics.Matrix;
007import android.graphics.Paint;
008import android.graphics.Point;
009import android.graphics.PointF;
010import android.graphics.Rect;
011import android.graphics.RectF;
012import android.graphics.Paint.Align;
013import android.graphics.Paint.FontMetrics;
014import android.graphics.Typeface;
015import android.os.Environment;
016import android.util.Log;
017import android.util.LruCache;
018import android.util.SparseArray;
019
020import java.io.File;
021import java.io.FileOutputStream;
022import java.io.OutputStream;
023
024import armyc2.c2sd.renderer.utilities.Color;
025import armyc2.c2sd.renderer.utilities.ErrorLogger;
026import armyc2.c2sd.renderer.utilities.FontManager;
027import armyc2.c2sd.renderer.utilities.ImageInfo;
028import armyc2.c2sd.renderer.utilities.MilStdAttributes;
029import armyc2.c2sd.renderer.utilities.ModifiersTG;
030import armyc2.c2sd.renderer.utilities.RectUtilities;
031import armyc2.c2sd.renderer.utilities.RendererSettings;
032import armyc2.c2sd.renderer.utilities.RendererUtilities;
033import armyc2.c2sd.renderer.utilities.SettingsChangedEvent;
034import armyc2.c2sd.renderer.utilities.SettingsChangedEventListener;
035import armyc2.c2sd.renderer.utilities.SinglePointLookup;
036import armyc2.c2sd.renderer.utilities.SinglePointLookupInfo;
037import armyc2.c2sd.renderer.utilities.SymbolDef;
038import armyc2.c2sd.renderer.utilities.SymbolDimensions;
039import armyc2.c2sd.renderer.utilities.SymbolUtilities;
040import armyc2.c2sd.renderer.utilities.UnitFontLookup;
041import armyc2.c2sd.renderer.utilities.UnitFontLookupInfo;
042
043public class SinglePointRenderer implements SettingsChangedEventListener
044{
045
046    private final String TAG = "SinglePointRenderer";
047    private static SinglePointRenderer _instance = null;
048
049    private Typeface _tfUnits = null;
050    private Typeface _tfSP = null;
051    private Typeface _tfTG = null;
052
053    private final Object _SinglePointFontMutex = new Object();
054    private final Object _UnitFontMutex = new Object();
055    private final Object _ModifierFontMutex = new Object();
056
057    private final Object _SinglePointCacheMutex = new Object();
058    private final Object _UnitCacheMutex = new Object();
059
060    private Paint _modifierFont = new Paint();
061    private Paint _modifierOutlineFont = new Paint();
062    private float _modifierDescent = 2;
063    private float _modifierFontHeight = 10;
064    private int _deviceDPI = 72;
065
066    //private LruCache<String, ImageInfo> _unitCache = new LruCache<String, ImageInfo>(15);
067    //private LruCache<String, ImageInfo> _tgCache = new LruCache<String, ImageInfo>(7);
068    private LruCache<String, ImageInfo> _unitCache = new LruCache<String, ImageInfo>(1024);
069    private LruCache<String, ImageInfo> _tgCache = new LruCache<String, ImageInfo>(1024);
070    private final int maxMemory = (int) (Runtime.getRuntime().maxMemory());// / 1024);
071    private int cacheSize = 5;//RendererSettings.getInstance().getCacheSize() / 2;
072    private int maxCachedEntrySize = cacheSize / 5;
073    private boolean cacheEnabled = RendererSettings.getInstance().getCacheEnabled();
074
075    private SinglePointRenderer()
076    {
077        _tfUnits = FontManager.getInstance().getTypeface(FontManager.FONT_UNIT);
078        _tfSP = FontManager.getInstance().getTypeface(FontManager.FONT_SPTG);
079        _tfTG = FontManager.getInstance().getTypeface(FontManager.FONT_MPTG);
080        TacticalGraphicIconRenderer.setTGTypeFace(_tfTG);
081        RendererSettings.getInstance().addEventListener(this);
082
083
084        //get modifier font values.
085        onSettingsChanged(new SettingsChangedEvent(SettingsChangedEvent.EventType_FontChanged));
086        //set cache
087        onSettingsChanged(new SettingsChangedEvent(SettingsChangedEvent.EventType_CacheSizeChanged));
088
089
090        
091    }
092
093    public static synchronized SinglePointRenderer getInstance()
094    {
095        if (_instance == null)
096        {
097            _instance = new SinglePointRenderer();
098        }
099
100        return _instance;
101    }
102
103    /**
104     *
105     * @param symbolID
106     * @param modifiers
107     * @return
108     */
109    public ImageInfo RenderUnit(String symbolID, SparseArray<String> modifiers, SparseArray<String> attributes)
110    {
111        ImageInfo temp = null;
112
113        float fontSize = RendererSettings.getInstance().getUnitFontSize();
114        Color lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID);
115        Color fillColor = SymbolUtilities.getFillColorOfAffiliation(symbolID);
116        Color iconColor = null;
117        int alpha = -1;
118
119        int symStd = RendererSettings.getInstance().getSymbologyStandard();
120        //get fill character
121        int charFillIndex = -1;
122        //get frame character
123        int charFrameIndex = -1;
124        int charSymbol1Index = -1;
125        int charSymbol2Index = -1;
126        int charFrameAssumeIndex = -1;
127        char frameAssume;
128
129        Paint fillPaint = null;
130        Paint framePaint = null;
131        Paint symbol1Paint = null;
132        Paint symbol2Paint = null;
133        Paint frameAssumePaint = null;
134
135        UnitFontLookupInfo lookup = null;
136
137        Rect symbolBounds = null;
138        Rect fullBounds = null;
139        Bitmap fullBMP = null;
140
141        boolean hasDisplayModifiers = false;
142        boolean hasTextModifiers = false;
143
144        int pixelSize = -1;
145        boolean keepUnitRatio = true;
146        boolean icon = false;
147        float[] dimensions =
148        {
149            0f, 0f, 0f, 0f
150        };
151
152        try
153        {
154
155            //check for symbology standard override.
156            if (attributes.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0)
157            {
158                symStd = Integer.parseInt(attributes.get(MilStdAttributes.SymbologyStandard));
159            }
160            //get fill character
161            charFillIndex = UnitFontLookup.getFillCode(symbolID, symStd);
162            //get frame character
163            charFrameIndex = UnitFontLookup.getFrameCode(symbolID, charFillIndex);
164
165            if (symStd > RendererSettings.Symbology_2525B)
166            {
167                char affiliation = symbolID.charAt(1);
168                switch (affiliation)
169                {
170                    case 'P':
171                    case 'A':
172                    case 'S':
173                    case 'G':
174                    case 'M':
175                        if(symbolID.charAt(2) == 'U' &&
176                                (symbolID.substring(4, 6).equals("WM") ||
177                                 symbolID.substring(4, 7).equals("WDM")))
178                        {
179                            if(symbolID.charAt(3) != 'A')
180                            {
181                                charFillIndex++;
182                            }
183                            charFrameAssumeIndex = charFillIndex - 1;
184                            charFrameIndex = -1;
185                        }
186                        else
187                        {
188                            charFrameIndex = charFillIndex + 2;
189                            charFrameAssumeIndex = charFillIndex + 1;
190                        }
191                        break;
192                }
193                if (charFrameAssumeIndex > 0)
194                {
195                    frameAssume = (char) (charFrameAssumeIndex);
196                }
197            }
198
199            if (attributes.indexOfKey(MilStdAttributes.PixelSize) >= 0)
200            {
201                pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize));
202            }
203            else
204            {
205                pixelSize = RendererSettings.getInstance().getDefaultPixelSize();
206            }
207
208            if (attributes.indexOfKey(MilStdAttributes.KeepUnitRatio) >= 0)
209            {
210                keepUnitRatio = Boolean.parseBoolean(attributes.get(MilStdAttributes.KeepUnitRatio));
211            }
212
213            if (attributes.indexOfKey(MilStdAttributes.DrawAsIcon) >= 0)
214            {
215                icon = Boolean.parseBoolean(attributes.get(MilStdAttributes.DrawAsIcon));
216            }
217
218            if (icon)//icon won't show modifiers or display icons
219            {
220                keepUnitRatio = false;
221                hasDisplayModifiers = false;
222                hasTextModifiers = false;
223                symbolID = symbolID.substring(0, 10) + "-----";
224            }
225            else
226            {
227                hasDisplayModifiers = ModifierRenderer.hasDisplayModifiers(symbolID, modifiers);
228                hasTextModifiers = ModifierRenderer.hasTextModifiers(symbolID, modifiers, attributes);
229            }
230
231            if (attributes.indexOfKey(MilStdAttributes.LineColor) >= 0)
232            {
233                lineColor = new Color(attributes.get(MilStdAttributes.LineColor));
234            }
235            if (attributes.indexOfKey(MilStdAttributes.FillColor) >= 0)
236            {
237                fillColor = new Color(attributes.get(MilStdAttributes.FillColor));
238            }
239            if (attributes.indexOfKey(MilStdAttributes.IconColor) >= 0)
240            {
241                iconColor = new Color(attributes.get(MilStdAttributes.IconColor));
242            }
243            if (attributes.indexOfKey(MilStdAttributes.Alpha) >= 0)
244            {
245                alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha));
246            }
247
248            //get symbol info
249            lookup = UnitFontLookup.getInstance().getLookupInfo(symbolID, symStd);
250            if (lookup == null)//if lookup fails, fix code/use unknown symbol code.
251            {
252                //if symbolID bad, do best to find a workable code
253                lookup = ResolveUnitFontLookupInfo(symbolID, symStd);
254            }
255
256            
257            ////////////////////////////////////////////////////////////////////
258            dimensions = SymbolDimensions.getUnitBounds(charFillIndex, 50);
259            symbolBounds = RectUtilities.makeRect(0f, 0f, dimensions[2], dimensions[3]);
260            Rect rect = new Rect(symbolBounds);
261            float ratio = -1;
262
263            if (pixelSize > 0 && keepUnitRatio == true)
264            {
265                float heightRatio = UnitFontLookup.getUnitRatioHeight(charFillIndex);
266                float widthRatio = UnitFontLookup.getUnitRatioWidth(charFillIndex);
267
268                if (heightRatio > widthRatio)
269                {
270                    pixelSize = (int) ((pixelSize / 1.5f) * heightRatio);
271                }
272                else
273                {
274                    pixelSize = (int) ((pixelSize / 1.5f) * widthRatio);
275                }
276            }
277            if (pixelSize > 0)
278            {
279                float p = pixelSize;
280                float h = rect.height();
281                float w = rect.width();
282
283                ratio = Math.min((p / h), (p / w));
284
285                float fontsize = 50;
286                //ratio = ratio / 72 * 96;
287                fontSize = (((fontsize * ratio)));
288                    //fontSize = (((fontsize * ratio) / 96) * 72);
289                //fontSize = (((fontsize * ratio) / 96) * _deviceDPI);
290
291                //ctx.font= "75pt UnitFontsC";
292                //symbolBounds = SymbolDimensions.getUnitBounds(charFillIndex, (50 * ratio));
293                dimensions = SymbolDimensions.getUnitBounds(charFillIndex, 50 * ratio);
294                symbolBounds = RectUtilities.makeRect(0f, 0f, dimensions[2], dimensions[3]);
295            }//*/
296
297            ////////////////////////////////////////////////////////////////////
298            fillPaint = new Paint();
299            fillPaint.setStyle(Paint.Style.FILL);
300            fillPaint.setColor(fillColor.toARGB());
301            fillPaint.setTextSize(fontSize);
302            fillPaint.setAntiAlias(true);
303            fillPaint.setTextAlign(Align.CENTER);
304            fillPaint.setTypeface(_tfUnits);
305            if(alpha != -1)
306                fillPaint.setAlpha(alpha);
307
308            framePaint = new Paint();
309            framePaint.setStyle(Paint.Style.FILL);
310            framePaint.setColor(lineColor.toARGB());
311            framePaint.setTextSize(fontSize);
312            framePaint.setAntiAlias(true);
313            framePaint.setTextAlign(Align.CENTER);
314            framePaint.setTypeface(_tfUnits);
315            if(alpha != -1)
316                framePaint.setAlpha(alpha);
317
318            symbol1Paint = new Paint();
319            symbol1Paint.setStyle(Paint.Style.FILL);
320            if(iconColor != null)
321            {
322                symbol1Paint.setColor(iconColor.toARGB());
323            }
324            else
325            {
326                symbol1Paint.setColor(lookup.getColor1().toARGB());
327            }
328            symbol1Paint.setTextSize(fontSize);
329            symbol1Paint.setAntiAlias(true);
330            symbol1Paint.setTextAlign(Align.CENTER);
331            symbol1Paint.setTypeface(_tfUnits);
332            if(alpha != -1)
333                symbol1Paint.setAlpha(alpha);
334
335            symbol2Paint = new Paint();
336            symbol2Paint.setStyle(Paint.Style.FILL);
337            symbol2Paint.setColor(lookup.getColor2().toARGB());
338            symbol2Paint.setTextSize(fontSize);
339            symbol2Paint.setAntiAlias(true);
340            symbol2Paint.setTextAlign(Align.CENTER);
341            symbol2Paint.setTypeface(_tfUnits);
342            if(alpha != -1)
343                symbol2Paint.setAlpha(alpha);
344
345            frameAssumePaint = new Paint();
346            frameAssumePaint.setStyle(Paint.Style.FILL);
347            frameAssumePaint.setColor(Color.WHITE.toARGB());
348            frameAssumePaint.setTextSize(fontSize);
349            frameAssumePaint.setAntiAlias(true);
350            frameAssumePaint.setTextAlign(Align.CENTER);
351            frameAssumePaint.setTypeface(_tfUnits);
352            if(alpha != -1)
353                frameAssumePaint.setAlpha(alpha);
354
355            
356          //Just for sea mines
357            if(symbolID.charAt(2) == 'U' &&
358                            symbolID.substring(4, 6).equals("WM"))
359            {
360                if(symStd == RendererSettings.Symbology_2525B)
361                {
362                    fillPaint.setColor(fillColor.toARGB());
363                    if(alpha != -1)
364                        fillPaint.setAlpha(alpha);
365                    symbol1Paint.setColor(lineColor.toARGB());
366                    if(alpha != -1)
367                        symbol1Paint.setAlpha(alpha);
368
369                }
370                else if(symStd == RendererSettings.Symbology_2525C)
371                {
372                        fillPaint.setColor(lineColor.toARGB());
373                    if(alpha != -1)
374                        fillPaint.setAlpha(alpha);
375                }
376                
377            }
378            else if(symbolID.charAt(2) == 'S' &&
379                    symbolID.charAt(4) == 'O')//own track, //SUSPO
380            {
381                fillPaint.setColor(lineColor.toARGB());
382                if(alpha != -1)
383                    fillPaint.setAlpha(alpha);
384            }
385        }
386        catch (Exception excModifiers)
387        {
388            ErrorLogger.LogException("MilStdIconRenderer", "RenderUnit", excModifiers);
389        }
390
391        try
392        {
393            ImageInfo ii = null;
394            String key = makeCacheKey(symbolID, lineColor.toInt(), fillColor.toInt(), symbol1Paint.getColor(), pixelSize, keepUnitRatio, symStd);
395
396            //see if it's in the cache
397            if(_unitCache != null)
398            {
399                ii = _unitCache.get(key);
400                //safety check in case bitmaps are getting recycled while still in the LRU cache
401                if (ii != null && ii.getImage() != null && ii.getImage().isRecycled()) {
402                    synchronized (_UnitCacheMutex) {
403                        _unitCache.remove(key);
404                        ii = null;
405                    }
406                }
407            }
408            //if not, generate symbol
409            if (ii == null)//*/
410            {
411
412                if (lookup != null)
413                {
414                    //get Symbol1 character mapping
415                    charSymbol1Index = lookup.getMapping1(symbolID);
416                    //get Symbol2 character mapping
417                    charSymbol2Index = lookup.getMapping2();
418                }
419
420                //dimensions of the unit at specified font size
421                //dimensions = SymbolDimensions.getUnitBounds(charFillIndex, fontSize);
422                //symbolBounds = RectUtilities.makeRect(0, 0, dimensions[2], dimensions[3]);
423                //get centerpoint of the image
424                Point centerPoint = new Point(Math.round(symbolBounds.width() / 2), Math.round(symbolBounds.height() / 2));
425                Point centerCache = new Point(centerPoint);
426                //y offset to get centerpoint so we set back to zero when done.
427                symbolBounds.top = 0;
428
429                //Draw glyphs to bitmap
430                Bitmap bmp = Bitmap.createBitmap((int) (symbolBounds.width()), (int) (symbolBounds.height()), Config.ARGB_8888);
431                Canvas canvas = new Canvas(bmp);
432
433                //Log.i("HWA?","HWA: " + String.valueOf(canvas.isHardwareAccelerated()));
434                String strFill = null;
435                String strFrame = null;
436                String strSymbol1 = null;
437                String strSymbol2 = null;
438                String strFrameAssume = null;
439                if (charFillIndex > 0)
440                {
441                    strFill = String.valueOf((char) charFillIndex);
442                }
443                if (charFrameIndex > 0)
444                {
445                    strFrame = String.valueOf((char) charFrameIndex);
446                }
447                if (charSymbol1Index > 0)
448                {
449                    strSymbol1 = String.valueOf((char) charSymbol1Index);
450                }
451                if (charSymbol2Index > 0)
452                {
453                    strSymbol2 = String.valueOf((char) charSymbol2Index);
454                }
455                if (charFrameAssumeIndex > 0)
456                {
457                    strFrameAssume = String.valueOf((char) charFrameAssumeIndex);
458                }
459
460                //test
461                /*Paint ptTest = new Paint();
462                 ptTest.setColor(Color.GREEN);
463                 Rect rTest = new Rect(0,0,bmp.getWidth(),bmp.getHeight());
464                 canvas.drawRect(rTest, ptTest);//*/
465                //end test
466                synchronized(_UnitFontMutex)
467                {
468                    if (strFrameAssume != null && charFillIndex == -1) {
469                        canvas.drawText(strFrameAssume, centerPoint.x, centerPoint.y + (int) dimensions[1], symbol2Paint);
470                        strFrameAssume = null;
471                    }
472                    if (strFill != null) {
473                        canvas.drawText(strFill, centerPoint.x, centerPoint.y + (int) dimensions[1], fillPaint);
474                    }
475                    if (strFrameAssume != null) {
476                        canvas.drawText(strFrameAssume, centerPoint.x, centerPoint.y + (int) dimensions[1], frameAssumePaint);
477                    }
478                    if (strFrame != null) {
479                        canvas.drawText(strFrame, centerPoint.x, centerPoint.y + (int) dimensions[1], framePaint);
480                    }
481                    if (strSymbol2 != null) {
482                        canvas.drawText(strSymbol2, centerPoint.x, centerPoint.y + (int) dimensions[1], symbol2Paint);
483                    }
484                    if (strSymbol1 != null) {
485                        canvas.drawText(strSymbol1, centerPoint.x, centerPoint.y + (int) dimensions[1], symbol1Paint);
486                    }
487                }
488
489                //adjust centerpoint for HQStaff if present
490                if (SymbolUtilities.isHQ(symbolID))
491                {
492                    PointF point1 = new PointF();
493                    PointF point2 = new PointF();
494                    char affiliation = symbolID.charAt(1);
495                    if (affiliation == ('F')
496                            || affiliation == ('A')
497                            || affiliation == ('D')
498                            || affiliation == ('M')
499                            || affiliation == ('J')
500                            || affiliation == ('K')
501                            || affiliation == ('N')
502                            || affiliation == ('L'))
503                    {
504                        point1.x = (symbolBounds.left);
505                        point1.y = symbolBounds.top + (symbolBounds.height());
506                        point2.x = point1.x;
507                        point2.y = point1.y + symbolBounds.height();
508                    }
509                    else
510                    {
511                        point1.x = (symbolBounds.left + 1);
512                        point1.y = symbolBounds.top + (symbolBounds.height() / 2);
513                        point2.x = point1.x;
514                        point2.y = point1.y + symbolBounds.height();
515                    }
516                    centerPoint = new Point((int) point2.x, (int) point2.y);
517                }
518
519                ii = new ImageInfo(bmp, centerPoint, symbolBounds);
520
521                if(cacheEnabled && icon == false && bmp.getByteCount() <= maxCachedEntrySize)
522                {
523                    synchronized (_UnitCacheMutex)
524                    {
525                        if(_unitCache != null && _unitCache.get(key) == null)
526                            _unitCache.put(key, new ImageInfo(bmp, new Point(centerCache), new Rect(symbolBounds)));
527                    }
528                }
529
530                /*if(icon == false && pixelSize <= 100)
531                {
532                    _unitCache.put(key, new ImageInfo(bmp, new Point(centerCache), new Rect(symbolBounds)));
533                }//*/
534            }
535
536            ImageInfo iinew = null;
537
538            ////////////////////////////////////////////////////////////////////
539            //process display modifiers
540            if (hasDisplayModifiers)
541            {
542                iinew = ModifierRenderer.processUnitDisplayModifiers(ii, symbolID, modifiers, hasTextModifiers, attributes);
543            }
544
545            if (iinew != null)
546            {
547                ii = iinew;
548            }
549            iinew = null;
550
551            //process test modifiers
552            if (hasTextModifiers)
553            {
554                iinew = ModifierRenderer.processUnitTextModifiers(ii, symbolID, modifiers, attributes);
555            }
556
557            if (iinew != null)
558            {
559                ii = iinew;
560            }
561            iinew = null;
562
563            //cleanup///////////////////////////////////////////////////////////
564            //bmp.recycle();
565            symbolBounds = null;
566            fullBMP = null;
567            fullBounds = null;
568            //fullCanvas = null;
569
570            fillPaint = null;
571            framePaint = null;
572            symbol1Paint = null;
573            symbol2Paint = null;
574            lookup = null;
575            ////////////////////////////////////////////////////////////////////
576
577            if (icon == true)
578            {
579                return ii.getSquareImageInfo();
580            }
581            else
582            {
583                return ii;
584            }
585
586        }
587        catch (Exception exc)
588        {
589            ErrorLogger.LogException("MilStdIconRenderer", "RenderUnit", exc);
590        }
591        return temp;
592    }
593
594    /**
595     *
596     * @param symbolID
597     * @param modifiers
598     * @return
599     */
600    @SuppressWarnings("unused")
601    public ImageInfo RenderSP(String symbolID, SparseArray<String> modifiers, SparseArray<String> attributes)
602    {
603        ImageInfo temp = null;
604        String basicSymbolID = null;
605        float fontSize = RendererSettings.getInstance().getSPFontSize();
606
607        Color lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID);
608        Color fillColor = null;//SymbolUtilities.getFillColorOfAffiliation(symbolID);
609
610        int alpha = -1;
611
612        int symStd = RendererSettings.getInstance().getSymbologyStandard();
613        //fill character
614        int charFillIndex = -1;
615        //frame character
616        int charFrameIndex = -1;
617        //made up symbol ID for fill characters
618        String fillID = null;
619
620        SymbolDef sd = null;
621
622        Paint fillPaint = null;
623        Paint framePaint = null;
624
625        SinglePointLookupInfo lookup = null;
626
627        Rect symbolBounds = null;
628        RectF fullBounds = null;
629        Bitmap fullBMP = null;
630
631        boolean drawAsIcon = false;
632        int pixelSize = -1;
633        boolean keepUnitRatio = true;
634        boolean hasDisplayModifiers = false;
635        boolean hasTextModifiers = false;
636        int symbolOutlineWidth = RendererSettings.getInstance().getSinglePointSymbolOutlineWidth();
637        float scale = -999;
638
639        try
640        {
641            if (modifiers == null)
642            {
643                modifiers = new SparseArray<String>();
644            }
645            //get MilStdAttributes
646            if (attributes != null && attributes.indexOfKey(MilStdAttributes.SymbologyStandard) >= 0)
647            {
648                symStd = Integer.parseInt(attributes.get(MilStdAttributes.SymbologyStandard));
649            }
650
651            //get symbol info
652            basicSymbolID = SymbolUtilities.getBasicSymbolIDStrict(symbolID);
653            lookup = SinglePointLookup.getInstance().getSPLookupInfo(basicSymbolID, symStd);
654            if (lookup == null)//if lookup fails, fix code/use unknown symbol code.
655            {
656                //if symbolID bad, do best to find a workable code
657                if (modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1) != null)
658                {
659                    modifiers.put(ModifiersTG.H1_ADDITIONAL_INFO_2, modifiers.get(ModifiersTG.H_ADDITIONAL_INFO_1));
660                }
661                modifiers.put(ModifiersTG.H_ADDITIONAL_INFO_1, symbolID.substring(0, 10));
662
663                symbolID = "G" + SymbolUtilities.getAffiliation(symbolID)
664                        + "G" + SymbolUtilities.getStatus(symbolID) + "GPP---****X";
665                basicSymbolID = SymbolUtilities.getBasicSymbolIDStrict(symbolID);
666                lookup = SinglePointLookup.getInstance().getSPLookupInfo(basicSymbolID, symStd);
667                lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID);
668                fillColor = null;//SymbolUtilities.getFillColorOfAffiliation(symbolID);
669            }
670
671            if (SymbolUtilities.hasDefaultFill(symbolID))
672            {
673                fillColor = SymbolUtilities.getFillColorOfAffiliation(symbolID);
674            }
675            if (SymbolUtilities.isTGSPWithFill(symbolID))
676            {
677                fillID = SymbolUtilities.getTGFillSymbolCode(symbolID);
678                if (fillID != null)
679                {
680                    charFillIndex = SinglePointLookup.getInstance().getCharCodeFromSymbol(fillID, symStd);
681                }
682            }
683            else if (SymbolUtilities.isWeatherSPWithFill(symbolID))
684            {
685                charFillIndex = charFrameIndex + 1;
686                fillColor = SymbolUtilities.getFillColorOfWeather(symbolID);
687
688            }
689
690            if (attributes != null)
691            {
692                if (attributes.indexOfKey(MilStdAttributes.KeepUnitRatio) >= 0)
693                {
694                    keepUnitRatio = Boolean.parseBoolean(attributes.get(MilStdAttributes.KeepUnitRatio));
695                }
696
697                if (attributes.indexOfKey(MilStdAttributes.LineColor) >= 0)
698                {
699                    lineColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.LineColor));
700                }
701
702                if (attributes.indexOfKey(MilStdAttributes.FillColor) >= 0)
703                {
704                    fillColor = SymbolUtilities.getColorFromHexString(attributes.get(MilStdAttributes.FillColor));
705                }
706
707                if (attributes.indexOfKey(MilStdAttributes.Alpha) >= 0)
708                {
709                    alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha));
710                }
711
712                if (attributes.indexOfKey(MilStdAttributes.DrawAsIcon) >= 0)
713                {
714                    drawAsIcon = Boolean.parseBoolean(attributes.get(MilStdAttributes.DrawAsIcon));
715                }
716
717                if (attributes.indexOfKey(MilStdAttributes.PixelSize) >= 0)
718                {
719                    pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize));
720                }
721                else
722                {
723                    if(keepUnitRatio == true)
724                        pixelSize = 35;
725                    else
726                    {
727                        try {
728                            Rect sb = SymbolDimensions.getSymbolBounds(SymbolUtilities.getBasicSymbolIDStrict(symbolID),symStd,60.0f);
729                            pixelSize = Math.max(sb.width(), sb.height());
730                        }
731                        catch(Exception exc){
732                            Log.e(TAG,exc.getMessage());
733                            exc.printStackTrace();
734                        }
735
736                    }
737                }
738                if (attributes.indexOfKey(MilStdAttributes.OutlineSymbol) >= 0)
739                {
740                    if(Boolean.parseBoolean(attributes.get(MilStdAttributes.OutlineSymbol))==false);
741                    symbolOutlineWidth = 0;
742                }
743
744
745
746                /*if (attributes.indexOfKey(MilStdAttributes.OutlineWidth)>=0)
747                 symbolOutlineWidth = Integer.parseInt(attributes.get(MilStdAttributes.OutlineWidth));//*/
748            }
749
750            if (drawAsIcon)//icon won't show modifiers or display icons
751            {
752                keepUnitRatio = false;
753                hasDisplayModifiers = false;
754                hasTextModifiers = false;
755                symbolOutlineWidth = 0;
756            }
757            else
758            {
759                hasDisplayModifiers = ModifierRenderer.hasDisplayModifiers(symbolID, modifiers);
760                hasTextModifiers = ModifierRenderer.hasTextModifiers(symbolID, modifiers, attributes);
761            }
762
763            int outlineOffset = symbolOutlineWidth;
764            if (outlineOffset > 2)
765            {
766                outlineOffset = (outlineOffset - 1) / 2;
767            }
768            else
769            {
770                outlineOffset = 0;
771            }
772
773            //check symbol font size////////////////////////////////////////////
774            Rect rect = null;
775
776            float ratio = 0;
777
778            if (pixelSize > 0)
779            {
780                symbolBounds = SymbolDimensions.getSymbolBounds(basicSymbolID, symStd, fontSize);
781                rect = new Rect(symbolBounds);
782
783                if (keepUnitRatio == true)
784                {
785                           //scale it somehow for consistency with units.
786
787                    //when SymbolSizeMedium = 80;
788                    //a pixel size of 35 = scale value of 1.0
789                    scale = pixelSize / 35.0f;
790                }
791
792                //adjust size
793                float fPixelSize = (float)pixelSize;
794                ratio = Math.min((fPixelSize / rect.height()), (fPixelSize / rect.width()));
795
796            }
797
798            //scale overrides pixel size.
799            if (scale != -999)
800            {
801                ratio = scale;
802            }
803
804            if (ratio > 0)
805            {
806                fontSize = fontSize * ratio;
807            }
808
809            //symbolBounds = SymbolDimensions.getSymbolBounds(basicSymbolID, symStd, fontSize);
810
811            ////////////////////////////////////////////////////////////////////
812            if (SymbolUtilities.isTGSPWithFill(symbolID) && fillColor != null)
813            {
814                fillPaint = new Paint();
815                fillPaint.setStyle(Paint.Style.FILL);
816                fillPaint.setColor(fillColor.toARGB());
817                fillPaint.setTextSize(fontSize);
818                fillPaint.setAntiAlias(true);
819                fillPaint.setTextAlign(Align.CENTER);
820                fillPaint.setTypeface(_tfSP);
821                if(alpha != -1)
822                    fillPaint.setAlpha(alpha);
823            }
824
825            framePaint = new Paint();
826            framePaint.setStyle(Paint.Style.FILL);
827            framePaint.setColor(lineColor.toARGB());
828            framePaint.setTextSize(fontSize);
829            framePaint.setAntiAlias(true);
830            framePaint.setTextAlign(Align.CENTER);
831            framePaint.setTypeface(_tfSP);
832            if(alpha != -1)
833                framePaint.setAlpha(alpha);
834
835            //Check if we need to set 'N' to "ENY"
836            if (symbolID.charAt(1) == 'H'
837                    && modifiers.indexOfKey(MilStdAttributes.DrawAsIcon) >= 0
838                    && (Boolean.parseBoolean(modifiers.get(MilStdAttributes.DrawAsIcon)) == false))
839            {
840                modifiers.put(ModifiersTG.N_HOSTILE, "ENY");
841            }
842
843        }
844        catch (Exception excModifiers)
845        {
846            ErrorLogger.LogException("MilStdIconRenderer", "RenderUnit", excModifiers);
847        }
848
849        try
850        {
851            ImageInfo ii = null;
852            int intFill = -1;
853            if (fillColor != null)
854            {
855                intFill = fillColor.toInt();
856            }
857            String key = makeCacheKey(symbolID, lineColor.toInt(), intFill, pixelSize, keepUnitRatio, symStd);
858
859            //see if it's in the cache
860            if(_tgCache != null) {
861                ii = _tgCache.get(key);
862                //safety check in case bitmaps are getting recycled while still in the LRU cache
863                if (ii != null && ii.getImage() != null && ii.getImage().isRecycled()) {
864                    synchronized (_SinglePointCacheMutex) {
865                        _tgCache.remove(key);
866                        ii = null;
867                    }
868                }
869            }
870            //if not, generate symbol
871            if (ii == null)//*/
872            {
873                //get fill character
874                //get frame character
875                //get symbol info
876                charFrameIndex = -1;//SinglePointLookup.instance.getCharCodeFromSymbol(symbolID);
877                charFillIndex = -1;
878
879                if (SymbolUtilities.getStatus(symbolID).equals("A"))
880                {
881                    charFrameIndex = lookup.getMappingA();
882                }
883                else
884                {
885                    charFrameIndex = lookup.getMappingP();
886                }
887
888                if (SymbolUtilities.isTGSPWithFill(symbolID) && fillColor != null)
889                {
890                    fillID = SymbolUtilities.getTGFillSymbolCode(symbolID);
891                    if (fillID != null)
892                    {
893                        charFillIndex = SinglePointLookup.getInstance().getCharCodeFromSymbol(fillID, symStd);
894                    }
895                }
896
897                //dimensions of the unit at specified font size
898                RectF rect = new RectF(0, 0, lookup.getWidth(), lookup.getHeight());
899
900                if (fontSize != 60.0)//adjust boundaries ratio if font size is not at the default setting.
901                {
902                    double ratio = fontSize / 60;
903
904                    rect = new RectF(0, 0, Math.round(rect.width() * ratio), Math.round(rect.height() * ratio));
905                }
906
907                //matrix to place the symbol centered in the MilStdBmp
908                Matrix matrix = new Matrix();
909                Point centerPoint = null;
910                centerPoint = SymbolDimensions.getSymbolCenter(lookup.getBasicSymbolID(), rect);
911
912                if (symbolOutlineWidth > 0)
913                {       //adjust matrix and centerpoint to account for outline if present
914                    matrix.postTranslate(centerPoint.x + symbolOutlineWidth, centerPoint.y + symbolOutlineWidth);
915                    centerPoint.offset(symbolOutlineWidth, symbolOutlineWidth);
916                    rect = new RectF(0, 0, (rect.width() + (symbolOutlineWidth * 2)), (rect.height() + (symbolOutlineWidth * 2)));
917                }
918                else
919                {
920                    matrix.postTranslate(centerPoint.x, centerPoint.y);
921                }
922
923                //Draw glyphs to bitmap
924                Bitmap bmp = Bitmap.createBitmap((int) (rect.width() + 0.5), (int) (rect.height() + 0.5), Config.ARGB_8888);
925                Canvas canvas = new Canvas(bmp);
926
927                symbolBounds = new Rect(0, 0, bmp.getWidth(), bmp.getHeight());
928
929                String strFill = null;
930                String strFrame = null;
931                if (charFillIndex > 0)
932                {
933                    strFill = String.valueOf((char) charFillIndex);
934                }
935                if (charFrameIndex > 0)
936                {
937                    strFrame = String.valueOf((char) charFrameIndex);
938                }
939
940                canvas.setMatrix(matrix);
941                synchronized (_SinglePointFontMutex)
942                {
943                    if (strFill != null)
944                    {
945                        canvas.drawText(strFill, 0, 0, fillPaint);
946                    }
947
948                    if (strFrame != null)
949                    {
950                        //try
951                        //{
952                        RendererUtilities.renderSymbolCharacter(canvas, strFrame, 0, 0, framePaint, lineColor, symbolOutlineWidth);
953                        //}
954                        //catch( Exception e){
955                        //    logError(TAG,e);
956                        //}
957
958                    }
959                }
960
961
962                ii = new ImageInfo(bmp, centerPoint, symbolBounds);
963
964                if(cacheEnabled && drawAsIcon == false && bmp.getByteCount() <= maxCachedEntrySize)
965                {
966                    synchronized (_SinglePointCacheMutex)
967                    {
968                        if(_tgCache != null && _tgCache.get(key) == null)
969                            _tgCache.put(key, ii);
970                    }
971                }
972                /*if (drawAsIcon == false && pixelSize <= 100)
973                {
974                    _tgCache.put(key, ii);
975                }//*/
976            }
977
978            //Process Modifiers
979            ImageInfo iiNew = null;
980            if (drawAsIcon == false && (hasTextModifiers || hasDisplayModifiers || SymbolUtilities.isTGSPWithIntegralText(symbolID)))
981            {
982                if (SymbolUtilities.isTGSPWithSpecialModifierLayout(symbolID)
983                        || SymbolUtilities.isTGSPWithIntegralText(symbolID))
984                {
985                    iiNew = ModifierRenderer.ProcessTGSPWithSpecialModifierLayout(ii, symbolID, modifiers, attributes, lineColor);
986                }
987                else
988                {
989                    iiNew = ModifierRenderer.ProcessTGSPModifiers(ii, symbolID, modifiers, attributes, lineColor);
990                }
991
992            }
993
994            if (iiNew != null)
995            {
996                ii = iiNew;
997            }
998
999            //cleanup
1000            //bmp.recycle();
1001            symbolBounds = null;
1002            fullBMP = null;
1003            fullBounds = null;
1004
1005            fillPaint = null;
1006            framePaint = null;
1007
1008            lookup = null;
1009
1010
1011            if (drawAsIcon)
1012            {
1013                return ii.getSquareImageInfo();
1014            }
1015            else
1016            {
1017                return ii;
1018            }
1019
1020        }
1021        catch (Exception exc)
1022        {
1023            ErrorLogger.LogException("MilStdIconRenderer", "RenderSP", exc);
1024        }
1025        return null;
1026    }
1027
1028    /**
1029     * Tries to get a valid UnitFontLookupInfo object when the symbolID is
1030     * poorly formed or there's no match in the lookup. Use this if you get a
1031     * null return value from:
1032     * "UnitFontLookupC.getInstance().getLookupInfo(symbolID)" or "CanRender"
1033     * returns false.
1034     *
1035     * @param symbolID
1036     * @return
1037     */
1038    private UnitFontLookupInfo ResolveUnitFontLookupInfo(String symbolID, int symStd)
1039    {
1040        String id = symbolID;
1041        UnitFontLookupInfo lookup = null;
1042        String affiliation = "";
1043        String status = "";
1044        if (id != null && id.length() >= 10)//if lookup fails, fix code/use unknown symbol code.
1045        {
1046            StringBuilder sb = new StringBuilder("");
1047            sb.append(id.charAt(0));
1048
1049            if (SymbolUtilities.hasValidAffiliation(id) == false)
1050            {
1051                sb.append('U');
1052                affiliation = "U";
1053            }
1054            else
1055            {
1056                sb.append(id.charAt(1));
1057                affiliation = id.substring(1, 2);
1058            }
1059
1060            if (SymbolUtilities.hasValidBattleDimension(id) == false)
1061            {
1062                sb.append('Z');
1063                sb.replace(0, 1, "S");
1064            }
1065            else
1066            {
1067                sb.append(id.charAt(2));
1068            }
1069
1070            if (SymbolUtilities.hasValidStatus(id) == false)
1071            {
1072                sb.append('P');
1073                status = "P";
1074            }
1075            else
1076            {
1077                sb.append(id.charAt(3));
1078                status = id.substring(3, 4);
1079            }
1080
1081            sb.append("------");
1082            if (id.length() >= 15)
1083            {
1084                sb.append(id.substring(10, 15));
1085            }
1086            else
1087            {
1088                sb.append("*****");
1089            }
1090            id = sb.toString();
1091
1092            lookup = UnitFontLookup.getInstance().getLookupInfo(id, symStd);
1093        }
1094        else if (symbolID == null || symbolID.equals(""))
1095        {
1096            lookup = UnitFontLookup.getInstance().getLookupInfo("SUZP------*****", symStd);
1097        }
1098        return lookup;
1099    }
1100
1101    public Bitmap getTestSymbol()
1102    {
1103        Bitmap temp = null;
1104        try
1105        {
1106            temp = Bitmap.createBitmap(70, 70, Config.ARGB_8888);
1107
1108            Canvas canvas = new Canvas(temp);
1109
1110            if (canvas.isHardwareAccelerated())
1111            {
1112                System.out.println("HW acceleration supported");
1113            }
1114                        //canvas.drawColor(Color.WHITE);
1115
1116            //Typeface tf = Typeface.createFromAsset(_am, "fonts/unitfonts.ttf");
1117            Typeface tf = _tfUnits;
1118
1119            Paint fillPaint = new Paint();
1120            fillPaint.setStyle(Paint.Style.FILL);
1121            fillPaint.setColor(Color.CYAN.toInt());
1122            fillPaint.setTextSize(50);
1123            fillPaint.setAntiAlias(true);
1124            fillPaint.setTextAlign(Align.CENTER);
1125            fillPaint.setTypeface(tf);
1126
1127            Paint framePaint = new Paint();
1128            framePaint.setStyle(Paint.Style.FILL);
1129            framePaint.setColor(Color.BLACK.toInt());
1130            framePaint.setTextSize(50);
1131            framePaint.setAntiAlias(true);
1132            framePaint.setTextAlign(Align.CENTER);
1133            framePaint.setTypeface(tf);
1134
1135            Paint symbolPaint = new Paint();
1136            symbolPaint.setStyle(Paint.Style.FILL);
1137            symbolPaint.setColor(Color.BLACK.toInt());
1138            symbolPaint.setTextSize(50);
1139            symbolPaint.setAntiAlias(true);
1140            symbolPaint.setTextAlign(Align.CENTER);
1141            symbolPaint.setTypeface(tf);
1142
1143            String strFill = String.valueOf((char) 800);
1144            String strFrame = String.valueOf((char) 801);
1145            String strSymbol = String.valueOf((char) 1121);
1146
1147            canvas.drawText(strFill, 35, 35, fillPaint);
1148            canvas.drawText(strFrame, 35, 35, framePaint);
1149            canvas.drawText(strSymbol, 35, 35, symbolPaint);
1150
1151            FontMetrics mf = framePaint.getFontMetrics();
1152            float height = mf.bottom - mf.top;
1153            float width = fillPaint.measureText(strFrame);
1154
1155            Log.i(TAG, "top: " + String.valueOf(mf.top));
1156            Log.i(TAG, "bottom: " + String.valueOf(mf.bottom));
1157            Log.i(TAG, "ascent: " + String.valueOf(mf.ascent));
1158            Log.i(TAG, "descent: " + String.valueOf(mf.descent));
1159            Log.i(TAG, "leading: " + String.valueOf(mf.leading));
1160            Log.i(TAG, "width: " + String.valueOf(width));
1161            Log.i(TAG, "height: " + String.valueOf(height));
1162
1163        }
1164        catch (Exception exc)
1165        {
1166            Log.e(TAG, exc.getMessage());
1167            Log.e(TAG, getStackTrace(exc));
1168        }
1169
1170        return temp;
1171    }//*/
1172
1173    public static String makeCacheKey(String symbolID, int lineColor, int fillColor, int iconColor, int size, boolean keepUnitRatio, int symStd)
1174    {
1175        String key = symbolID.substring(0, 10) + String.valueOf(lineColor) + String.valueOf(fillColor) + String.valueOf(iconColor) + String.valueOf(size) + String.valueOf(keepUnitRatio) + String.valueOf(symStd);
1176        return key;
1177    }
1178
1179    public static String makeCacheKey(String symbolID, int lineColor, int fillColor, int size, boolean keepUnitRatio, int symStd)
1180    {
1181        String key = symbolID.substring(0, 10) + String.valueOf(lineColor) + String.valueOf(fillColor) + String.valueOf(size) + String.valueOf(keepUnitRatio) + String.valueOf(symStd);
1182        return key;
1183    }
1184
1185    public void logError(String tag, Throwable thrown)
1186    {
1187        if (tag == null || tag.equals(""))
1188        {
1189            tag = "singlePointRenderer";
1190        }
1191
1192        String message = thrown.getMessage();
1193        String stack = getStackTrace(thrown);
1194        if (message != null)
1195        {
1196            Log.e(tag, message);
1197        }
1198        if (stack != null)
1199        {
1200            Log.e(tag, stack);
1201        }
1202    }
1203
1204    public String getStackTrace(Throwable thrown)
1205    {
1206        try
1207        {
1208            if (thrown != null)
1209            {
1210                if (thrown.getStackTrace() != null)
1211                {
1212                    String eol = System.getProperty("line.separator");
1213                    StringBuilder sb = new StringBuilder();
1214                    sb.append(thrown.toString());
1215                    sb.append(eol);
1216                    for (StackTraceElement element : thrown.getStackTrace())
1217                    {
1218                        sb.append("        at ");
1219                        sb.append(element);
1220                        sb.append(eol);
1221                    }
1222                    return sb.toString();
1223                }
1224                else
1225                {
1226                    return thrown.getMessage() + "- no stack trace";
1227                }
1228            }
1229            else
1230            {
1231                return "no stack trace";
1232            }
1233        }
1234        catch (Exception exc)
1235        {
1236            Log.e("getStackTrace", exc.getMessage());
1237        }
1238        return thrown.getMessage();
1239    }//*/
1240
1241    /*
1242     private static String PrintList(ArrayList list)
1243     {
1244     String message = "";
1245     for(Object item : list)
1246     {
1247
1248     message += item.toString() + "\n";
1249     }
1250     return message;
1251     }//*/
1252    /*
1253     private static String PrintObjectMap(Map<String, Object> map)
1254     {
1255     Iterator<Object> itr = map.values().iterator();
1256     String message = "";
1257     String temp = null;
1258     while(itr.hasNext())
1259     {
1260     temp = String.valueOf(itr.next());
1261     if(temp != null)
1262     message += temp + "\n";
1263     }
1264     //ErrorLogger.LogMessage(message);
1265     return message;
1266     }//*/
1267    @Override
1268    public void onSettingsChanged(SettingsChangedEvent sce)
1269    {
1270
1271        if(sce != null && sce.getEventType().equals(SettingsChangedEvent.EventType_FontChanged))
1272        {
1273            synchronized (_ModifierFontMutex)
1274            {
1275                _modifierFont = RendererSettings.getInstance().getModiferFont();
1276                _modifierOutlineFont = RendererSettings.getInstance().getModiferFont();
1277                FontMetrics fm = new FontMetrics();
1278                fm = _modifierFont.getFontMetrics();
1279                _modifierDescent = fm.descent;
1280                //_modifierFontHeight = fm.top + fm.bottom;
1281                _modifierFontHeight = fm.bottom - fm.top;
1282
1283                _modifierFont.setStrokeWidth(RendererSettings.getInstance().getTextOutlineWidth());
1284                _modifierOutlineFont.setColor(Color.white.toInt());
1285                _deviceDPI = RendererSettings.getInstance().getDeviceDPI();
1286
1287                ModifierRenderer.setModifierFont(_modifierFont, _modifierFontHeight, _modifierDescent);
1288
1289            }
1290        }
1291        
1292        if(sce != null && sce.getEventType().equals(SettingsChangedEvent.EventType_CacheSizeChanged))
1293        {
1294
1295            int cSize = RendererSettings.getInstance().getCacheSize()/2;
1296            //adjust unit cache
1297            if(cSize != cacheSize) {
1298                cacheSize = cSize;
1299                if (cacheSize >= 5)
1300                    maxCachedEntrySize = cacheSize / 5;
1301                else
1302                    maxCachedEntrySize = 1;
1303
1304                if(cacheEnabled) //if cache enabled, update cache
1305                {
1306
1307                    synchronized (_UnitCacheMutex) {
1308                        if(_unitCache != null)
1309                            _unitCache.evictAll();
1310                        _unitCache = new LruCache<String, ImageInfo>(cSize) {
1311                            @Override
1312                            protected int sizeOf(String key, ImageInfo ii) {
1313                                return ii.getByteCount();// / 1024;
1314                            }
1315                        };
1316                    }
1317                    //adjust tg cache
1318                    synchronized (_SinglePointCacheMutex) {
1319                        if(_tgCache != null)
1320                            _tgCache.evictAll();
1321                        _tgCache = new LruCache<String, ImageInfo>(cSize) {
1322                            @Override
1323                            protected int sizeOf(String key, ImageInfo ii) {
1324                                return ii.getByteCount();// / 1024;
1325                            }
1326                        };
1327                    }
1328                }
1329            }
1330
1331        }
1332
1333        if(sce != null && sce.getEventType().equals(SettingsChangedEvent.EventType_CacheToggled))
1334        {
1335            if(cacheEnabled != RendererSettings.getInstance().getCacheEnabled())
1336            {
1337                cacheEnabled = RendererSettings.getInstance().getCacheEnabled();
1338
1339                if (cacheEnabled == false)
1340                {
1341                    synchronized (_SinglePointCacheMutex)
1342                    {
1343                        if (_tgCache != null)
1344                            _tgCache.evictAll();
1345                        _tgCache = null;
1346                    }
1347                    synchronized (_UnitCacheMutex)
1348                    {
1349                        if (_unitCache != null)
1350                            _unitCache.evictAll();
1351                        _unitCache = null;
1352                    }
1353                }
1354                else
1355                {
1356                    int cSize = RendererSettings.getInstance().getCacheSize() / 2;
1357                    synchronized (_SinglePointCacheMutex)
1358                    {
1359                        if(_tgCache != null)
1360                            _tgCache.evictAll();
1361                        _tgCache = new LruCache<String, ImageInfo>(cSize) {
1362                            @Override
1363                            protected int sizeOf(String key, ImageInfo ii) {
1364                                return ii.getByteCount();// / 1024;
1365                            }
1366                        };
1367                    }
1368                    synchronized (_UnitCacheMutex)
1369                    {
1370                        if(_unitCache != null)
1371                            _unitCache.evictAll();
1372                        _unitCache = new LruCache<String, ImageInfo>(cSize) {
1373                            @Override
1374                            protected int sizeOf(String key, ImageInfo ii) {
1375                                return ii.getByteCount();// / 1024;
1376                            }
1377                        };
1378                    }
1379                }
1380            }
1381        }
1382    }
1383}