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