001package armyc2.c5isr.renderer; 002 003import android.graphics.Bitmap; 004import android.graphics.Bitmap.Config; 005import android.graphics.Canvas; 006import android.graphics.Paint; 007import android.graphics.Paint.FontMetrics; 008import android.graphics.Point; 009import android.graphics.PointF; 010import android.graphics.Rect; 011import android.graphics.RectF; 012import android.util.Log; 013import android.util.LruCache; 014 015import com.caverock.androidsvg.SVG; 016 017import java.util.HashMap; 018import java.util.Map; 019 020import armyc2.c5isr.renderer.utilities.Color; 021import armyc2.c5isr.renderer.utilities.DrawRules; 022import armyc2.c5isr.renderer.utilities.ErrorLogger; 023import armyc2.c5isr.renderer.utilities.ImageInfo; 024import armyc2.c5isr.renderer.utilities.MSInfo; 025import armyc2.c5isr.renderer.utilities.MSLookup; 026import armyc2.c5isr.renderer.utilities.MilStdAttributes; 027import armyc2.c5isr.renderer.utilities.Modifiers; 028import armyc2.c5isr.renderer.utilities.RectUtilities; 029import armyc2.c5isr.renderer.utilities.RendererSettings; 030import armyc2.c5isr.renderer.utilities.RendererUtilities; 031import armyc2.c5isr.renderer.utilities.SVGInfo; 032import armyc2.c5isr.renderer.utilities.SVGLookup; 033import armyc2.c5isr.renderer.utilities.SettingsChangedEvent; 034import armyc2.c5isr.renderer.utilities.SettingsChangedEventListener; 035import armyc2.c5isr.renderer.utilities.SymbolDimensionInfo; 036import armyc2.c5isr.renderer.utilities.SymbolID; 037import armyc2.c5isr.renderer.utilities.SymbolUtilities; 038 039public class SinglePointRenderer implements SettingsChangedEventListener 040{ 041 042 private final String TAG = "SinglePointRenderer"; 043 private static SinglePointRenderer _instance = null; 044 045 private final Object _SinglePointCacheMutex = new Object(); 046 private final Object _UnitCacheMutex = new Object(); 047 048 private final Object _modifierFontMutex = new Object(); 049 private Paint _modifierFont = new Paint(); 050 private Paint _modifierOutlineFont = new Paint(); 051 private float _modifierDescent = 2; 052 private float _modifierFontHeight = 10; 053 private int _deviceDPI = 72; 054 055 //private LruCache<String, ImageInfo> _unitCache = new LruCache<String, ImageInfo>(15); 056 //private LruCache<String, ImageInfo> _tgCache = new LruCache<String, ImageInfo>(7); 057 private LruCache<String, ImageInfo> _unitCache = new LruCache<String, ImageInfo>(1024); 058 private LruCache<String, ImageInfo> _tgCache = new LruCache<String, ImageInfo>(1024); 059 private final int maxMemory = (int) (Runtime.getRuntime().maxMemory());// / 1024); 060 private int cacheSize = 5;//RendererSettings.getInstance().getCacheSize() / 2; 061 private int maxCachedEntrySize = cacheSize / 5; 062 private boolean cacheEnabled = RendererSettings.getInstance().getCacheEnabled(); 063 064 private SinglePointRenderer() 065 { 066 RendererSettings.getInstance().addEventListener(this); 067 068 //get modifier font values. 069 onSettingsChanged(new SettingsChangedEvent(SettingsChangedEvent.EventType_FontChanged)); 070 //set cache 071 onSettingsChanged(new SettingsChangedEvent(SettingsChangedEvent.EventType_CacheSizeChanged)); 072 073 } 074 075 public static synchronized SinglePointRenderer getInstance() 076 { 077 if (_instance == null) 078 { 079 _instance = new SinglePointRenderer(); 080 } 081 082 return _instance; 083 } 084 085 /** 086 * 087 * @param symbolID 088 * @param modifiers 089 * @return 090 */ 091 public ImageInfo RenderUnit(String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 092 { 093 Color lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID); 094 Color fillColor = SymbolUtilities.getFillColorOfAffiliation(symbolID); 095 Color iconColor = null; 096 097 int alpha = -1; 098 099 100 //SVG values 101 String frameID = null; 102 String iconID = null; 103 String mod1ID = null; 104 String mod2ID = null; 105 SVGInfo siFrame = null; 106 SVGInfo siIcon = null; 107 SVGInfo siMod1 = null; 108 SVGInfo siMod2 = null; 109 SVG mySVG = null; 110 int top = 0; 111 int left = 0; 112 int width = 0; 113 int height = 0; 114 String svgStart = null; 115 String strSVG = null; 116 String strSVGFrame = null; 117 118 119 Rect symbolBounds = null; 120 Rect fullBounds = null; 121 Bitmap fullBMP = null; 122 123 boolean hasDisplayModifiers = false; 124 boolean hasTextModifiers = false; 125 126 int pixelSize = -1; 127 boolean keepUnitRatio = true; 128 boolean icon = false; 129 boolean noFrame = false; 130 131 int ver = SymbolID.getVersion(symbolID); 132 133 // <editor-fold defaultstate="collapsed" desc="Parse Attributes"> 134 try 135 { 136 137 if (attributes.containsKey(MilStdAttributes.PixelSize)) 138 { 139 pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize)); 140 } 141 else 142 { 143 pixelSize = RendererSettings.getInstance().getDefaultPixelSize(); 144 } 145 146 if (attributes.containsKey(MilStdAttributes.KeepUnitRatio)) 147 { 148 keepUnitRatio = Boolean.parseBoolean(attributes.get(MilStdAttributes.KeepUnitRatio)); 149 } 150 151 if (attributes.containsKey(MilStdAttributes.DrawAsIcon)) 152 { 153 icon = Boolean.parseBoolean(attributes.get(MilStdAttributes.DrawAsIcon)); 154 } 155 156 if (icon)//icon won't show modifiers or display icons 157 { 158 //TODO: symbolID modifications as necessary 159 keepUnitRatio = false; 160 hasDisplayModifiers = false; 161 hasTextModifiers = false; 162 //symbolID = symbolID.substring(0, 10) + "-----"; 163 } 164 else 165 { 166 hasDisplayModifiers = ModifierRenderer.hasDisplayModifiers(symbolID, modifiers); 167 hasTextModifiers = ModifierRenderer.hasTextModifiers(symbolID, modifiers); 168 } 169 170 if (attributes.containsKey(MilStdAttributes.LineColor)) 171 { 172 lineColor = new Color(attributes.get(MilStdAttributes.LineColor)); 173 } 174 if (attributes.containsKey(MilStdAttributes.FillColor)) 175 { 176 fillColor = new Color(attributes.get(MilStdAttributes.FillColor)); 177 } 178 if (attributes.containsKey(MilStdAttributes.IconColor)) 179 { 180 iconColor = new Color(attributes.get(MilStdAttributes.IconColor)); 181 }//*/ 182 if (attributes.containsKey(MilStdAttributes.Alpha)) 183 { 184 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 185 } 186 187 } 188 catch (Exception excModifiers) 189 { 190 ErrorLogger.LogException("SinglePointRenderer", "RenderUnit", excModifiers); 191 } 192 // </editor-fold> 193 194 try 195 { 196 197 ImageInfo ii = null; 198 String key = makeCacheKey(symbolID, lineColor.toInt(), fillColor.toInt(), String.valueOf(iconColor),pixelSize, keepUnitRatio, false); 199 200 //see if it's in the cache 201 if(_unitCache != null) { 202 ii = _unitCache.get(key); 203 //safety check in case bitmaps are getting recycled while still in the LRU cache 204 if (ii != null && ii.getImage() != null && ii.getImage().isRecycled()) { 205 synchronized (_UnitCacheMutex) { 206 _unitCache.remove(key); 207 ii = null; 208 } 209 } 210 } 211 //if not, generate symbol 212 if (ii == null)//*/ 213 { 214 int version = SymbolID.getVersion(symbolID); 215 //Get SVG pieces of symbol 216 frameID = SVGLookup.getFrameID(symbolID); 217 iconID = SVGLookup.getMainIconID(symbolID); 218 mod1ID = SVGLookup.getMod1ID(symbolID); 219 mod2ID = SVGLookup.getMod2ID(symbolID); 220 siFrame = SVGLookup.getInstance().getSVGLInfo(frameID, version); 221 siIcon = SVGLookup.getInstance().getSVGLInfo(iconID, version); 222 223 if(siFrame == null) 224 { 225 frameID = SVGLookup.getFrameID(SymbolUtilities.reconcileSymbolID(symbolID)); 226 siFrame = SVGLookup.getInstance().getSVGLInfo(frameID, version); 227 if(siFrame == null)//still no match, get unknown frame 228 { 229 frameID = SVGLookup.getFrameID(SymbolID.setSymbolSet(symbolID,SymbolID.SymbolSet_Unknown)); 230 siFrame = SVGLookup.getInstance().getSVGLInfo(frameID, version); 231 } 232 } 233 234 if(siIcon == null) 235 { 236 if(SymbolID.getSymbolSet(symbolID) == SymbolID.SymbolSet_Unknown) 237 siIcon = SVGLookup.getInstance().getSVGLInfo("00000000", version);//question mark 238 /*else if(iconID.substring(2,8).equals("000000")==false && MSLookup.getInstance().getMSLInfo(symbolID) == null) 239 siIcon = SVGLookup.getInstance().getSVGLInfo("98100000", version);//inverted question mark//*/ 240 } 241 242 if(RendererSettings.getInstance().getScaleMainIcon()) 243 siIcon = RendererUtilities.scaleIcon(symbolID,siIcon); 244 245 siMod1 = SVGLookup.getInstance().getSVGLInfo(mod1ID, version); 246 siMod2 = SVGLookup.getInstance().getSVGLInfo(mod2ID, version); 247 top = Math.round(siFrame.getBbox().top); 248 left = Math.round(siFrame.getBbox().left); 249 width = Math.round(siFrame.getBbox().width()); 250 height = Math.round(siFrame.getBbox().height()); 251 if(siFrame.getBbox().bottom > 400) 252 svgStart = "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 612 792\">"; 253 else 254 svgStart = "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 400 400\">"; 255 256 //update line and fill color of frame SVG 257 if(lineColor != null || fillColor != null) 258 strSVGFrame = RendererUtilities.setSVGFrameColors(symbolID,siFrame.getSVG(),lineColor,fillColor); 259 else 260 strSVGFrame = siFrame.getSVG(); 261 262 if(frameID.equals("octagon"))//for the 1 unit symbol that doesn't have a frame: 30 + 15000 263 { 264 noFrame = true; 265 strSVGFrame = strSVGFrame.replaceFirst("<g id=\"octagon\">", "<g id=\"octagon\" display=\"none\">"); 266 } 267 268 269 //get SVG dimensions and target dimensions 270 symbolBounds = RectUtilities.makeRect(left,top,width,height); 271 Rect rect = new Rect(symbolBounds); 272 float ratio = -1; 273 274 if (pixelSize > 0 && keepUnitRatio == true) 275 { 276 float heightRatio = SymbolUtilities.getUnitRatioHeight(symbolID); 277 float widthRatio = SymbolUtilities.getUnitRatioWidth(symbolID); 278 279 if(noFrame == true)//using octagon with display="none" as frame for a 1x1 shape 280 { 281 heightRatio = 1.0f; 282 widthRatio = 1.0f; 283 } 284 285 if (heightRatio > widthRatio) 286 { 287 pixelSize = (int) ((pixelSize / 1.5f) * heightRatio); 288 } 289 else 290 { 291 pixelSize = (int) ((pixelSize / 1.5f) * widthRatio); 292 } 293 } 294 if (pixelSize > 0) 295 { 296 float p = pixelSize; 297 float h = rect.height(); 298 float w = rect.width(); 299 300 ratio = Math.min((p / h), (p / w)); 301 302 symbolBounds = RectUtilities.makeRect(0f, 0f, w * ratio, h * ratio); 303 } 304 305 //center of octagon is the center of all unit symbols 306 Point centerOctagon = new Point(306, 396); 307 centerOctagon.offset(-left,-top);//offset for the symbol bounds x,y 308 //scale center point by same ratio as the symbol 309 centerOctagon = new Point((int)(centerOctagon.x * ratio), (int)(centerOctagon.y * ratio)); 310 311 //set centerpoint of the image 312 Point centerPoint = centerOctagon; 313 Point centerCache = new Point(centerOctagon.x, centerOctagon.y); 314 315 //y offset to get centerpoint so we set back to zero when done. 316 symbolBounds.top = 0; 317 318 //Create destination BMP 319 Bitmap bmp = Bitmap.createBitmap(symbolBounds.width(), symbolBounds.height(), Config.ARGB_8888); 320 Canvas canvas = new Canvas(bmp); 321 322 //draw unit from SVG 323 StringBuilder sb = new StringBuilder(); 324 sb.append(svgStart); 325 326 if(strSVGFrame != null) 327 sb.append(strSVGFrame); 328 329 String color = ""; 330 String strokeFill = ""; 331 if(iconColor != null) 332 { 333 //make sure string is properly formatted. 334 color = RendererUtilities.colorToHexString(iconColor,false); 335 if(color != null && color != "#000000" && color != "") 336 strokeFill = " fill=\"" + color + "\" "; 337 else 338 color = null; 339 } 340 String unit = "<g" + strokeFill + ">"; 341 if (siIcon != null) 342 unit += (siIcon.getSVG()); 343 if (siMod1 != null) 344 unit += (siMod1.getSVG()); 345 if (siMod2 != null) 346 unit += (siMod2.getSVG()); 347 if(iconColor != null && color != null && color != "") 348 unit = unit.replaceAll("#000000",color); 349 sb.append(unit + "</g>"); 350 351 sb.append("</svg>"); 352 353 strSVG = sb.toString(); 354 355 mySVG = SVG.getFromString(strSVG); 356 mySVG.setDocumentViewBox(left,top,width,height); 357 mySVG.renderToCanvas(canvas); 358 359 360 //adjust centerpoint for HQStaff if present 361 if (SymbolUtilities.isHQ(symbolID)) 362 { 363 PointF point1 = new PointF(); 364 PointF point2 = new PointF(); 365 int affiliation = SymbolID.getAffiliation(symbolID); 366 int ss = SymbolID.getStandardIdentity(symbolID); 367 if (affiliation == SymbolID.StandardIdentity_Affiliation_Friend 368 || affiliation == SymbolID.StandardIdentity_Affiliation_AssumedFriend 369 || affiliation == SymbolID.StandardIdentity_Affiliation_Neutral 370 || ss == 15 || ss == 16)//exercise joker or faker 371 { 372 point1.x = (symbolBounds.left); 373 point1.y = symbolBounds.top + (symbolBounds.height()); 374 point2.x = point1.x; 375 point2.y = point1.y + symbolBounds.height(); 376 } 377 else 378 { 379 point1.x = (symbolBounds.left + 1); 380 point1.y = symbolBounds.top + (symbolBounds.height() / 2); 381 point2.x = point1.x; 382 point2.y = point1.y + symbolBounds.height(); 383 } 384 centerPoint = new Point((int) point2.x, (int) point2.y); 385 } 386 387 ii = new ImageInfo(bmp, centerPoint, symbolBounds); 388 389 if(cacheEnabled && icon == false && bmp.getAllocationByteCount() <= maxCachedEntrySize) 390 { 391 synchronized (_UnitCacheMutex) 392 { 393 if(_unitCache != null && _unitCache.get(key) == null) 394 _unitCache.put(key, new ImageInfo(bmp, new Point(centerCache), new Rect(symbolBounds))); 395 } 396 } 397 398 /*if(icon == false && pixelSize <= 100) 399 { 400 _unitCache.put(key, new ImageInfo(bmp, new Point(centerCache), new Rect(symbolBounds))); 401 }//*/ 402 } 403 404 ImageInfo iiNew = null; 405 SymbolDimensionInfo sdiTemp = null; 406 //////////////////////////////////////////////////////////////////// 407 //process display modifiers 408 if (hasDisplayModifiers) 409 { 410 sdiTemp = ModifierRenderer.processUnitDisplayModifiers( ii, symbolID, modifiers, hasTextModifiers, attributes); 411 iiNew = (sdiTemp instanceof ImageInfo ? (ImageInfo)sdiTemp : null); 412 sdiTemp = null; 413 } 414 415 if (iiNew != null) 416 { 417 ii = iiNew; 418 } 419 iiNew = null; 420 421 //process text modifiers 422 if (hasTextModifiers) 423 { 424 sdiTemp = ModifierRenderer.processSPTextModifiers(ii, symbolID, modifiers, attributes); 425 } 426 427 iiNew = (sdiTemp instanceof ImageInfo ? (ImageInfo)sdiTemp : null); 428 if (iiNew != null) 429 { 430 ii = iiNew; 431 } 432 iiNew = null; 433 434 if(modifiers != null) 435 ii = (ImageInfo) ModifierRenderer.processSpeedLeader(ii,symbolID,modifiers,attributes); 436 437 //cleanup/////////////////////////////////////////////////////////// 438 //bmp.recycle(); 439 symbolBounds = null; 440 fullBMP = null; 441 fullBounds = null; 442 mySVG = null; 443 //////////////////////////////////////////////////////////////////// 444 445 if (icon == true) 446 { 447 return ii.getSquareImageInfo(); 448 } 449 else 450 { 451 return ii; 452 } 453 454 } 455 catch (Exception exc) 456 { 457 ErrorLogger.LogException("SinglePointRenderer", "RenderUnit", exc); 458 } 459 return null; 460 } 461 462 /** 463 * 464 * @param symbolID 465 * @param modifiers 466 * @return 467 */ 468 @SuppressWarnings("unused") 469 public ImageInfo RenderSP(String symbolID, Map<String,String> modifiers, Map<String,String> attributes) 470 { 471 ImageInfo temp = null; 472 String basicSymbolID = null; 473 474 Color lineColor = SymbolUtilities.getDefaultLineColor(symbolID); 475 Color fillColor = null;//SymbolUtilities.getFillColorOfAffiliation(symbolID); 476 477 int alpha = -1; 478 479 480 //SVG rendering variables 481 MSInfo msi = null; 482 String iconID = null; 483 SVGInfo siIcon = null; 484 String mod1ID = null; 485 SVGInfo siMod1 = null; 486 int top = 0; 487 int left = 0; 488 int width = 0; 489 int height = 0; 490 String svgStart = null; 491 String strSVG = null; 492 SVG mySVG = null; 493 494 float ratio = 0; 495 496 Rect symbolBounds = null; 497 RectF fullBounds = null; 498 Bitmap fullBMP = null; 499 500 boolean drawAsIcon = false; 501 int pixelSize = -1; 502 boolean keepUnitRatio = true; 503 boolean hasDisplayModifiers = false; 504 boolean hasTextModifiers = false; 505 boolean drawCustomOutline = false; 506 507 msi = MSLookup.getInstance().getMSLInfo(symbolID); 508 int ss = SymbolID.getSymbolSet(symbolID); 509 int ec = SymbolID.getEntityCode(symbolID); 510 int mod1 = 0; 511 int drawRule = 0; 512 if(msi!=null){drawRule = msi.getDrawRule();} 513 boolean hasAPFill = false; 514 if(RendererSettings.getInstance().getActionPointDefaultFill()) { 515 if (SymbolUtilities.isActionPoint(symbolID) || //action points 516 ec/100 == 2135 || //sonobuoy 517 ec == 180100 || ec == 180200 || ec == 180400) //ACP, CCP, PUP 518 { 519 if (SymbolID.getSymbolSet(symbolID) == SymbolID.SymbolSet_ControlMeasure) { 520 lineColor = Color.BLACK; 521 hasAPFill = true; 522 } 523 } 524 } 525 526 try 527 { 528 if (modifiers == null) 529 { 530 modifiers = new HashMap<>(); 531 } 532 533 534 //get symbol info 535 536 msi = MSLookup.getInstance().getMSLInfo(symbolID); 537 538 if (msi == null)//if lookup fails, fix code/use unknown symbol code. 539 { 540 //TODO: change symbolID to Action Point with bad symbolID in the T or H field 541 } 542 543 /* Fills built into SVG 544 if (SymbolUtilities.hasDefaultFill(symbolID)) 545 { 546 fillColor = SymbolUtilities.getFillColorOfAffiliation(symbolID); 547 } 548 if (SymbolUtilities.isTGSPWithFill(symbolID)) 549 { 550 fillID = SymbolUtilities.getTGFillSymbolCode(symbolID); 551 if (fillID != null) 552 { 553 charFillIndex = SinglePointLookup.getInstance().getCharCodeFromSymbol(fillID, symStd); 554 } 555 } 556 else if (SymbolUtilities.isWeatherSPWithFill(symbolID)) 557 { 558 charFillIndex = charFrameIndex + 1; 559 fillColor = SymbolUtilities.getFillColorOfWeather(symbolID); 560 561 }//*/ 562 563 if (attributes != null) 564 { 565 if (attributes.containsKey(MilStdAttributes.KeepUnitRatio)) 566 { 567 keepUnitRatio = Boolean.parseBoolean(attributes.get(MilStdAttributes.KeepUnitRatio)); 568 } 569 570 if (attributes.containsKey(MilStdAttributes.LineColor)) 571 { 572 lineColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.LineColor)); 573 } 574 575 if (attributes.containsKey(MilStdAttributes.FillColor)) 576 { 577 fillColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.FillColor)); 578 } 579 580 if (attributes.containsKey(MilStdAttributes.Alpha)) 581 { 582 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 583 } 584 585 if (attributes.containsKey(MilStdAttributes.DrawAsIcon)) 586 { 587 drawAsIcon = Boolean.parseBoolean(attributes.get(MilStdAttributes.DrawAsIcon)); 588 } 589 590 if (attributes.containsKey(MilStdAttributes.PixelSize)) 591 { 592 pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize)); 593 } 594 else 595 { 596 pixelSize = RendererSettings.getInstance().getDefaultPixelSize(); 597 } 598 /*if(keepUnitRatio == true && msi.getSymbolSet() == SymbolID.SymbolSet_ControlMeasure && msi.getGeometry().equalsIgnoreCase("point")) 599 { 600 if(msi.getDrawRule() == DrawRules.POINT1)//Action Points 601 pixelSize = (int)Math.ceil((pixelSize/1.5f) * 2.0f); 602 else if(SymbolID.getSymbolSet(symbolID)==SymbolID.SymbolSet_ControlMeasure && 603 ec/100 == 2135)//Sonobuoy 604 { 605 pixelSize = (int)Math.ceil((pixelSize/1.5f) * 2.0f); 606 } 607 else 608 pixelSize = (int)Math.ceil((pixelSize/1.5f) * 1.2f); 609 }//*/ 610 611 if(!(drawAsIcon==true || hasAPFill==true))//don't outline icons because they're not going on the map and icons with fills don't need it 612 { 613 if (attributes.containsKey(MilStdAttributes.OutlineSymbol)) 614 drawCustomOutline = Boolean.parseBoolean(attributes.get(MilStdAttributes.OutlineSymbol)); 615 else 616 drawCustomOutline = RendererSettings.getInstance().getOutlineSPControlMeasures(); 617 618 //Protection of Cultural Property doesn't get outlined 619 if(ss==25 && ec >= 360000 && ec < 360400) 620 drawCustomOutline = false; 621 } 622 623 if(SymbolUtilities.isMultiPoint(symbolID)) 624 drawCustomOutline=false;//icon previews for multipoints do not need outlines since they shouldn't be on the map 625 } 626 627 if (drawAsIcon)//icon won't show modifiers or display icons 628 { 629 keepUnitRatio = false; 630 hasDisplayModifiers = false; 631 hasTextModifiers = false; 632 drawCustomOutline = false; 633 } 634 else 635 { 636 hasDisplayModifiers = ModifierRenderer.hasDisplayModifiers(symbolID, modifiers); 637 hasTextModifiers = ModifierRenderer.hasTextModifiers(symbolID, modifiers); 638 } 639 640 //Check if we need to set 'N' to "ENY" 641 int aff = SymbolID.getAffiliation(symbolID); 642 //int ss = msi.getSymbolSet(); 643 if (ss == SymbolID.SymbolSet_ControlMeasure && 644 (aff == SymbolID.StandardIdentity_Affiliation_Hostile_Faker || 645 aff == SymbolID.StandardIdentity_Affiliation_Suspect_Joker ) && 646 modifiers.containsKey(Modifiers.N_HOSTILE) && 647 drawAsIcon == false) 648 { 649 modifiers.put(Modifiers.N_HOSTILE, "ENY"); 650 } 651 652 } 653 catch (Exception excModifiers) 654 { 655 ErrorLogger.LogException("SinglePointRenderer", "RenderSP", excModifiers); 656 } 657 658 try 659 { 660 ImageInfo ii = null; 661 int intFill = -1; 662 if (fillColor != null) 663 { 664 intFill = fillColor.toInt(); 665 } 666 667 668 if(msi.getSymbolSet() != SymbolID.SymbolSet_ControlMeasure) 669 lineColor = Color.BLACK;//color isn't black but should be fine for weather since colors can't be user defined. 670 671 672 673 if (SymbolID.getSymbolSet(symbolID)==SymbolID.SymbolSet_ControlMeasure && SymbolID.getEntityCode(symbolID) == 270701)//static depiction 674 { 675 //add mine fill to image 676 mod1 = SymbolID.getModifier1(symbolID); 677 if (!(mod1 >= 13 && mod1 <= 50)) 678 symbolID = SymbolID.setModifier1(symbolID, 13); 679 } 680 681 String key = makeCacheKey(symbolID, lineColor.toInt(), intFill, pixelSize, keepUnitRatio, drawCustomOutline); 682 683 //see if it's in the cache 684 if(_tgCache != null) { 685 ii = _tgCache.get(key); 686 //safety check in case bitmaps are getting recycled while still in the LRU cache 687 if (ii != null && ii.getImage() != null && ii.getImage().isRecycled()) { 688 synchronized (_SinglePointCacheMutex) { 689 _tgCache.remove(key); 690 ii = null; 691 } 692 } 693 } 694 695 //if not, generate symbol. 696 if (ii == null)//*/ 697 { 698 int version = SymbolID.getVersion(symbolID); 699 //check symbol size//////////////////////////////////////////// 700 Rect rect = null; 701 iconID = SVGLookup.getMainIconID(symbolID); 702 siIcon = SVGLookup.getInstance().getSVGLInfo(iconID, version); 703 if(siIcon==null) { 704 return null; 705 } 706 mod1ID = SVGLookup.getMod1ID(symbolID); 707 siMod1 = SVGLookup.getInstance().getSVGLInfo(mod1ID, version); 708 float borderPadding = 0; 709 if (drawCustomOutline) { 710 borderPadding = RendererUtilities.findWidestStrokeWidth(siIcon.getSVG()); 711 } 712 top = (int)Math.floor(siIcon.getBbox().top); 713 left = (int)Math.floor(siIcon.getBbox().left); 714 width = (int)Math.ceil(siIcon.getBbox().width() + (siIcon.getBbox().left - left)); 715 height = (int)Math.ceil(siIcon.getBbox().height() + (siIcon.getBbox().top - top)); 716 if(siIcon.getBbox().bottom > 400) 717 svgStart = "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 612 792\">"; 718 else 719 svgStart = "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 400 400\">"; 720 721 String strSVGIcon = null; 722 723 if(keepUnitRatio) 724 { 725 double scaler = Math.max(width/(float)height, height/(float)width); 726 if (scaler < 1.2) 727 scaler = 1.2; 728 if (scaler > 2) 729 scaler = 2; 730 731 if(!SymbolUtilities.isCBRNEvent(symbolID)) 732 pixelSize = (int) Math.ceil((pixelSize / 1.5f) * scaler); 733 734 /* 735 double min = Math.min(width/(float)height, height/(float)width); 736 if (min < 0.6)//Rectangle 737 pixelSize = (int) Math.ceil((pixelSize / 1.5f) * 2.0f); 738 else if(min < 0.85) 739 pixelSize = (int) Math.ceil((pixelSize / 1.5f) * 1.8f); 740 else //more of a square 741 pixelSize = (int) Math.ceil((pixelSize / 1.5f) * 1.2f);//*/ 742 } 743 744 if(hasAPFill) //action points and a few others //Sonobuoy //ACP, CCP, PUP 745 { 746 String apFill; 747 if(fillColor != null) 748 apFill = RendererUtilities.colorToHexString(fillColor,false); 749 else 750 apFill = RendererUtilities.colorToHexString(SymbolUtilities.getFillColorOfAffiliation(symbolID),false); 751 siIcon = new SVGInfo(siIcon.getID(),siIcon.getBbox(), siIcon.getSVG().replaceAll("fill=\"none\"","fill=\"" + apFill + "\"")); 752 } 753 754 //Set dash array depending on affiliation and status 755 siIcon = RendererUtilities.setAffiliationDashArray(symbolID, siIcon); 756 757 //update line and fill color of frame SVG 758 if(msi.getSymbolSet() == SymbolID.SymbolSet_ControlMeasure && (lineColor != null || fillColor != null)) { 759 if (drawCustomOutline) { 760 // create outline with larger stroke-width first (if selected) 761 strSVGIcon = RendererUtilities.setSVGSPCMColors(symbolID, siIcon.getSVG(), RendererUtilities.getIdealOutlineColor(lineColor), fillColor, true); 762 } 763 764 // append normal symbol SVG to be layered on top of outline 765 strSVGIcon += RendererUtilities.setSVGSPCMColors(symbolID, siIcon.getSVG(), lineColor, fillColor, false); 766 } 767 else//weather symbol (don't change color of weather graphics) 768 strSVGIcon = siIcon.getSVG(); 769 770 //If symbol is Static Depiction, add internal mine graphic based on sector modifier 1 771 if(SymbolID.getEntityCode(symbolID) == 270701 && siMod1 != null) 772 { 773 if (drawCustomOutline) { 774 // create outline with larger stroke-width first (if selected) 775 strSVGIcon += RendererUtilities.setSVGSPCMColors(mod1ID, siMod1.getSVG(), RendererUtilities.getIdealOutlineColor(RendererUtilities.getColorFromHexString("#00A651")), RendererUtilities.getColorFromHexString("#00A651"), true); 776 } 777 //strSVGIcon += siMod1.getSVG(); 778 strSVGIcon += RendererUtilities.setSVGSPCMColors(mod1ID, siMod1.getSVG(), lineColor, fillColor, false); 779 } 780 781 if (pixelSize > 0) 782 { 783 symbolBounds = RectUtilities.makeRect(left,top,width,height); 784 rect = new Rect(symbolBounds); 785 786 //adjust size 787 float p = pixelSize; 788 float h = rect.height(); 789 float w = rect.width(); 790 791 ratio = Math.min((p / h), (p / w)); 792 793 symbolBounds = RectUtilities.makeRect(0f, 0f, w * ratio, h * ratio); 794 795 //make sure border padding isn't excessive. 796 w = symbolBounds.width(); 797 h = symbolBounds.height(); 798 799 if(borderPadding > 0) { 800 if (h / (h + borderPadding) > 0.10) { 801 borderPadding = (float) (h * 0.1); 802 } else if (w / (w + borderPadding) > 0.10) { 803 borderPadding = (float) (w * 0.1); 804 } 805 } 806 } 807 808 //Draw glyphs to bitmap 809 Bitmap bmp = Bitmap.createBitmap((symbolBounds.width() + Math.round(borderPadding)), (symbolBounds.height() + Math.round(borderPadding)), Config.ARGB_8888); 810 Canvas canvas = new Canvas(bmp); 811 812 symbolBounds = new Rect(0, 0, bmp.getWidth(), bmp.getHeight()); 813 814 //grow size SVG to accommodate the outline we added 815 int offset = 0; 816 if(drawCustomOutline) 817 { 818 RectUtilities.grow(rect, 2); 819 offset = 4; 820 821 //RectUtilities.grow(rect, Math.round(borderPadding / ratio)); 822 //offset = (int)borderPadding; 823 }//*/ 824 825 826 if(SymbolUtilities.isActionPoint(symbolID))//smooth out action points 827 strSVGIcon = "/n<g stroke-linejoin=\"round\" >/n" + strSVGIcon + "/n</g>"; 828 829 strSVG = svgStart + strSVGIcon + "</svg>"; 830 mySVG = SVG.getFromString(strSVG); 831 //mySVG.setDocumentViewBox(left,top,width,height); 832 mySVG.setDocumentViewBox(rect.left,rect.top,rect.width(),rect.height()); 833 mySVG.renderToCanvas(canvas); 834 835 Point centerPoint = SymbolUtilities.getCMSymbolAnchorPoint(symbolID,new RectF(offset, offset, symbolBounds.right-offset, symbolBounds.bottom-offset)); 836 if(offset > 0) 837 centerPoint.offset(offset,offset); 838 839 ii = new ImageInfo(bmp, centerPoint, symbolBounds); 840 841 if(cacheEnabled && drawAsIcon == false && bmp.getAllocationByteCount() <= maxCachedEntrySize) 842 { 843 synchronized (_SinglePointCacheMutex) 844 { 845 if(_tgCache.get(key) == null) 846 _tgCache.put(key, ii); 847 } 848 } 849 /*if (drawAsIcon == false && pixelSize <= 100) 850 851 _tgCache.put(key, ii); 852 }//*/ 853 } 854 855 //Process Modifiers 856 ImageInfo iiNew = null; 857 if (drawAsIcon == false && (hasTextModifiers || hasDisplayModifiers)) 858 { 859 SymbolDimensionInfo sdiTemp = null; 860 if (SymbolUtilities.isSPWithSpecialModifierLayout(symbolID))//(SymbolUtilitiesD.isTGSPWithSpecialModifierLayout(symbolID)) 861 { 862 sdiTemp = ModifierRenderer.ProcessTGSPWithSpecialModifierLayout(ii, symbolID, modifiers, attributes, lineColor); 863 } 864 else 865 { 866 sdiTemp = ModifierRenderer.ProcessTGSPModifiers(ii, symbolID, modifiers, attributes, lineColor); 867 } 868 iiNew = (sdiTemp instanceof ImageInfo ? (ImageInfo)sdiTemp : null); 869 } 870 871 if (iiNew != null) 872 { 873 ii = iiNew; 874 } 875 876 //cleanup 877 //bmp.recycle(); 878 symbolBounds = null; 879 fullBMP = null; 880 fullBounds = null; 881 mySVG = null; 882 883 884 if (drawAsIcon) 885 { 886 return ii.getSquareImageInfo(); 887 } 888 else 889 { 890 return ii; 891 } 892 893 } 894 catch (Exception exc) 895 { 896 ErrorLogger.LogException("SinglePointRenderer", "RenderSP(" + SymbolUtilities.getBasicSymbolID(symbolID) + ")", exc); 897 } 898 return null; 899 } 900 901 902 /** 903 * 904 * @param symbolID 905 * @return 906 */ 907 @SuppressWarnings("unused") 908 public ImageInfo RenderModifier(String symbolID, Map<String,String> attributes) 909 { 910 ImageInfo temp = null; 911 String basicSymbolID = null; 912 913 Color lineColor = null; 914 Color fillColor = null;//SymbolUtilities.getFillColorOfAffiliation(symbolID); 915 916 int alpha = -1; 917 918 919 //SVG rendering variables 920 MSInfo msi = null; 921 String iconID = null; 922 SVGInfo siIcon = null; 923 int top = 0; 924 int left = 0; 925 int width = 0; 926 int height = 0; 927 String svgStart = null; 928 String strSVG = null; 929 SVG mySVG = null; 930 931 float ratio = 0; 932 933 Rect symbolBounds = null; 934 RectF fullBounds = null; 935 Bitmap fullBMP = null; 936 937 boolean drawAsIcon = false; 938 int pixelSize = -1; 939 boolean keepUnitRatio = true; 940 boolean hasDisplayModifiers = false; 941 boolean hasTextModifiers = false; 942 int symbolOutlineWidth = RendererSettings.getInstance().getSinglePointSymbolOutlineWidth(); 943 boolean drawCustomOutline = false; 944 945 try 946 { 947 948 msi = MSLookup.getInstance().getMSLInfo(symbolID); 949 if (attributes != null) 950 { 951 if (attributes.containsKey(MilStdAttributes.KeepUnitRatio)) 952 { 953 keepUnitRatio = Boolean.parseBoolean(attributes.get(MilStdAttributes.KeepUnitRatio)); 954 } 955 956 if (attributes.containsKey(MilStdAttributes.LineColor)) 957 { 958 lineColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.LineColor)); 959 } 960 961 if (attributes.containsKey(MilStdAttributes.FillColor)) 962 { 963 fillColor = RendererUtilities.getColorFromHexString(attributes.get(MilStdAttributes.FillColor)); 964 } 965 966 if (attributes.containsKey(MilStdAttributes.Alpha)) 967 { 968 alpha = Integer.parseInt(attributes.get(MilStdAttributes.Alpha)); 969 } 970 971 if (attributes.containsKey(MilStdAttributes.DrawAsIcon)) 972 { 973 drawAsIcon = Boolean.parseBoolean(attributes.get(MilStdAttributes.DrawAsIcon)); 974 } 975 976 if (attributes.containsKey(MilStdAttributes.PixelSize)) 977 { 978 pixelSize = Integer.parseInt(attributes.get(MilStdAttributes.PixelSize)); 979 if(msi.getSymbolSet() == SymbolID.SymbolSet_ControlMeasure) 980 { 981 if(SymbolID.getEntityCode(symbolID)==270701)//static depiction 982 pixelSize = (int)(pixelSize * 0.9);//try to scale to be somewhat in line with units 983 } 984 } 985 986 if(drawAsIcon==false)//don't outline icons because they're not going on the map 987 { 988 if(attributes.containsKey(MilStdAttributes.OutlineSymbol)) 989 drawCustomOutline = Boolean.parseBoolean(attributes.get(MilStdAttributes.OutlineSymbol)); 990 else 991 drawCustomOutline = RendererSettings.getInstance().getOutlineSPControlMeasures(); 992 } 993 994 if(SymbolUtilities.isMultiPoint(symbolID)) 995 drawCustomOutline=false;//icon previews for multipoints do not need outlines since they shouldn't be on the map 996 997 /*if (attributes.containsKey(MilStdAttributes.OutlineWidth)>=0) 998 symbolOutlineWidth = Integer.parseInt(attributes.get(MilStdAttributes.OutlineWidth));//*/ 999 } 1000 1001 int outlineOffset = symbolOutlineWidth; 1002 if (drawCustomOutline && outlineOffset > 2) 1003 { 1004 outlineOffset = (outlineOffset - 1) / 2; 1005 } 1006 else 1007 { 1008 outlineOffset = 0; 1009 } 1010 1011 } 1012 catch (Exception excModifiers) 1013 { 1014 ErrorLogger.LogException("SinglePointRenderer", "RenderModifier", excModifiers); 1015 } 1016 1017 try 1018 { 1019 ImageInfo ii = null; 1020 int intFill = -1; 1021 if (fillColor != null) 1022 { 1023 intFill = fillColor.toInt(); 1024 } 1025 1026 1027 if(msi.getSymbolSet() != SymbolID.SymbolSet_ControlMeasure) 1028 lineColor = Color.BLACK;//color isn't black but should be fine for weather since colors can't be user defined. 1029 1030 1031 //if not, generate symbol 1032 if (ii == null)//*/ 1033 { 1034 int version = SymbolID.getVersion(symbolID); 1035 //check symbol size//////////////////////////////////////////// 1036 Rect rect = null; 1037 1038 iconID = SVGLookup.getMod1ID(symbolID); 1039 siIcon = SVGLookup.getInstance().getSVGLInfo(iconID, version); 1040 top = Math.round(siIcon.getBbox().top); 1041 left = Math.round(siIcon.getBbox().left); 1042 width = Math.round(siIcon.getBbox().width()); 1043 height = Math.round(siIcon.getBbox().height()); 1044 if(siIcon.getBbox().bottom > 400) 1045 svgStart = "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 612 792\">"; 1046 else 1047 svgStart = "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 400 400\">"; 1048 1049 String strSVGIcon = null; 1050 String strSVGOutline = null; 1051 1052 //update line and fill color of frame SVG 1053 if(msi.getSymbolSet() == SymbolID.SymbolSet_ControlMeasure && (lineColor != null || fillColor != null)) 1054 strSVGIcon = RendererUtilities.setSVGFrameColors(symbolID,siIcon.getSVG(),lineColor,fillColor); 1055 else 1056 strSVGIcon = siIcon.getSVG(); 1057 1058 if (pixelSize > 0) 1059 { 1060 symbolBounds = RectUtilities.makeRect(left,top,width,height); 1061 rect = new Rect(symbolBounds); 1062 1063 //adjust size 1064 float p = pixelSize; 1065 float h = rect.height(); 1066 float w = rect.width(); 1067 1068 ratio = Math.min((p / h), (p / w)); 1069 1070 symbolBounds = RectUtilities.makeRect(0f, 0f, w * ratio, h * ratio); 1071 1072 } 1073 1074 1075 //TODO: figure out how to draw an outline and adjust the symbol bounds accordingly 1076 1077 //Draw glyphs to bitmap 1078 Bitmap bmp = Bitmap.createBitmap((symbolBounds.width()), (symbolBounds.height()), Config.ARGB_8888); 1079 Canvas canvas = new Canvas(bmp); 1080 1081 symbolBounds = new Rect(0, 0, bmp.getWidth(), bmp.getHeight()); 1082 1083 strSVG = svgStart + strSVGIcon + "</svg>"; 1084 mySVG = SVG.getFromString(strSVG); 1085 mySVG.setDocumentViewBox(left,top,width,height); 1086 mySVG.renderToCanvas(canvas); 1087 1088 Point centerPoint = SymbolUtilities.getCMSymbolAnchorPoint(symbolID,new RectF(0, 0, symbolBounds.right, symbolBounds.bottom)); 1089 1090 ii = new ImageInfo(bmp, centerPoint, symbolBounds); 1091 1092 1093 /*if (drawAsIcon == false && pixelSize <= 100) 1094 { 1095 _tgCache.put(key, ii); 1096 }//*/ 1097 } 1098 1099 1100 //cleanup 1101 //bmp.recycle(); 1102 symbolBounds = null; 1103 fullBMP = null; 1104 fullBounds = null; 1105 mySVG = null; 1106 1107 1108 if (drawAsIcon) 1109 { 1110 return ii.getSquareImageInfo(); 1111 } 1112 else 1113 { 1114 return ii; 1115 } 1116 1117 } 1118 catch (Exception exc) 1119 { 1120 ErrorLogger.LogException("SinglePointRenderer", "RenderModifier", exc); 1121 } 1122 return null; 1123 } 1124 1125 1126 1127 /** 1128 * 1129 * @param symbolID 1130 * @param lineColor 1131 * @param fillColor 1132 * @param size 1133 * @param keepUnitRatio 1134 * @param drawOutline (only for single-point Control Measures) 1135 * @return 1136 */ 1137 private static String makeCacheKey(String symbolID, int lineColor, int fillColor, int size, boolean keepUnitRatio, boolean drawOutline) 1138 { 1139 return makeCacheKey(symbolID, lineColor, fillColor, "null",size, keepUnitRatio, false); 1140 } 1141 1142 private static String makeCacheKey(String symbolID, int lineColor, int fillColor, String iconColor, int size, boolean keepUnitRatio, boolean drawOutline) 1143 { 1144 //String key = symbolID.substring(0, 20) + String.valueOf(lineColor) + String.valueOf(fillColor) + String.valueOf(size) + String.valueOf(keepUnitRatio); 1145 String key = symbolID.substring(0, 7) + symbolID.substring(10, 20) + SymbolID.getFrameShape(symbolID) + lineColor + fillColor + iconColor + size + keepUnitRatio + drawOutline; 1146 return key; 1147 } 1148 1149 public void logError(String tag, Throwable thrown) 1150 { 1151 if (tag == null || tag.equals("")) 1152 { 1153 tag = "singlePointRenderer"; 1154 } 1155 1156 String message = thrown.getMessage(); 1157 String stack = getStackTrace(thrown); 1158 if (message != null) 1159 { 1160 Log.e(tag, message); 1161 } 1162 if (stack != null) 1163 { 1164 Log.e(tag, stack); 1165 } 1166 } 1167 1168 public String getStackTrace(Throwable thrown) 1169 { 1170 try 1171 { 1172 if (thrown != null) 1173 { 1174 if (thrown.getStackTrace() != null) 1175 { 1176 String eol = System.getProperty("line.separator"); 1177 StringBuilder sb = new StringBuilder(); 1178 sb.append(thrown.toString()); 1179 sb.append(eol); 1180 for (StackTraceElement element : thrown.getStackTrace()) 1181 { 1182 sb.append(" at "); 1183 sb.append(element); 1184 sb.append(eol); 1185 } 1186 return sb.toString(); 1187 } 1188 else 1189 { 1190 return thrown.getMessage() + "- no stack trace"; 1191 } 1192 } 1193 else 1194 { 1195 return "no stack trace"; 1196 } 1197 } 1198 catch (Exception exc) 1199 { 1200 Log.e("getStackTrace", exc.getMessage()); 1201 } 1202 return thrown.getMessage(); 1203 }// 1204 1205 /* 1206 private static String PrintList(ArrayList list) 1207 { 1208 String message = ""; 1209 for(Object item : list) 1210 { 1211 1212 message += item.toString() + "\n"; 1213 } 1214 return message; 1215 }//*/ 1216 /* 1217 private static String PrintObjectMap(Map<String, Object> map) 1218 { 1219 Iterator<Object> itr = map.values().iterator(); 1220 String message = ""; 1221 String temp = null; 1222 while(itr.hasNext()) 1223 { 1224 temp = String.valueOf(itr.next()); 1225 if(temp != null) 1226 message += temp + "\n"; 1227 } 1228 //ErrorLogger.LogMessage(message); 1229 return message; 1230 }//*/ 1231 @Override 1232 public void onSettingsChanged(SettingsChangedEvent sce) 1233 { 1234 1235 if(sce != null && sce.getEventType().equals(SettingsChangedEvent.EventType_FontChanged)) 1236 { 1237 synchronized (_modifierFontMutex) 1238 { 1239 _modifierFont = RendererSettings.getInstance().getModiferFont(); 1240 _modifierOutlineFont = RendererSettings.getInstance().getModiferFont(); 1241 FontMetrics fm = new FontMetrics(); 1242 fm = _modifierFont.getFontMetrics(); 1243 _modifierDescent = fm.descent; 1244 //_modifierFontHeight = fm.top + fm.bottom; 1245 _modifierFontHeight = fm.bottom - fm.top; 1246 1247 _modifierFont.setStrokeWidth(RendererSettings.getInstance().getTextOutlineWidth()); 1248 _modifierOutlineFont.setColor(Color.white.toInt()); 1249 _deviceDPI = RendererSettings.getInstance().getDeviceDPI(); 1250 1251 ModifierRenderer.setModifierFont(_modifierFont, _modifierFontHeight, _modifierDescent); 1252 1253 } 1254 } 1255 1256 if(sce != null && sce.getEventType().equals(SettingsChangedEvent.EventType_CacheSizeChanged)) 1257 { 1258 1259 int cSize = RendererSettings.getInstance().getCacheSize()/2; 1260 //adjust unit cache 1261 if(cSize != cacheSize) { 1262 cacheSize = cSize; 1263 if (cacheSize >= 5) 1264 maxCachedEntrySize = cacheSize / 5; 1265 else 1266 maxCachedEntrySize = 1; 1267 1268 if(cacheEnabled) //if cache enabled, update cache 1269 { 1270 1271 synchronized (_UnitCacheMutex) { 1272 if(_unitCache != null) 1273 _unitCache.evictAll(); 1274 _unitCache = new LruCache<String, ImageInfo>(cSize) { 1275 @Override 1276 protected int sizeOf(String key, ImageInfo ii) { 1277 return ii.getByteCount();// / 1024; 1278 } 1279 }; 1280 } 1281 //adjust tg cache 1282 synchronized (_SinglePointCacheMutex) { 1283 if(_tgCache != null) 1284 _tgCache.evictAll(); 1285 _tgCache = new LruCache<String, ImageInfo>(cSize) { 1286 @Override 1287 protected int sizeOf(String key, ImageInfo ii) { 1288 return ii.getByteCount();// / 1024; 1289 } 1290 }; 1291 } 1292 } 1293 } 1294 } 1295 if(sce != null && sce.getEventType().equals(SettingsChangedEvent.EventType_CacheToggled)) 1296 { 1297 if(cacheEnabled != RendererSettings.getInstance().getCacheEnabled()) 1298 { 1299 cacheEnabled = RendererSettings.getInstance().getCacheEnabled(); 1300 1301 if (cacheEnabled == false) 1302 { 1303 synchronized (_SinglePointCacheMutex) 1304 { 1305 if (_tgCache != null) 1306 _tgCache.evictAll(); 1307 _tgCache = null; 1308 } 1309 synchronized (_UnitCacheMutex) 1310 { 1311 if (_unitCache != null) 1312 _unitCache.evictAll(); 1313 _unitCache = null; 1314 } 1315 } 1316 else 1317 { 1318 int cSize = RendererSettings.getInstance().getCacheSize() / 2; 1319 synchronized (_SinglePointCacheMutex) 1320 { 1321 if(_tgCache != null) 1322 _tgCache.evictAll(); 1323 _tgCache = new LruCache<String, ImageInfo>(cSize) { 1324 @Override 1325 protected int sizeOf(String key, ImageInfo ii) { 1326 return ii.getByteCount();// / 1024; 1327 } 1328 }; 1329 } 1330 synchronized (_UnitCacheMutex) 1331 { 1332 if(_unitCache != null) 1333 _unitCache.evictAll(); 1334 _unitCache = new LruCache<String, ImageInfo>(cSize) { 1335 @Override 1336 protected int sizeOf(String key, ImageInfo ii) { 1337 return ii.getByteCount();// / 1024; 1338 } 1339 }; 1340 } 1341 } 1342 } 1343 } 1344 } 1345}