001package armyc2.c2sd.renderer; 002 003import android.graphics.Bitmap; 004import android.graphics.BitmapFactory; 005import android.graphics.Canvas; 006import android.graphics.Point; 007import android.graphics.Rect; 008import android.util.Base64; 009import android.util.SparseArray; 010 011import armyc2.c2sd.renderer.utilities.ImageInfo; 012import armyc2.c2sd.renderer.utilities.MilStdAttributes; 013 014 015/** 016 * Created by michael.spinelli on 8/23/2017. 017 */ 018 019public class PatternFillRenderer { 020 021 022 private static String duriBeachSlopeModerate = "iVBORw0KGgoAAAANSUhEUgAAADYAAAAzBAMAAAAupuZdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAYUExURQAAAMXFxczMzM3NzdXV1dnZ2eLi4ubm5nz94OEAAAABdFJOUwBA5thmAAAAWklEQVQ4y2NgoD8wA5PMCQgSKgTkCjuAKEMTBAkRYgIyhAxAfCNlBAkVAgJ3MMlSgCChQiMc4AtrIcywFoKFtTJmWCuPhjXJaVcIT9odDU/qpl1hPGl3SJUTACZHFZF+np+2AAAAAElFTkSuQmCC"; 023 private static String duriBeachSlopeSteep = "iVBORw0KGgoAAAANSUhEUgAAABoAAAAaBAMAAABbZFH9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAVUExURQAAAJSUlKKioru7u87OztfX1+Li4hAmdeYAAAABdFJOUwBA5thmAAAAJElEQVQY02NgIB+YIpEMzEIOMJIJiAQVGGAkELghkfQHg8WdABqRBBGoXfbeAAAAAElFTkSuQmCC"; 024 private static String duriBeigeStipple = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9gMHhIBKQOEJ3wAAAADUExURfnz8ehEBXEAAAAMSURBVAgdY2AYjAAAAJYAASEQeSYAAAAASUVORK5CYII="; 025 private static String duriFoulGround = "iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABOUExURQAAAICAgIaGhouLi42NjZCQkJSUlJiYmJycnKCgoKWlpampqa6urrGxsbe3t7u7u7y8vMbGxsjIyMzMzNHR0djY2N/f3+Xl5evr6/Ly8oBtGtwAAAABdFJOUwBA5thmAAAA50lEQVRIx+2UwW7DMAxDySVy0iqRl7WL6v//0R2GDttR8iHoEN4JU7T0gFOngrpZBZqZZ8yFM1DJe8LbRl4ApTwS5k/SgJklk3olHRBeo8bdzArH1ZSUaGPG37KYuf4x12DT7u/k4l5Y3Fuur1bifQGAcgL28MDfsYWzu5JbOHZX213m3UZSq76xmNkenfrK8lzvzD1enusdlg9cAKVkHt7IDRBOGXNzB+D+wH/R4VAdk1CtwJz7xE6oDqstpETv5bgz/4Hq1ANV6YNqzdyacHJX8iMcux4I1YHUqgPl1aCqJ1RPvZy+AED/Df1MKozlAAAAAElFTkSuQmCC"; 026 private static String duriKelp = "iVBORw0KGgoAAAANSUhEUgAAAFUAAAA5CAMAAABwHZdJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABFUExURQAAAICAgIeHh4qKio+Pj5KSkpSUlJqamp6enqGhoaenp6+vr7Gxsbi4uMDAwMjIyM/Pz9bW1tra2t7e3uDg4OXl5evr67APy9YAAAABdFJOUwBA5thmAAABCUlEQVQYGe3BQXbCMAwFwO8KXMWJI6uudP+j9kGB57AjMaw8AwzD8FnueAON6MDxJGUcx5QNG1HQgcRzQcOpoAP9msKiuNF1CjOeVbxojgYUDknUJIVF7DedDRuF8BrL+FclBVJcFUoVd1aYHXslUjwUpjhRuOBZsZfQikadKP3gIGd2NFJUHCZB0FBa0cGM1kqG7owdwzB8TsU7kOENlHCcECs2MqMDTbQ4GpnRgX9HigU3VdLp5HjihtcUEqDOxLlYzcRSLQfBhlPBa2bDlclyChlXnmLBnddMir2EMh5sDueJw0VMBXtZTI5GDpMYDlqpoFFCxmEWE1rMjuOyouG0oj9SDMPwcX/MrgqpcUsGFwAAAABJRU5ErkJggg=="; 027 private static String duriRigField = "iVBORw0KGgoAAAANSUhEUgAAACwAAAAsBAMAAADsqkcyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAqUExURQAAAMDAwMTExMjIyM3NzdHR0dXV1dnZ2d3d3eHh4eXl5enp6e3t7fDw8Awi1VsAAAABdFJOUwBA5thmAAAAh0lEQVQoz2NgGAqATdAHxiwSngBj8goKCkI5TIKCojBhZqCwAIRZCGRugCpmBLKlIGxFIDMBqhokLAlhAlmCAUjC0hCmIZBZABVmBbIVIMyJQOYFmJ2GgkIH4Cok4e7mCm2AMbeFX2AYBbgBjqDCHrDYo4EXR6ThiWIsCQJ78sGV2HAkzUENAN13GlU/PHOyAAAAAElFTkSuQmCC"; 028 private static String duriSweptArea = "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAnUExURQAAAP4A/v41/v5k/v51/v6F/v6T/v6h/v6t/v7E/v7P/v7Z/v7j/s8+NL4AAAABdFJOUwBA5thmAAAAbElEQVQoz2NgGHLgmKHZAVQRVkFBQVFUIUOgkKABsggLSERQBFloIlhIcAK6PkFBByQhiIigAEKEGyokjVcIi0YGRYiQApJQIUSoAEmICSwihOxUTrCQJAOG8yegCPEECgrGoAfYigUMwwIAAJevDkkSlISwAAAAAElFTkSuQmCC"; 029 private static String duriWeirs = "iVBORw0KGgoAAAANSUhEUgAAACQAAAAiBAMAAADFd2a2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAAhUExURQAAAMDAwMTExMjIyM7OztHR0dXV1d3d3eHh4enp6fDw8MnCp1cAAAABdFJOUwBA5thmAAAASUlEQVQoz2NgIBp4YoiwCU7AEFOUxBBioqEy1lAgCBEUCQUDsNBCQWSwACxk0QEE7R1gYAgRCkAyJXDICWHxI6YQ1ypkwDB4AQCRDzCzcuhQTwAAAABJRU5ErkJggg=="; 030 031 private static Bitmap patternBeachSlopeModerate = null; 032 private static Bitmap patternBeachSlopeSteep = null; 033 private static Bitmap patternBeigeStipple = null; 034 private static Bitmap patternFoulGround = null; 035 private static Bitmap patternKelp = null; 036 private static Bitmap patternRigField = null; 037 private static Bitmap patternSweptArea = null; 038 private static Bitmap patternWeirs = null; 039 040 public static Bitmap MakeSymbolPatternFill(String symbolFillIDs, int symbolFillSize) 041 { 042 String[] IDs = symbolFillIDs.split(","); 043 return MakeSymbolPatternFill(IDs, symbolFillSize); 044 } 045 046 public static Bitmap MakeSymbolPatternFill(String[] symbolFillIDs, int symbolFillSize) 047 { 048 Bitmap fill = null; 049 int symCount = symbolFillIDs.length; 050 ImageInfo[] symbols = new ImageInfo[symCount]; 051 int width = 0; 052 int height = 0; 053 int top = 0; 054 int bottom = 0; 055 int spacerW = 0; 056 int spacerH = 0; 057 Rect rect = null; 058 SparseArray<String> mods = new SparseArray<String>(); 059 SparseArray<String> sa = new SparseArray<String>(); 060 sa.put(MilStdAttributes.PixelSize, String.valueOf(symbolFillSize)); 061 062 //calculate texture dimensions 063 for(int i = 0; i < symCount; i++) 064 { 065 if(symbolFillIDs[i].charAt(0)=='W') 066 mods.put(MilStdAttributes.OutlineSymbol,"false"); 067 else 068 mods.put(MilStdAttributes.OutlineSymbol,"true"); 069 symbols[i] = MilStdIconRenderer.getInstance().RenderIcon(symbolFillIDs[i],mods,sa); 070 if(symbols[i] != null) 071 { 072 rect = symbols[i].getImageBounds(); 073 074 if(rect.width() > width) 075 width = rect.width(); 076 if(rect.height() > height) 077 height = rect.height(); 078 if(top < symbols[i].getCenterPoint().y) 079 top = symbols[i].getCenterPoint().y; 080 if(bottom < rect.height() - symbols[i].getCenterPoint().y) 081 bottom = rect.height() - symbols[i].getCenterPoint().y; 082 } 083 } 084 height = top + bottom; 085 spacerW = width / 3; 086 spacerH = height / 3; 087 088 //create bitmap 089 int bWidth = (width * symCount) + (spacerW * symCount); 090 int bHeight = height + spacerH; 091 if(bWidth > 0 && bHeight > 0) 092 { 093 fill = Bitmap.createBitmap(bWidth,bHeight, Bitmap.Config.ARGB_8888); 094 Canvas canvas = new Canvas(fill); 095 //draw to bitmap 096 int x = spacerW; 097 int y = spacerH; 098 for(int j = 0; j < symCount; j++) 099 { 100 ImageInfo ii = symbols[j]; 101 if(ii != null) 102 { 103 Point center = ii.getCenterPoint(); 104 canvas.drawBitmap(ii.getImage(),x + width/2 - center.x, y + top - center.y,null); 105 x += spacerW + width; 106 } 107 } 108 } 109 return fill; 110 } 111 112 /*public static Bitmap MakeSymbolPatternFill(ImageInfo[] iia) 113 { 114 Bitmap fill = null; 115 int imageCount = 0; 116 int width = 0; 117 int height = 0; 118 int top = 0; 119 int bottom = 0; 120 int spacerW = 0; 121 int spacerH = 0; 122 Rect rect = null; 123 124 if(iia != null) 125 imageCount = iia.length; 126 127 //calculate texture dimensions 128 for(int i = 0; i < imageCount; i++) 129 { 130 rect = iia[i].getImageBounds(); 131 if(rect.width() > width) 132 width = rect.width(); 133 if(rect.height() > height) 134 height = rect.height(); 135 if(top < iia[i].getCenterPoint().y) 136 top = iia[i].getCenterPoint().y; 137 if(bottom < rect.height() - iia[i].getCenterPoint().y) 138 bottom = rect.height() - iia[i].getCenterPoint().y; 139 } 140 height = top + bottom; 141 spacerW = width / 3; 142 spacerH = height / 3; 143 144 //create bitmap 145 int bWidth = (width * imageCount) + (spacerW * imageCount); 146 int bHeight = height + spacerH; 147 fill = Bitmap.createBitmap(bWidth,bHeight, Bitmap.Config.ARGB_8888); 148 Canvas canvas = new Canvas(fill); 149 //draw to bitmap 150 int x = spacerW; 151 int y = spacerH; 152 for(int j = 0; j < imageCount; j++) 153 { 154 ImageInfo ii = iia[j]; 155 Point center = ii.getCenterPoint(); 156 canvas.drawBitmap(ii.getImage(),x + width/2 - center.x, y + top - center.y,null); 157 x += spacerW + width; 158 } 159 160 return fill; 161 }//*/ 162 163 public static Bitmap MakeMetocPatternFill(String symbolID) 164 { 165 if(symbolID.equals("WO-DBSM-----A--"))//beach slope moderate 166 { 167 if(patternBeachSlopeModerate == null) 168 patternBeachSlopeModerate = LoadBMPFromDataURL(duriBeachSlopeModerate); 169 return patternBeachSlopeModerate; 170 } 171 else if(symbolID.equals("WO-DBST-----A--"))//beach slope steep 172 { 173 if(patternBeachSlopeSteep == null) 174 patternBeachSlopeSteep = LoadBMPFromDataURL(duriBeachSlopeSteep); 175 return patternBeachSlopeSteep; 176 } 177 else if(symbolID.equals("WO-DHCB-----A--"))//beige stipple 178 { 179 if(patternBeigeStipple == null) 180 patternBeigeStipple = LoadBMPFromDataURL(duriBeigeStipple); 181 return patternBeigeStipple; 182 } 183 else if(symbolID.equals("WO-DHHDF----A--"))//Foul Ground 184 { 185 if(patternFoulGround == null) 186 patternFoulGround = LoadBMPFromDataURL(duriFoulGround); 187 return patternFoulGround; 188 } 189 else if(symbolID.equals("WO-DHHDK----A--"))//Kelp 190 { 191 if(patternKelp == null) 192 patternKelp = LoadBMPFromDataURL(duriKelp); 193 return patternKelp; 194 } 195 else if(symbolID.equals("WO-DMOA-----A--"))//OIL/GAS RIG FIELD 196 { 197 if(patternRigField == null) 198 patternRigField = LoadBMPFromDataURL(duriRigField); 199 return patternRigField; 200 } 201 else if(symbolID.equals("WO-DL-SA----A--"))//swept area 202 { 203 if(patternSweptArea == null) 204 patternSweptArea = LoadBMPFromDataURL(duriSweptArea); 205 return patternSweptArea; 206 } 207 else if(symbolID.equals("WOS-HPFF----A--"))//Weirs 208 { 209 if(patternWeirs == null) 210 patternWeirs = LoadBMPFromDataURL(duriWeirs); 211 return patternWeirs; 212 } 213 else 214 return null; 215 } 216 217 private static Bitmap LoadBMPFromDataURL(String durl) 218 { 219 byte[] decodedString = Base64.decode(durl, Base64.DEFAULT); 220 Bitmap bmp = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); 221 return bmp; 222 } 223 224 public static Bitmap MakeHatchPatternFill() 225 { 226 return null; 227 } 228 229 /*private static Bitmap[] fillBMP = null; 230 231 protected static boolean createBitmapShader(TGLight tg, 232 ShapeInfo shape, 233 Context context) 234 { 235 try 236 { 237 if(fillBMP==null) 238 { 239 fillBMP=new Bitmap[8]; 240 for(int j=0;j<8;j++) 241 fillBMP[j]=null; 242 } 243 BitmapShader fillBMPshader=null; 244 int linetype=tg.get_LineType(); 245 int useIndex=-1; 246 switch(linetype) 247 { 248 case TacticalLines.WEIRS: 249 if(fillBMP[0]==null) 250 fillBMP[0] = BitmapFactory.decodeResource(context.getResources(), R.drawable.weirs); 251 useIndex=0; 252 break; 253 case TacticalLines.BEACH_SLOPE_MODERATE: 254 if(fillBMP[1]==null) 255 fillBMP[1] = BitmapFactory.decodeResource(context.getResources(), R.drawable.beach_slope_moderate); 256 useIndex=1; 257 break; 258 case TacticalLines.BEACH_SLOPE_STEEP: 259 if(fillBMP[2]==null) 260 fillBMP[2] = BitmapFactory.decodeResource(context.getResources(), R.drawable.beach_slope_steep); 261 useIndex=2; 262 break; 263 case TacticalLines.KELP: 264 if(fillBMP[3]==null) 265 fillBMP[3] = BitmapFactory.decodeResource(context.getResources(), R.drawable.kelp); 266 useIndex=3; 267 break; 268 case TacticalLines.OIL_RIG_FIELD: 269 if(fillBMP[4]==null) 270 fillBMP[4] = BitmapFactory.decodeResource(context.getResources(), R.drawable.oil_rig_field); 271 useIndex=4; 272 break; 273 case TacticalLines.BEACH: 274 if(fillBMP[5]==null) 275 fillBMP[5] = BitmapFactory.decodeResource(context.getResources(), R.drawable.beige_stipple); 276 useIndex=5; 277 break; 278 case TacticalLines.FOUL_GROUND: 279 if(fillBMP[6]==null) 280 fillBMP[6] = BitmapFactory.decodeResource(context.getResources(), R.drawable.foul_ground); 281 useIndex=6; 282 break; 283 case TacticalLines.SWEPT_AREA: 284 if(fillBMP[7]==null) 285 fillBMP[7] = BitmapFactory.decodeResource(context.getResources(), R.drawable.swept_area); 286 useIndex=7; 287 break; 288 default: //we do not use pattern fill for these 289 return false; 290 } 291 if(useIndex >= 0) 292 { 293 fillBMPshader = new BitmapShader(fillBMP[useIndex], Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 294 shape.setShader(fillBMPshader); 295 shape.setFillColor(Color.WHITE); 296 //fillBMP.recycle(); 297 } 298 } 299 catch(Exception exc) 300 { 301 ErrorLogger.LogException("clsUtility", "createBitmapShader", 302 new RendererException("Failed inside createBitmapShader", exc)); 303 304 } 305 return true; 306 }//*/ 307 308}