// ************************************************************* // * Font -- Version 1.3.0 // * by Deaod // ************************************************************* // * // * CREDITS: // * - Vexorian (JassHelper, ARGB, Table) // * - PitzerMike (JassNewGenPack, original TextSplat system) // * - MindWorX (JassNewGenPack) // * - Pipedream (Grimoire) // * - SFilip (TESH) // * // * HOW TO IMPORT: // * * C'n'P the code into your map // * * If you haven't done that already, import Table into your map // * // * HOW TO USE: // * // * * declare a variable of type font // * // * * use font.create(font Parent) to create a new font // * - Parent is the font thats accessed should a char not be available in this font // * // * * you can add a new symbol to the font by calling the method yourfont.addChar(string which, real width, string path). // * - which is the symbol you want to add to the font // * - width is the width of the symbol in pixels // * - path is the path to the image file thatll be used to display the symbol. // * PitzerMike attached a program for creating new fonts to his TextSplat system. I suggest you use it. // * The paths of the imported blps dont matter, but you should copy the width of the individual chars from the .j file that program creates. // * Refer to [url]http://www.wc3c.net/showthread.php?t=87798[/url] (--> Importing custom Fonts) for a guide on how to create custom fonts. // * // * * you can access the width of individual characters like this: CustomFont["C"].width. // * To access the path associated with the character use the path attribute. // * Example: CustomFont["C"].path // * "C" can be replaced with any character that has been previously added to the font using CustomFont.addChar() // * The double quote character can be used like this: \" (dont be scared by the broken highlighting of TESH, itll save just fine) // * The backslash character like this: \\ // * // * * you can add custom images to a font by calling the method .addImage(string which, real width, string path) // * Parameters work almost exactly like the ones of .addChar(), with the exception of which being case-insensitive // * and "slash-insensitive" (/ and \ being the same). // * Images are fully compatible with parents. // * // * * to access such an image you have to use CustomFont.getImage(string which) // * which being the same or an equivalent (slash/case-insensitivity!) of the which you passed to .addImage(). // * // * * Fonts are not meant to be destroyed. Just dont do it. // * // ************************************************************* library Font initializer Init requires Table globals private constant integer ASCII_CHAR_COUNT = 256 private constant integer COLLISION_DEPTH = 2 // how many individual chars collide at most endglobals globals private StringTable Collisions private StringTable Single private string array CollisionMapping private integer array CollisionResult endglobals private function ASCII2Int takes string char returns integer local integer id local integer i set char=SubString(char, 0, 1) if char == "" or char == null then // manually filter out 0 return 0 endif set id=Single[char] // see if the char is a non-colliding char if id>0 then // if it is, return id // return immediately else // if it isnt set id=Collisions[char] // get the ID of the collision set i=0 loop // and see which char of the two colliding ones it is exitwhen i>=COLLISION_DEPTH if CollisionMapping[id*COLLISION_DEPTH+i]==char then return CollisionResult[id*COLLISION_DEPTH+i] // found it! Return immediately, to shorten the algorithm endif set i=i+1 endloop endif debug call BJDebugMsg("TextSplat: Faulty Setup of Collisions for ASCII2Int.") return 0 // this line normally shouldnt be reached. If however, it is reached, you have a faulty Setup of the Collisions endfunction private struct fontchar string path real width static method create takes string path, real width returns thistype local thistype s=.allocate() set s.path=path set s.width=width return s endmethod endstruct private struct fontimage string path real width static method create takes string path, real width returns thistype local thistype s=.allocate() set s.path=path set s.width=width return s endmethod endstruct struct font private font parent=0 private fontchar array Symbol[ASCII_CHAR_COUNT] private StringTable Images method operator [] takes string ch returns fontchar local fontchar f=.Symbol[ASCII2Int(ch)] if f==0 then if .parent!=0 then return .parent[ch] debug else debug call BJDebugMsg("TextSplat: Char '"+ch+"' is not available in font "+I2S(this)+".") endif endif return f endmethod method addChar takes string which, real width, string path returns nothing local integer i=ASCII2Int(which) if i>0 then if .Symbol[i]==0 then set .Symbol[i]=fontchar.create(path, width) else set .Symbol[i].path=path set .Symbol[i].width=width endif debug else debug call BJDebugMsg("TextSplat: font.addChar: '"+which+"' could not be found in the CharMap!") endif endmethod method getImage takes string which returns fontimage local fontimage fi=fontimage(.Images[which]) if fi==0 then if .parent!=0 then return .parent.getImage(which) debug else debug call BJDebugMsg("TextSplat: Image '"+which+"' is not available in font "+I2S(this)+".") endif endif return fi endmethod method addImage takes string which, real width, string path returns nothing if .Images[which]>0 then set fontimage(.Images[which]).path=path set fontimage(.Images[which]).width=width else set .Images[which]=fontimage.create(path, width) endif endmethod static method create takes font Parent returns thistype local thistype s=.allocate() set s.parent=Parent set s.Images=StringTable.create() return s endmethod private method destroy takes nothing returns nothing endmethod endstruct // What im doing here is basically precalculating some things thatll lead to a speed gain in the ASCII2Int function private function Init takes nothing returns nothing set Collisions=StringTable.create() set Single=StringTable.create() // First, all chars that dont collide. // Note that they must be !=0 set Single["\b"]=8 set Single["\t"]=9 set Single["\n"]=10 set Single["\f"]=12 set Single["\r"]=13 set Single[" "]=32 set Single["!"]=33 set Single["\""]=34 set Single["#"]=35 set Single["$"]=36 set Single["%"]=37 set Single["&"]=38 set Single["'"]=39 set Single["("]=40 set Single[")"]=41 set Single["*"]=42 set Single["+"]=43 set Single[","]=44 set Single["-"]=45 set Single["."]=46 set Single["0"]=48 set Single["1"]=49 set Single["2"]=50 set Single["3"]=51 set Single["4"]=52 set Single["5"]=53 set Single["6"]=54 set Single["7"]=55 set Single["8"]=56 set Single["9"]=57 set Single[":"]=58 set Single[";"]=59 set Single["<"]=60 set Single["="]=61 set Single[">"]=62 set Single["?"]=63 set Single["@"]=64 set Single["["]=91 set Single["]"]=93 set Single["^"]=94 set Single["_"]=95 set Single["`"]=96 set Single["{"]=123 set Single["|"]=124 set Single["}"]=125 set Single["~"]=126 // ------------------- // This is the initialization of the arrays that will map from individual chars to integers later on set CollisionResult[(0*COLLISION_DEPTH)+0]=65 set CollisionResult[(1*COLLISION_DEPTH)+0]=66 set CollisionResult[(2*COLLISION_DEPTH)+0]=67 set CollisionResult[(3*COLLISION_DEPTH)+0]=68 set CollisionResult[(4*COLLISION_DEPTH)+0]=69 set CollisionResult[(5*COLLISION_DEPTH)+0]=70 set CollisionResult[(6*COLLISION_DEPTH)+0]=71 set CollisionResult[(7*COLLISION_DEPTH)+0]=72 set CollisionResult[(8*COLLISION_DEPTH)+0]=73 set CollisionResult[(9*COLLISION_DEPTH)+0]=74 set CollisionResult[(10*COLLISION_DEPTH)+0]=75 set CollisionResult[(11*COLLISION_DEPTH)+0]=76 set CollisionResult[(12*COLLISION_DEPTH)+0]=77 set CollisionResult[(13*COLLISION_DEPTH)+0]=78 set CollisionResult[(14*COLLISION_DEPTH)+0]=79 set CollisionResult[(15*COLLISION_DEPTH)+0]=80 set CollisionResult[(16*COLLISION_DEPTH)+0]=81 set CollisionResult[(17*COLLISION_DEPTH)+0]=82 set CollisionResult[(18*COLLISION_DEPTH)+0]=83 set CollisionResult[(19*COLLISION_DEPTH)+0]=84 set CollisionResult[(20*COLLISION_DEPTH)+0]=85 set CollisionResult[(21*COLLISION_DEPTH)+0]=86 set CollisionResult[(22*COLLISION_DEPTH)+0]=87 set CollisionResult[(23*COLLISION_DEPTH)+0]=88 set CollisionResult[(24*COLLISION_DEPTH)+0]=89 set CollisionResult[(25*COLLISION_DEPTH)+0]=90 set CollisionResult[(26*COLLISION_DEPTH)+0]=47 set CollisionResult[(0*COLLISION_DEPTH)+1]=97 set CollisionResult[(1*COLLISION_DEPTH)+1]=98 set CollisionResult[(2*COLLISION_DEPTH)+1]=99 set CollisionResult[(3*COLLISION_DEPTH)+1]=100 set CollisionResult[(4*COLLISION_DEPTH)+1]=101 set CollisionResult[(5*COLLISION_DEPTH)+1]=102 set CollisionResult[(6*COLLISION_DEPTH)+1]=103 set CollisionResult[(7*COLLISION_DEPTH)+1]=104 set CollisionResult[(8*COLLISION_DEPTH)+1]=105 set CollisionResult[(9*COLLISION_DEPTH)+1]=106 set CollisionResult[(10*COLLISION_DEPTH)+1]=107 set CollisionResult[(11*COLLISION_DEPTH)+1]=108 set CollisionResult[(12*COLLISION_DEPTH)+1]=109 set CollisionResult[(13*COLLISION_DEPTH)+1]=110 set CollisionResult[(14*COLLISION_DEPTH)+1]=111 set CollisionResult[(15*COLLISION_DEPTH)+1]=112 set CollisionResult[(16*COLLISION_DEPTH)+1]=113 set CollisionResult[(17*COLLISION_DEPTH)+1]=114 set CollisionResult[(18*COLLISION_DEPTH)+1]=115 set CollisionResult[(19*COLLISION_DEPTH)+1]=116 set CollisionResult[(20*COLLISION_DEPTH)+1]=117 set CollisionResult[(21*COLLISION_DEPTH)+1]=118 set CollisionResult[(22*COLLISION_DEPTH)+1]=119 set CollisionResult[(23*COLLISION_DEPTH)+1]=120 set CollisionResult[(24*COLLISION_DEPTH)+1]=121 set CollisionResult[(25*COLLISION_DEPTH)+1]=122 set CollisionResult[(26*COLLISION_DEPTH)+1]=92 // -------------------- // This maps the ID of the collision onto the colliding chars, which are stored in this virtual 2D array set CollisionMapping[ 0*(COLLISION_DEPTH)+0]="A" set CollisionMapping[ 1*(COLLISION_DEPTH)+0]="B" set CollisionMapping[ 2*(COLLISION_DEPTH)+0]="C" set CollisionMapping[ 3*(COLLISION_DEPTH)+0]="D" set CollisionMapping[ 4*(COLLISION_DEPTH)+0]="E" set CollisionMapping[ 5*(COLLISION_DEPTH)+0]="F" set CollisionMapping[ 6*(COLLISION_DEPTH)+0]="G" set CollisionMapping[ 7*(COLLISION_DEPTH)+0]="H" set CollisionMapping[ 8*(COLLISION_DEPTH)+0]="I" set CollisionMapping[ 9*(COLLISION_DEPTH)+0]="J" set CollisionMapping[10*(COLLISION_DEPTH)+0]="K" set CollisionMapping[11*(COLLISION_DEPTH)+0]="L" set CollisionMapping[12*(COLLISION_DEPTH)+0]="M" set CollisionMapping[13*(COLLISION_DEPTH)+0]="N" set CollisionMapping[14*(COLLISION_DEPTH)+0]="O" set CollisionMapping[15*(COLLISION_DEPTH)+0]="P" set CollisionMapping[16*(COLLISION_DEPTH)+0]="Q" set CollisionMapping[17*(COLLISION_DEPTH)+0]="R" set CollisionMapping[18*(COLLISION_DEPTH)+0]="S" set CollisionMapping[19*(COLLISION_DEPTH)+0]="T" set CollisionMapping[20*(COLLISION_DEPTH)+0]="U" set CollisionMapping[21*(COLLISION_DEPTH)+0]="V" set CollisionMapping[22*(COLLISION_DEPTH)+0]="W" set CollisionMapping[23*(COLLISION_DEPTH)+0]="X" set CollisionMapping[24*(COLLISION_DEPTH)+0]="Y" set CollisionMapping[25*(COLLISION_DEPTH)+0]="Z" set CollisionMapping[26*(COLLISION_DEPTH)+0]="/" set CollisionMapping[ 0*(COLLISION_DEPTH)+1]="a" set CollisionMapping[ 1*(COLLISION_DEPTH)+1]="b" set CollisionMapping[ 2*(COLLISION_DEPTH)+1]="c" set CollisionMapping[ 3*(COLLISION_DEPTH)+1]="d" set CollisionMapping[ 4*(COLLISION_DEPTH)+1]="e" set CollisionMapping[ 5*(COLLISION_DEPTH)+1]="f" set CollisionMapping[ 6*(COLLISION_DEPTH)+1]="g" set CollisionMapping[ 7*(COLLISION_DEPTH)+1]="h" set CollisionMapping[ 8*(COLLISION_DEPTH)+1]="i" set CollisionMapping[ 9*(COLLISION_DEPTH)+1]="j" set CollisionMapping[10*(COLLISION_DEPTH)+1]="k" set CollisionMapping[11*(COLLISION_DEPTH)+1]="l" set CollisionMapping[12*(COLLISION_DEPTH)+1]="m" set CollisionMapping[13*(COLLISION_DEPTH)+1]="n" set CollisionMapping[14*(COLLISION_DEPTH)+1]="o" set CollisionMapping[15*(COLLISION_DEPTH)+1]="p" set CollisionMapping[16*(COLLISION_DEPTH)+1]="q" set CollisionMapping[17*(COLLISION_DEPTH)+1]="r" set CollisionMapping[18*(COLLISION_DEPTH)+1]="s" set CollisionMapping[19*(COLLISION_DEPTH)+1]="t" set CollisionMapping[20*(COLLISION_DEPTH)+1]="u" set CollisionMapping[21*(COLLISION_DEPTH)+1]="v" set CollisionMapping[22*(COLLISION_DEPTH)+1]="w" set CollisionMapping[23*(COLLISION_DEPTH)+1]="x" set CollisionMapping[24*(COLLISION_DEPTH)+1]="y" set CollisionMapping[25*(COLLISION_DEPTH)+1]="z" set CollisionMapping[26*(COLLISION_DEPTH)+1]="\\" // -------------------- // These are all the chars that collide // Note that i have left out their counterparts (with which they would collide) set Collisions["A"]= 0 set Collisions["B"]= 1 set Collisions["C"]= 2 set Collisions["D"]= 3 set Collisions["E"]= 4 set Collisions["F"]= 5 set Collisions["G"]= 6 set Collisions["H"]= 7 set Collisions["I"]= 8 set Collisions["J"]= 9 set Collisions["K"]=10 set Collisions["L"]=11 set Collisions["M"]=12 set Collisions["N"]=13 set Collisions["O"]=14 set Collisions["P"]=15 set Collisions["Q"]=16 set Collisions["R"]=17 set Collisions["S"]=18 set Collisions["T"]=19 set Collisions["U"]=20 set Collisions["V"]=21 set Collisions["W"]=22 set Collisions["X"]=23 set Collisions["Y"]=24 set Collisions["Z"]=25 set Collisions["/"]=26 set Collisions["\\"]=26 endfunction endlibrary