// // Latex Project Public Licence (lppl1.3) applies // Originally written by Kwanleung Tse // First Release : 1st July, 2014 // Last Update : 27th September, 2014 // // package worker4math.hktex2; import java.util.ArrayList; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.util.SparseIntArray; public class Parseblock { private ArrayList blockfractionlevel = new ArrayList(); private ArrayList blocklevel = new ArrayList(); private ArrayList blockenclosurelevel = new ArrayList(); private ArrayList blocksuperscriptlevel = new ArrayList(); private ArrayList blocksubscriptlevel = new ArrayList(); private ArrayList blocktabularlevel = new ArrayList(); private ArrayList blockwidth = new ArrayList(); private ArrayList blockheight = new ArrayList(); private ArrayList blockdepth = new ArrayList(); private ArrayList> subblock = new ArrayList>(); private ArrayList> subblockwidth = new ArrayList>(); private ArrayList> subblockheight = new ArrayList>(); private ArrayList> subblockdepth = new ArrayList>(); private ArrayList> subblockxpos = new ArrayList>(); private ArrayList> subblockypos = new ArrayList>(); private ArrayList> subblockattribute = new ArrayList>(); public void parseblock(int tid, Canvas canvas, Block block, String molecule, ArrayList tf , String defaultattribute){ SparseIntArray subblocknumber = new SparseIntArray(); subblocknumber.put(tid, -1); char charExclam = '!'; String stringfra = "fra"; String stringcnb = "cnb"; String stringodb = "odb"; String stringcdb = "cdb"; String stringosp = "osp"; String stringcsp = "csp"; String stringosu = "osu"; String stringcsu = "csu"; String stringobx = "obx"; String stringcbx = "cbx"; String stringbta = "bta"; String stringeta = "eta"; String stringbln = "bln"; String stringeln = "eln"; String stringolb = "olb"; String stringclb = "clb"; String stringhline = "!hlin "; String stringdnot = "!dno "; String key=""; String key2=""; String parentkey=""; String sfontsize=""; String thisattribute; String attribute2; String columnspec=""; boolean showcloseenclosure = true; boolean containfraction = false; boolean containenclosure = false; int i,j = 0; int ii=0; int iii=0; int i3=0; int j3=0; int index=0; int index2=0; int blocknumber = 0; int currentblock=0; int previousblock=0; int parentblock = 0; int fontsize = Integer.parseInt(defaultattribute.substring(1,4)); int thisfontsize = fontsize; int fontinteger = Integer.parseInt(defaultattribute.substring(4,7)); int thisblocklevel = 0; int thisfractionlevel = 0; int thisenclosurelevel = -1; int thissuperscriptlevel = -1; int thissubscriptlevel = -1; int thistabularlevel = -1; int fractionnumber = -1; int currentfraction = -1; int previousfraction = -1; int numeratornumber = -1; int currentnumerator = -1; int denominatornumber = -1; int currentdenominator = -1; int previousdenominator = -1; int enclosurenumber = -1; int currentenclosure = -1; int previousenclosure = -1; int tabularnumber = -1; int currenttabular = -1; int previoustabular = -1; int tabularlinenumber = -1; int currenttabularline = -1; int previoustabularline = -1; int tabularlineblocknumber = -1; int currenttabularlineblock = -1; int superscriptnumber = -1; int currentsuperscript = -1; int subscriptnumber = -1; int currentsubscript = -1; int previoussubscript = -1; int previoussuperscript = -1; int numcolumn=0; int column = 0; float ypos = 0.0f; float xpos = 0.0f; float halfheight=0.0f; float maxtop=0.0f; float gap=Header.characterheadroom; float columngap=Header.columngap; float strokewidth=0.0f; float width1 = 0.0f; float width2 = 0.0f; float width3 = 0.0f; float maxwidth = 0.0f; float maxwidth1=0.0f; float maxcolumnwidth=0.0f; float totalcolumnwidth=0.0f; float tempx=0.0f; float tempy=0.0f; float twidth=0.0f; float twidth2=0.0f; float case6xmargin=0.0f; float case7xmargin=0.0f; float theight=0.0f; float tdepth=0.0f; float totaltabularheight=0.0f; float totaltabulardepth=0.0f; float spacewidth=0.0f; float spaceheight=0.0f; float spacedepth=0.0f; ArrayList showopenenclosure = new ArrayList(); ArrayList aftersuperscript = new ArrayList(); ArrayList aftersubscript = new ArrayList(); ArrayList numeratorwidth = new ArrayList(); ArrayList numeratorheight = new ArrayList(); ArrayList numeratordepth = new ArrayList(); ArrayList denominatorwidth = new ArrayList(); ArrayList denominatorheight = new ArrayList(); ArrayList denominatordepth = new ArrayList(); ArrayList fractionwidth = new ArrayList(); ArrayList fractionheight = new ArrayList(); ArrayList fractiondepth = new ArrayList(); ArrayList columnwidth = new ArrayList(); ArrayList openblock = new ArrayList(); ArrayList closeblock = new ArrayList(); ArrayList subparentblock = new ArrayList(); ArrayList supparentblock = new ArrayList(); ArrayList linenu = new ArrayList(); ArrayList openfraction = new ArrayList(); ArrayList closefraction = new ArrayList(); ArrayList opennumerator = new ArrayList(); ArrayList closenumerator = new ArrayList(); ArrayList opendenominator = new ArrayList(); ArrayList closedenominator = new ArrayList(); ArrayList homeblock = new ArrayList(); ArrayList numeratorindex = new ArrayList(); ArrayList denominatorindex = new ArrayList(); ArrayList opensubscript = new ArrayList(); ArrayList closesubscript = new ArrayList(); ArrayList opensuperscript = new ArrayList(); ArrayList closesuperscript = new ArrayList(); ArrayList openenclosure = new ArrayList(); ArrayList closeenclosure = new ArrayList(); ArrayList opentabular = new ArrayList(); ArrayList closetabular = new ArrayList(); ArrayList opentabularline = new ArrayList(); ArrayList closetabularline = new ArrayList(); ArrayList opentabularlineblock = new ArrayList(); ArrayList closetabularlineblock = new ArrayList(); ArrayList supparentkey = new ArrayList(); ArrayList subparentkey = new ArrayList(); double[] fractionfontfactor = {1.0,0.75,0.5}; Fontfile font = new Fontfile(); font.fontfile(); Colorfile color = new Colorfile(); color.colorfile(); Paint textpaint = new Paint(); Rect textbounds = new Rect(); textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(fontinteger)); textpaint.getTextBounds("Aj",0,"Aj".length(),textbounds); spacewidth=textpaint.measureText(" "); spaceheight=textbounds.height(); spacedepth=textbounds.bottom; Paint textpaint5 = new Paint(); Rect textbounds5 = new Rect(); textpaint5.setTextSize(thisfontsize); textpaint5.setTypeface(tf.get(5)); Paint symbolpaint = new Paint(); Rect symbolbounds = new Rect(); symbolpaint.setTextSize(thisfontsize); symbolpaint.setTypeface(tf.get(4)); thisattribute=defaultattribute; attribute2=defaultattribute; sfontsize=Integer.toString(thisfontsize); int ij=sfontsize.length(); if (ij==1){ thisattribute=thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4); } else if (ij==2){ thisattribute=thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4); } else if (ij==3){ thisattribute=thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4); } molecule=molecule.trim(); molecule = molecule + charExclam + charExclam + charExclam + charExclam + charExclam; j=0; char temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} create(tid,blocknumber, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1);add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,0.0f,0.0f,thisattribute); openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); for (i=0;!((molecule.charAt(j) == charExclam) && (molecule.charAt(j+1)==charExclam)) ; i++) { if (temp == charExclam && key.equals("openblock")) { previousblock=currentblock; blocknumber++; currentblock= blocknumber; thisblocklevel++; create(tid,currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); j+=11; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals("closeblock")) { closeblock.set(currentblock, subblocknumber.get(tid)); previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } insert(tid,previousblock, currentblock,blockwidth.get(previousblock), blockheight.get(previousblock),blockdepth.get(previousblock) ); thisblocklevel--; j+=12; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals(stringfra)) { // open fraction, open numerator thisfractionlevel++; fractionnumber++; currentfraction=fractionnumber; previousblock=currentblock; blocknumber++; currentblock= blocknumber; thisblocklevel++; create(tid, currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); openfraction.add(subblocknumber.get(tid)); closefraction.add(-1); if (thissubscriptlevel ==-1 && thissuperscriptlevel ==-1){ if (thisfractionlevel<=2){ thisfontsize=(int)((double)fontsize*fractionfontfactor[thisfractionlevel]); }else { thisfontsize=(int)((double)fontsize*fractionfontfactor[2]); }; if (thisfontsize<8){thisfontsize=8;}; }; numeratornumber++; currentnumerator=numeratornumber; previousblock=currentblock; blocknumber++; currentblock= blocknumber; thisblocklevel++; create(tid,currentblock, thisblocklevel, thisfractionlevel,thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); numeratorindex.add(currentblock); numeratorwidth.add(0.0f); numeratorheight.add(0.0f);numeratordepth.add(0.0f); denominatorindex.add(-1); denominatorwidth.add(0.0f); denominatorheight.add(0.0f);denominatordepth.add(0.0f); fractionwidth.add(0.0f); fractionheight.add(0.0f); fractiondepth.add(0.0f); opennumerator.add(subblocknumber.get(tid)); closenumerator.add(-1); opendenominator.add(-1); closedenominator.add(-1); linenu.add(currentblock); j+=9; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals(stringcnb) ) { // close numerator numeratorwidth.set(currentnumerator,blockwidth.get(currentblock)); numeratorheight.set(currentnumerator,blockheight.get(currentblock)); numeratordepth.set(currentnumerator,blockdepth.get(currentblock)); closenumerator.set(currentnumerator, subblocknumber.get(tid)); closeblock.set(currentblock, subblocknumber.get(tid)); containfraction = false; containenclosure=false; for (i=currentblock+1;i<=blocknumber && !containfraction && !containenclosure;i++){ if (blockenclosurelevel.get(i)==thisenclosurelevel && blocksuperscriptlevel.get(i)==thissuperscriptlevel && blocksubscriptlevel.get(i)==thissubscriptlevel && blockfractionlevel.get(i)==thisfractionlevel+1 && openblock.get(i)> openblock.get(currentblock) && closeblock.get(i) <= closeblock.get(currentblock)){ containfraction=true; } else if (blockenclosurelevel.get(i)==thisenclosurelevel+1 && blocklevel.get(i)==thisblocklevel+1 && openblock.get(i)>openblock.get(currentblock) && closeblock.get(i)<=closeblock.get(currentblock)){ containenclosure=true; } } textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(0)); textpaint.getTextBounds("1",0,"1".length(),textbounds); Float off=(float) textbounds.height()/2; if (containfraction){ adjustfraction(tid,currentblock, blocknumber, homeblock,openblock,closeblock,thisfractionlevel, thisblocklevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, off, gap); } strokewidth=(float)thisfontsize/10; if (strokewidth < 1){strokewidth=1;}; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringhline,0.0f,strokewidth,strokewidth,subblockxpos.get(currentblock).get(0),ypos+gap+blockdepth.get(currentblock),thisattribute); closenumerator.set(currentnumerator, subblocknumber.get(tid)); closeblock.set(currentblock, subblocknumber.get(tid));homeblock.add(currentblock); thisblocklevel--; for (i=subblocknumber.get(tid);currentnumerator >=0 && closenumerator.get(currentnumerator)>=0;i--){ currentnumerator--; } previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } parentkey=""; j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals(stringcdb)) { // close denominator //denominator block subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); closedenominator.set(currentdenominator, subblocknumber.get(tid)); closeblock.set(currentblock, subblocknumber.get(tid)); denominatorwidth.set(currentdenominator,blockwidth.get(currentblock)); denominatorheight.set(currentdenominator,blockheight.get(currentblock)); denominatordepth.set(currentdenominator,blockdepth.get(currentblock)); fractionwidth.set(currentfraction, Math.max(numeratorwidth.get(currentfraction),denominatorwidth.get(currentdenominator))); fractionheight.set(currentfraction, numeratorheight.get(currentfraction) + denominatorheight.get(currentdenominator) + gap*2); fractiondepth.set(currentfraction, denominatorheight.get(currentdenominator) + gap); index=numeratorindex.get(currentfraction); int l=subblockwidth.get(index).size(); subblockwidth.get(index).set(l-1,fractionwidth.get(currentfraction)); tempy=fractionwidth.get(currentfraction); sfontsize=Integer.toString((int)tempy); ij=sfontsize.length(); index=numeratorindex.get(currentfraction); if (ij==1){ subblockattribute.get(index).set(l-1,thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4)); } else if (ij==2){ subblockattribute.get(index).set(l-1,thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4)); } else if (ij==3){ subblockattribute.get(index).set(l-1,thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4)); } containfraction = false; containenclosure=false; for (i=currentblock+1;i<=blocknumber && !containfraction && !containenclosure;i++){ if (blockenclosurelevel.get(i)==thisenclosurelevel && blocksuperscriptlevel.get(i)==thissuperscriptlevel && blocksubscriptlevel.get(i)==thissubscriptlevel && blockfractionlevel.get(i)==thisfractionlevel+1 && openblock.get(i)> openblock.get(currentblock) && closeblock.get(i) <= closeblock.get(currentblock)){ containfraction=true; } else if (blockenclosurelevel.get(i)==thisenclosurelevel+1 && blocklevel.get(i)==thisblocklevel+1 && openblock.get(i)>openblock.get(currentblock) && closeblock.get(i)<=closeblock.get(currentblock)){ containenclosure=true; } } textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(0)); textpaint.getTextBounds("1",0,"1".length(),textbounds); Float off=(float) textbounds.height()/2; if (containfraction){adjustfraction(tid,currentblock, blocknumber, homeblock,openblock,closeblock,thisfractionlevel, thisblocklevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, off, gap);} thisblocklevel--; // adjust horizontal position of numerator and denominator if (numeratorwidth.get(currentfraction) > denominatorwidth.get(currentdenominator)){ tempx = (numeratorwidth.get(currentfraction) - denominatorwidth.get(currentdenominator))/2; index=currentblock; for (i=0;i<=subblock.get(index).size()-1;i++){subblockxpos.get(index).set(i, subblockxpos.get(index).get(i) + tempx);}; } else if (numeratorwidth.get(currentfraction) < denominatorwidth.get(currentdenominator)){ tempx = (denominatorwidth.get(currentdenominator) - numeratorwidth.get(currentfraction))/2; index=numeratorindex.get(currentfraction); blockwidth.set(numeratorindex.get(currentfraction),numeratorwidth.get(currentfraction)); for (i=0;i<=subblock.get(index).size()-2;i++){subblockxpos.get(index).set(i, subblockxpos.get(index).get(i) + tempx);}; } // adjust vertical position of denominator index=numeratorindex.get(currentfraction); index2=currentblock; tempy=subblockypos.get(index).get(subblock.get(index).size()-1)-subblockypos.get(index).get(0); for (ii=0;ii<=subblock.get(index2).size()-1;ii++){ subblockypos.get(index2).set(ii,subblockypos.get(index2).get(ii)+tempy+gap+blockheight.get(currentblock)-blockdepth.get(currentblock)); } index=0; previousdenominator=currentdenominator; halfheight=(float) 0; for (i=subblocknumber.get(tid);currentdenominator >=0 && closedenominator.get(currentdenominator)>=0;i--){ currentdenominator--; } previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (thisfractionlevel == 1){ textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(0)); textpaint.getTextBounds("a",0,"a".length(),textbounds); halfheight=textbounds.height()*5/8; index=numeratorindex.get(currentfraction); tempy=subblockypos.get(index).get(subblock.get(index).size()-1)-subblockypos.get(index).get(0); for (i=1;i<=subblock.get(index).size()-1;i++){ subblockypos.get(index).set(i, subblockypos.get(index).get(i)-tempy-halfheight); } ypos=subblockypos.get(index).get(0); xpos=subblockxpos.get(index).get(subblock.get(index).size()-1)+fractionwidth.get(currentfraction); index=previousblock; for (i=1;i<=subblock.get(index).size()-2;i++){ subblockypos.get(index).set(i, subblockypos.get(index).get(i)-tempy-halfheight); } fractiondepth.set(currentfraction,fractiondepth.get(currentfraction)-halfheight); } else if (thisfractionlevel >= 2){ // adjust position after fraction textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(0)); textpaint.getTextBounds("a",0,"a".length(),textbounds); halfheight=textbounds.height()*5/8; index=numeratorindex.get(currentfraction); iii=subblock.get(index).size()-1; tempy=subblockypos.get(index).get(0); blockdepth.set(currentblock,blockdepth.get(currentblock)-tempy+ypos); ypos=tempy; xpos=subblockxpos.get(index).get(iii)+subblockwidth.get(index).get(iii); } index = numeratorindex.get(currentfraction); insert(tid,index, currentblock,0.0f,0.0f,0.0f); insert(tid,previousblock, currentblock,0.0f,0.0f,0.0f); blockwidth.set(index, numeratorwidth.get(currentfraction)); maxtop=Math.max(blockheight.get(currentblock)-blockdepth.get(currentblock), blockheight.get(index)-blockdepth.get(index)); blockdepth.set(currentblock, Math.max(blockdepth.get(currentblock),blockdepth.get(index))); blockheight.set(currentblock, maxtop+blockdepth.get(currentblock)); blockwidth.set(previousblock, denominatorwidth.get(currentfraction)); maxtop=Math.max(blockheight.get(currentblock)-blockdepth.get(currentblock), blockheight.get(previousblock)-blockdepth.get(previousblock)); blockdepth.set(currentblock, Math.max(blockdepth.get(currentblock),blockdepth.get(previousblock))); blockheight.set(currentblock, maxtop+blockdepth.get(currentblock)); //fraction block subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); closefraction.set(currentfraction, subblocknumber.get(tid)); closeblock.set(currentblock, subblocknumber.get(tid)); thisblocklevel--; thisfractionlevel--; if (thissubscriptlevel >= 0 || thissuperscriptlevel >= 0){ thisfontsize=fontsize/3; }else if (thisfractionlevel<=2){ thisfontsize=(int)((double)fontsize*fractionfontfactor[thisfractionlevel]); }else { thisfontsize=(int)((double)fontsize*fractionfontfactor[2]); }; if (thisfontsize<8){thisfontsize=8;}; previousfraction=currentfraction; for (i=subblocknumber.get(tid);currentfraction >=0 && closefraction.get(currentfraction)>=0;i--){ currentfraction--; } previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } blockwidth.set(previousblock, fractionwidth.get(previousfraction)); blockheight.set(previousblock, fractionheight.get(previousfraction)); if (thisfractionlevel==0) {blockdepth.set(previousblock,denominatorheight.get(previousdenominator)+gap-halfheight);} else {blockdepth.set(previousblock, numeratordepth.get(previousfraction)+denominatorheight.get(previousdenominator)+gap*2);}; twidth=fractionwidth.get(previousfraction); theight=fractionheight.get(previousfraction); tdepth=blockdepth.get(previousblock); insert(tid,previousblock, currentblock,twidth, theight, tdepth); parentkey=""; j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals(stringodb)) { // open denominator denominatornumber++; currentdenominator=denominatornumber; previousblock=currentblock; blocknumber++; currentblock=blocknumber; thisblocklevel++; index = numeratorindex.get(currentfraction); ypos=subblockypos.get(index).get(0); xpos=subblockxpos.get(index).get(subblock.get(index).size()-1); create(tid,currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); denominatorindex.set(currentdenominator,currentblock); j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} opendenominator.set(currentdenominator, subblocknumber.get(tid)); } else if (temp == charExclam && key.equals(stringbta)) { // begin tabular thistabularlevel=0; tabularnumber=0; currenttabular=tabularnumber; opentabularline.clear();closetabularline.clear();opentabular.clear();closetabular.clear();opentabularlineblock.clear();closetabularlineblock.clear(); if (thisfractionlevel>0){ synchronized(this){ Block.error.put(tid, true); Block.errormessage.put(tid, "Fraction cannot have tabular, parse failed!");} return; } if (thistabularlevel>0){ synchronized(this){ Block.error.put(tid, true); Block.errormessage.put(tid, "Tabular cannot have tabular, parse failed!");} return; } blocknumber++; currentblock= blocknumber; thisblocklevel++; create(tid,currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); opentabular.add(subblocknumber.get(tid)); closetabular.add(-1); tabularlinenumber=-1; j+=5; int i4=molecule.indexOf("{",j); numcolumn=0; for (i=j;i<=i4-2;i++){ if (molecule.charAt(i)=='l' || molecule.charAt(i)=='c' || molecule.charAt(i)=='r'){ numcolumn++; } } columnspec=molecule.substring(j,i4-1); totalcolumnwidth=0; columnwidth.clear(); opentabularlineblock.clear(); j=i4+1; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals(stringeta)) { // end tabular thistabularlevel--; closetabular.set(currenttabular, subblocknumber.get(tid));closeblock.set(currentblock, subblocknumber.get(tid)); blockwidth.set(currentblock, totalcolumnwidth); twidth=0;totalcolumnwidth=0; for (i=0;i<=numcolumn-1;i++){ totalcolumnwidth=totalcolumnwidth+columnwidth.get(i)+columngap; } totalcolumnwidth=totalcolumnwidth-columngap; index2=currentblock; blockwidth.set(currentblock, totalcolumnwidth); xpos=subblockxpos.get(index2).get(0)+blockwidth.get(currentblock); for (iii=0;iii<=currenttabularline;iii++){ twidth=0; for (i=0;i<=numcolumn-1;i++){ for (ii=1;ii<=subblock.get(homeblock.get(opentabularlineblock.get(iii*numcolumn+i))).size()-1;ii++){ index= opentabularlineblock.get(iii*numcolumn+i)-openblock.get(currentblock)+ii; if (columnspec.charAt(i)=='l'){subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(index)+twidth);} else if (columnspec.charAt(i)=='c'){twidth2=(columnwidth.get(i)-blockwidth.get(homeblock.get(opentabularlineblock.get(iii*numcolumn+i))))/2; subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(index)+twidth+twidth2);} else if (columnspec.charAt(i)=='r'){twidth2=columnwidth.get(i)-blockwidth.get(homeblock.get(opentabularlineblock.get(iii*numcolumn+i))); subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(index)+twidth+twidth2);}; } twidth=twidth+columnwidth.get(i)+columngap; }} previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } previoustabular=currenttabular; for (i=subblocknumber.get(tid);currenttabular >=0 && closeblock.get(currenttabular)>=0;i--){ currenttabular--; } if (tabularlinenumber>0) { textpaint.setTextSize(thisfontsize); textpaint.getTextBounds("a",0,"a".length(),textbounds); tempy=blockdepth.get(previousblock)-blockheight.get(previousblock)/2+textbounds.height()/2; for (i=opentabularlineblock.get(0)-opentabular.get(previoustabular);i<=closetabularlineblock.get(currenttabularlineblock)-opentabular.get(previoustabular);i++){ subblockypos.get(previousblock).set(i, subblockypos.get(previousblock).get(i)-tempy); } blockdepth.set(previousblock,blockdepth.get(previousblock)-tempy);} insert(tid,previousblock, currentblock, blockwidth.get(previousblock), blockheight.get(previousblock),blockdepth.get(previousblock)); j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals(stringbln)) { // begin tabular line tabularlinenumber++; previoustabularline=currenttabularline; currenttabularline=tabularlinenumber; blocknumber++; previousblock=currentblock; currentblock= blocknumber; thisblocklevel++; if (currenttabularline >=1){xpos=subblockxpos.get(homeblock.get(opentabularline.get(previoustabularline))).get(0);}; create(tid,currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); opentabularline.add(subblocknumber.get(tid)); closetabularline.add(-1); tabularlineblocknumber=-1; column=-1; maxcolumnwidth=0; j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals(stringeln)) { // end tabular line closetabularline.set(currenttabularline, subblocknumber.get(tid));closeblock.set(currentblock, subblocknumber.get(tid)); float gap2=gap*thisfontsize/fontsize; index2=currentblock; if (currenttabularline > 0){ tempy=totaltabulardepth+blockheight.get(currentblock)-blockdepth.get(currentblock)+gap2; for (i=1;i<=subblock.get(currentblock).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)+tempy); } } previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (currenttabularline >=1) { totaltabularheight=totaltabularheight+blockheight.get(previousblock)+gap2; totaltabulardepth=totaltabulardepth+blockheight.get(previousblock)+gap2; insert(tid,previousblock, currentblock, 0.0f, totaltabularheight, totaltabulardepth); } else { insert(tid,previousblock, currentblock, blockwidth.get(previousblock),blockheight.get(previousblock) , blockdepth.get(previousblock)); totaltabularheight=blockheight.get(previousblock); totaltabulardepth=blockdepth.get(previousblock); } j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals(stringolb)) { // begin tabular line block tabularlineblocknumber++; currenttabularlineblock=tabularlineblocknumber; column++;columnwidth.add(0.0f); blocknumber++; previousblock=currentblock; currentblock= blocknumber; thisblocklevel++; textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(fontinteger)); textpaint.getTextBounds("Aj",0,"Aj".length(),textbounds); spacewidth=textpaint.measureText(" "); spaceheight=textbounds.height(); spacedepth=textbounds.bottom; create(tid,currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,spacewidth,spaceheight,spacedepth,xpos,ypos,thisattribute); openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); opentabularlineblock.add(subblocknumber.get(tid)); closetabularlineblock.add(-1); xpos=subblockxpos.get(homeblock.get(opentabularline.get(0))).get(0); j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals(stringclb)) { // end tabular line block closetabularlineblock.set(currenttabularlineblock, subblocknumber.get(tid));closeblock.set(currentblock, subblocknumber.get(tid)); maxcolumnwidth = Math.max(columnwidth.get(column),blockwidth.get(currentblock)); columnwidth.set(column, maxcolumnwidth); previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } insert(tid,previousblock, currentblock, blockwidth.get(previousblock),blockheight.get(previousblock) , blockdepth.get(previousblock)); j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals("blank")) { sfontsize=Integer.toString(thisfontsize); ij=sfontsize.length(); if (ij==1){ thisattribute=thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4); } else if (ij==2){ thisattribute=thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4); } else if (ij==3){ thisattribute=thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4); } textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(fontinteger)); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock," ",(float)textpaint.measureText(" "),0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); xpos=xpos+textbounds.width(); j+=7; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals("dno")) { // do nothing subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals(stringobx)) { // open mbox thisattribute=thisattribute.substring(0,4)+"000"+thisattribute.substring(7); j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals(stringcbx)) { // close mbox thisattribute=thisattribute.substring(0,4)+defaultattribute.substring(4,7)+thisattribute.substring(7); j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.charAt(0) == 'A') { //Begin attribute if (key.charAt(1) == 'o'){ String attribute; int jj=key.indexOf("("); if (jj >2){ attribute = key.substring(2,jj); } else { attribute = key.substring(2); } if (attribute.equals("underlinetext")){ thisattribute="0"+thisattribute.substring(1,18)+"1"+thisattribute.substring(19); } else if (attribute.equals("strikethru")){ thisattribute="0"+thisattribute.substring(1,19)+'1'+thisattribute.substring(20); } else if (attribute.equals("skew")){ if (molecule.charAt(j+attribute.length()+3)=='(' ){ jj = molecule.indexOf(')',j+attribute.length()+3); thisattribute="0"+thisattribute.substring(1,20)+molecule.substring(j+attribute.length()+4,jj)+thisattribute.substring(25);; j=jj-key.length(); } else { thisattribute="0"+thisattribute.substring(1,20)+"-0.25"+thisattribute.substring(25); }; }else if (attribute.equals("alpha")){ // alpha does not work synchronized(this){ Block.error.put(tid, true); Block.errormessage.put(tid, "Alpha does not work, parse failed!");} return; }else if (attribute.equals("shadow")){ if (molecule.charAt(j+attribute.length()+3)=='(' ){ jj = molecule.indexOf(')',j+attribute.length()+3); thisattribute="0"+thisattribute.substring(1,29)+molecule.substring(j+attribute.length()+4,jj); j=jj-key.length(); } else { thisattribute="0"+thisattribute.substring(1,29)+"222black";} }; j=j+key.length()+2; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (key.charAt(1) == 'c'){ String attribute; attribute = key.substring(2); if (attribute.equals("underlinetext")){ thisattribute=thisattribute.substring(0,18)+"0"+thisattribute.substring(19); } else if (attribute.equals("strikethru")){ thisattribute=thisattribute.substring(0,19)+"0"+thisattribute.substring(20); } else if (attribute.equals("skew")){ thisattribute=thisattribute.substring(0,20)+"+0.00"+thisattribute.substring(25); }else if (attribute.equals("alpha")){ // thisattribute=thisattribute.substring(0,25)+"0xFF"+thisattribute.substring(29); //alpha not working !! }else if (attribute.equals("shadow")){ thisattribute=thisattribute.substring(0,29)+"0000xFF000000"; }; if (thisattribute.substring(1).equals(defaultattribute.substring(1))){ thisattribute='1'+thisattribute.substring(1);}; j=j+key.length()+2; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } } else if (temp == charExclam && key.charAt(0) == 'F') { //Begin font String fontname = key.substring(2); if (key.charAt(1) == 'o'){ fontinteger = font.fontname.indexOf(fontname); if (Integer.toString(fontinteger).length()==1){ thisattribute=thisattribute.substring(0,4)+"00"+Integer.toString(fontinteger)+thisattribute.substring(7); } else if (Integer.toString(fontinteger).length()==2){ thisattribute=thisattribute.substring(0,4)+"0"+Integer.toString(fontinteger)+thisattribute.substring(7); } else if (Integer.toString(fontinteger).length()==3){ thisattribute=thisattribute.substring(0,4)+Integer.toString(fontinteger)+thisattribute.substring(7); } j=j+key.length()+2; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (key.charAt(1) == 'c'){ fontinteger = Integer.parseInt(defaultattribute.substring(4,7)); if (Integer.toString(fontinteger).length()==1){ thisattribute=thisattribute.substring(0,4)+"00"+Integer.toString(fontinteger)+thisattribute.substring(7); } else if (Integer.toString(fontinteger).length()==2){ thisattribute=thisattribute.substring(0,4)+"0"+Integer.toString(fontinteger)+thisattribute.substring(7); } else if (Integer.toString(fontinteger).length()==3){ thisattribute=thisattribute.substring(0,4)+Integer.toString(fontinteger)+thisattribute.substring(7); } j=j+key.length()+2; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } } else if (temp == charExclam && key.charAt(0) == 'X') { // Begin size String sizename = key.substring(2); if (key.charAt(1) == 'o'){ thisfontsize= (int)((float)fontsize*Header.sizefactor.get(sizename)); j=j+key.length()+2; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (key.charAt(1) == 'c'){ thisfontsize= fontsize; j=j+key.length()+2; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } } else if (temp == charExclam && key.charAt(0) == 'C') { // Begin color String colorname = key.substring(2); if (key.charAt(1) == 'o'){ thisattribute=thisattribute.substring(0,7)+color.colorinteger.get(colorname)+thisattribute.substring(17); j=j+key.length()+2; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } else if (key.charAt(1) == 'c'){ thisattribute=thisattribute.substring(0,7)+defaultattribute.substring(7,17)+thisattribute.substring(17); j=j+key.length()+2; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!'||molecule.charAt(ii)==')' || molecule.charAt(ii)=='(');ii++){ key = key + molecule.charAt(ii); }} } }else if (temp == charExclam && key.charAt(0) == 'V') { // open enclosure key = key.substring(1); if (Symbol.symboltype.containsKey(key) && (Symbol.symboltype.get(key) == 1 || Symbol.symboltype.get(key) == 2 ||Symbol.symboltype.get(key) == 3 || Symbol.symboltype.get(key) == 5 || Symbol.symboltype.get(key) == 6 || Symbol.symboltype.get(key) == 7 || Symbol.symboltype.get(key) == 8 || Symbol.symboltype.get(key) == 9)) { // open enclosure ii=j+key.length()+2; temp=molecule.charAt(ii); if (temp=='{'){ enclosurenumber++; currentenclosure=enclosurenumber; thisenclosurelevel++; previousblock=currentblock; blocknumber++; currentblock= blocknumber; thisblocklevel++; synchronized(this){ create(tid,currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); } openblock.add(subblocknumber.get(tid)); closeblock.add(-1);homeblock.add(currentblock); openenclosure.add(subblocknumber.get(tid)); closeenclosure.add(-1); showopenenclosure.add(true); index2=+currentblock; switch(Symbol.symboltype.get(key)){ case 1: case 3: j3=j+key.length()+3; if ( molecule.charAt(j3)== '!' && molecule.charAt(j3+1)== '.'){ showopenenclosure.set(currentenclosure, false); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); j=j+2; } else { key2="!"+key+" "; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,key2,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); }; break; case 5: case 6: case 7: case 8: subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); break; case 9: key2="!"+key+" "; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,key2,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); break; } parentkey=key; index2=currentblock; index = subblocknumber.get(tid)-openblock.get(currentblock); subblockxpos.get(index2).set(index,xpos); subblockypos.get(index2).set(index,ypos); blockwidth.set(currentblock, 0.0f); blockheight.set(currentblock, 0.0f); blockdepth.set(currentblock, 0.0f); j=j+key.length()+3; temp = molecule.charAt(j); key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); } } else if (temp == '}'){ // close enclosure index2=currentblock; closeblock.set(currentblock, subblocknumber.get(tid)); containfraction = false; containenclosure=false; for (i=currentblock+1;i<=blocknumber && !containfraction && !containenclosure;i++){ if (blockenclosurelevel.get(i)==thisenclosurelevel && blocksuperscriptlevel.get(i)==thissuperscriptlevel && blocksubscriptlevel.get(i)==thissubscriptlevel && blockfractionlevel.get(i)==thisfractionlevel+1 && blocktabularlevel.get(i)==-1 && openblock.get(i)> openblock.get(currentblock) && closeblock.get(i) <= closeblock.get(currentblock)){ containfraction=true; }} textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(0)); textpaint.getTextBounds("1",0,"1".length(),textbounds); Float off=(float) textbounds.height()/2; if (containfraction){adjustfraction(tid,currentblock, blocknumber, homeblock,openblock,closeblock,thisfractionlevel, thisblocklevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, off, gap);} containfraction = false; containenclosure=false; switch(Symbol.symboltype.get(key)){ case 2: case 3: j3=j+key.length()+3; if ( molecule.charAt(j3)== '!' && molecule.charAt(j3+1)== '.'){ showcloseenclosure=false; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); j=j+2; } else { key2="!"+key+" "; showcloseenclosure=true; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,key2,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); } closeblock.set(currentblock,subblocknumber.get(tid)); closeenclosure.set(currentenclosure,subblocknumber.get(tid)); twidth=0;theight=0;tdepth=0; for (i=0; theight<=blockheight.get(currentblock)+1;i++){ symbolpaint.setTextSize(i+8); symbolpaint.getTextBounds(Symbol.symbolunicode.get(key),0,Symbol.symbolunicode.get(key).length(),symbolbounds); theight = symbolbounds.height(); i3=i;}; twidth = symbolpaint.measureText(Symbol.symbolunicode.get(key)); tdepth = symbolbounds.bottom; index=subblocknumber.get(tid)-openblock.get(currentblock); if (showopenenclosure.get(currentenclosure)){ subblockwidth.get(index2).set(1,twidth); subblockheight.get(index2).set(1,theight); subblockdepth.get(index2).set(1,tdepth); sfontsize=Integer.toString(i3+8); int is=sfontsize.length(); if (is==1){ subblockattribute.get(index2).set(1, thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4)); } else if (is==2){ subblockattribute.get(index2).set(1, thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4)); } else if (is==3){ subblockattribute.get(index2).set(1, thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4)); } subblockypos.get(index2).set(1, ypos+blockdepth.get(currentblock)-tdepth); subblockxpos.get(index2).set(1, subblockxpos.get(index2).get(0)); blockwidth.set(currentblock,blockwidth.get(currentblock)+subblockwidth.get(index2).get(1)); for (i=2; i<=subblocknumber.get(tid)-openblock.get(currentblock);i++) {subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+subblockwidth.get(index2).get(1));}; }; if (showcloseenclosure){ subblockwidth.get(index2).set(index,twidth); subblockheight.get(index2).set(index,theight); subblockdepth.get(index2).set(index,tdepth); sfontsize=Integer.toString(i3+8); int is=sfontsize.length(); if (is==1){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4)); } else if (is==2){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4)); } else if (is==3){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4)); } subblockypos.get(index2).set(index, ypos+blockdepth.get(currentblock)-tdepth); subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(0)+blockwidth.get(currentblock)); blockwidth.set(currentblock,blockwidth.get(currentblock)+subblockwidth.get(index2).get(index)); }; if (showopenenclosure.get(currentenclosure) || showcloseenclosure){ blockheight.set(currentblock,Math.max(blockheight.get(currentblock),theight+gap)); } if (showcloseenclosure){ xpos = subblockxpos.get(index2).get(index)+ twidth; } else { xpos = subblockxpos.get(index2).get(index); } parentkey=key; parentblock=currentblock; break; case 5: case 6 : j3=j+key.length()+3; key2="!"+key+" "; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,key2,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); closeblock.set(currentblock,subblocknumber.get(tid)); closeenclosure.set(currentenclosure,subblocknumber.get(tid)); twidth=0;theight=0;tdepth=0; for (i=0; twidth<=blockwidth.get(currentblock);i++){ symbolpaint.setTextSize(i+8); symbolpaint.getTextBounds(Symbol.symbolunicode.get(key),0,Symbol.symbolunicode.get(key).length(),symbolbounds); twidth=symbolbounds.width(); i3=i;}; theight = symbolbounds.height(); tdepth = symbolbounds.bottom; index2=currentblock; index=subblock.get(index2).size()-1; subblockwidth.get(index2).set(index,twidth); subblockheight.get(index2).set(index, theight); subblockdepth.get(index2).set(index, tdepth); if (Symbol.symboltype.get(key)==5){ subblockypos.get(index2).set(index, subblockypos.get(index2).get(0)-blockheight.get(currentblock)+blockdepth.get(currentblock)-tdepth); blockheight.set(currentblock,blockheight.get(currentblock)+theight); blockwidth.set(currentblock, Math.max(blockwidth.get(currentblock),twidth)); subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(0)); } else if (Symbol.symboltype.get(key)==6){ blockheight.set(currentblock,blockheight.get(currentblock)+theight+gap); blockdepth.set(currentblock,blockdepth.get(currentblock)+theight+gap); subblockypos.get(index2).set(index, subblockypos.get(index2).get(0)+blockdepth.get(currentblock)-tdepth); case6xmargin=(symbolpaint.measureText(Symbol.symbolunicode.get(key))-twidth)/2; subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(0)-case6xmargin); } sfontsize=Integer.toString(i3+8); int is=sfontsize.length(); if (is==1){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4)); } else if (is==2){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4)); } else if (is==3){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4)); } parentkey=key; break; case 7: j3=j+key.length()+3; key2="!"+key+" "; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,key2,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); closeblock.set(currentblock,subblocknumber.get(tid)); closeenclosure.set(currentenclosure,subblocknumber.get(tid)); twidth=0;theight=0;tdepth=0; if (Symbol.symbolsubtype.get(key)==1){ i3=thisfontsize-8; symbolpaint.setTextSize(i3+8); symbolpaint.getTextBounds(Symbol.symbolunicode.get(key),0,Symbol.symbolunicode.get(key).length(),symbolbounds); twidth=symbolbounds.width(); } else if (Symbol.symbolsubtype.get(key)==2){ for (i=0; twidth<=blockwidth.get(currentblock) ;i++){ symbolpaint.setTextSize(i+8); symbolpaint.getTextBounds(Symbol.symbolunicode.get(key),0,Symbol.symbolunicode.get(key).length(),symbolbounds); twidth=symbolbounds.width(); i3=i;}; }; theight = symbolbounds.height(); tdepth = symbolbounds.bottom; case7xmargin=(blockwidth.get(currentblock)-twidth)/2; index2=currentblock; index=subblock.get(index2).size()-1; subblockwidth.get(index2).set(index,twidth); subblockheight.get(index2).set(index, theight); subblockdepth.get(index2).set(index, tdepth); if (!key.equals("not") && !key.equals("bar")){ subblockypos.get(index2).set(index, subblockypos.get(index2).get(0)-blockheight.get(currentblock)+blockdepth.get(currentblock)-tdepth-gap); blockheight.set(currentblock,blockheight.get(currentblock)+theight+gap); } else { subblockypos.get(index2).set(index,subblockypos.get(index2).get(0)); } if (Symbol.symbolsubtype.get(key)==1){ subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(0)+twidth+case7xmargin); } else if (Symbol.symbolsubtype.get(key)==2){ subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(0)+case7xmargin); } blockwidth.set(currentblock, Math.max(blockwidth.get(currentblock),twidth)); sfontsize=Integer.toString(i3+8); is=sfontsize.length(); if (is==1){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4)); } else if (is==2){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4)); } else if (is==3){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4)); } parentkey=key; break; case 8: j3=j+key.length()+3; key2="!"+key+" "; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,key2,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); closeblock.set(currentblock,subblocknumber.get(tid)); closeenclosure.set(currentenclosure,subblocknumber.get(tid)); twidth=0;theight=0;tdepth=0; for (i=0; twidth<=blockwidth.get(currentblock);i++){ symbolpaint.setTextSize(i3+8); symbolpaint.getTextBounds(Symbol.symbolunicode.get(key),0,Symbol.symbolunicode.get(key).length(),symbolbounds); twidth=symbolbounds.width(); i3=i;}; theight = symbolbounds.height(); tdepth = symbolbounds.bottom; blockheight.set(currentblock,blockheight.get(currentblock)+theight+gap); blockdepth.set(currentblock,blockdepth.get(currentblock)+theight+gap); blockwidth.set(currentblock, Math.max(blockwidth.get(currentblock),twidth)); index2=currentblock; index=subblock.get(index2).size()-1; subblockwidth.get(index2).set(index,blockwidth.get(currentblock)); subblockheight.get(index2).set(index, theight); subblockdepth.get(index2).set(index, tdepth); subblockypos.get(index2).set(index, subblockypos.get(index2).get(0)+blockdepth.get(currentblock)-tdepth); subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(0)); sfontsize=Integer.toString(i3+8); is=sfontsize.length(); if (is==1){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4)); } else if (is==2){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4)); } else if (is==3){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4)); } parentkey=key; break; case 9: j3=j+key.length()+3; strokewidth=(float)thisfontsize/10; if (strokewidth < 1){strokewidth=1;}; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringhline,0.0f,strokewidth,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); closeblock.set(currentblock,subblocknumber.get(tid)); closeenclosure.set(currentenclosure,subblocknumber.get(tid)); twidth=0;theight=0;tdepth=0; for (i=0; theight<=blockheight.get(currentblock)+gap+1;i++){ symbolpaint.setTextSize(i+8); symbolpaint.getTextBounds(Symbol.symbolunicode.get(key),0,Symbol.symbolunicode.get(key).length(),symbolbounds); theight = symbolbounds.height(); i3=i;}; twidth = symbolpaint.measureText(Symbol.symbolunicode.get(key)); tdepth = symbolbounds.bottom; index2=currentblock; subblockwidth.get(index2).set(1,twidth); subblockheight.get(index2).set(1,theight); subblockdepth.get(index2).set(1,tdepth); index=subblock.get(index2).size()-1; subblockwidth.get(index2).set(index,blockwidth.get(currentblock)+1); subblockypos.get(index2).set(index, ypos-blockheight.get(currentblock)-gap+blockdepth.get(currentblock)); subblockxpos.get(index2).set(index, subblockxpos.get(index2).get(1)+subblockwidth.get(index2).get(1)-1); tempy=blockwidth.get(currentblock)+1; sfontsize=Integer.toString((int)tempy+1); is=sfontsize.length(); if (is==1){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4)); } else if (is==2){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4)); } else if (is==3){ subblockattribute.get(index2).set(index, thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4)); } blockheight.set(currentblock,blockheight.get(currentblock)+gap+strokewidth); subblockypos.get(index2).set(1, ypos+blockdepth.get(currentblock)-tdepth); blockwidth.set(currentblock,blockwidth.get(currentblock)+subblockwidth.get(index2).get(1)); for (i=2; i<=subblocknumber.get(tid)-openblock.get(currentblock)-1;i++) {subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+subblockwidth.get(index2).get(1));}; sfontsize=Integer.toString(i3+8); is=sfontsize.length(); if (is==1){ subblockattribute.get(index2).set(1, thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4)); } else if (is==2){ subblockattribute.get(index2).set(1, thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4)); } else if (is==3){ subblockattribute.get(index2).set(1, thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4)); } parentkey=""; break; } closeblock.set(currentblock, subblocknumber.get(tid)); closeenclosure.set(currentenclosure,subblocknumber.get(tid)); thisenclosurelevel--; previousenclosure = currentenclosure; for (i=subblocknumber.get(tid);currentenclosure >= 0 && closeenclosure.get(currentenclosure)>=0;i--){ currentenclosure--; } thisblocklevel--; previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } insert(tid,previousblock, currentblock, blockwidth.get(previousblock), blockheight.get(previousblock),blockdepth.get(previousblock)); j=j+key.length()+3; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); }} } }} else if (temp == charExclam && key.equals(stringosp)) { // open superscript thissuperscriptlevel++; superscriptnumber++; currentsuperscript=superscriptnumber; aftersubscript.add(false); supparentkey.add(parentkey); if (Symbol.symboltype.containsKey(parentkey) && (Symbol.symboltype.get(parentkey)<=3)){ supparentblock.add(previousblock); } else if (Symbol.symboltype.containsKey(parentkey) && (Symbol.symboltype.get(parentkey)==5 || Symbol.symboltype.get(parentkey)==7 )){ supparentblock.add(previousblock); } else if (supparentkey.get(currentsuperscript).equals("csp")){ supparentblock.add(parentblock); } else if (supparentkey.get(currentsuperscript).equals("csu")){ supparentkey.set(currentsuperscript, subparentkey.get(previoussubscript)); supparentblock.add(subparentblock.get(previoussubscript)); aftersubscript.set(currentsuperscript, true); } else { supparentblock.add(currentblock); } previousblock=currentblock; blocknumber++; currentblock= blocknumber; thisblocklevel++; thisfractionlevel=0; thisenclosurelevel = -1; synchronized(this){ create(tid,currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock ,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); } homeblock.add(currentblock); openblock.add(subblocknumber.get(tid)); closeblock.add(-1); opensuperscript.add(subblocknumber.get(tid));closesuperscript.add(-1); thisfontsize=fontsize*5/12;if (thisfontsize<8){thisfontsize=8;}; if (Symbol.symboltype.containsKey(supparentkey.get(currentsuperscript))){ switch(Symbol.symboltype.get(supparentkey.get(currentsuperscript))){ case 1 : case 6 : case 8 : case 10 : case 11 : case 12 : case 15 : case 17 : synchronized(this){ Block.error.put(tid, true); Block.errormessage.put(tid, key+" does not have superscript, parse failed!");} return; case 2 : case 3: ypos = ypos+blockdepth.get(supparentblock.get(currentsuperscript))-blockheight.get(supparentblock.get(currentsuperscript)); if (aftersubscript.get(currentsuperscript)){xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(0)+blockwidth.get(supparentblock.get(currentsuperscript));}; break; case 5 : xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(subblock.get(supparentblock.get(currentsuperscript)).size()-1); break ; case 7 : xpos=subblockxpos.get(homeblock.get(closeenclosure.get(previousenclosure))).get(0)+blockwidth.get(homeblock.get(closeenclosure.get(previousenclosure))); break ; case 13 : case 14 : if (aftersubscript.get(currentsuperscript)){xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(0)+blockwidth.get(supparentblock.get(currentsuperscript))-blockwidth.get(homeblock.get(opensubscript.get(previoussubscript)));}; break ; case 19 : case 20 : case 21 : if (!aftersubscript.get(currentsuperscript)){ xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(subblock.get(parentblock).size()-1); } else { index=subblock.get(supparentblock.get(currentsuperscript)).size()-subblock.get(homeblock.get(opensubscript.get(previoussubscript))).size()-1; xpos=Math.min(subblockxpos.get(supparentblock.get(currentsuperscript)).get(index), subblockxpos.get(supparentblock.get(currentsuperscript)).get(index+2)); } break ; case 22 : case 23 : case 24 : if (!aftersubscript.get(currentsuperscript)){ } else { index=opensubscript.get(previoussubscript)-openblock.get(supparentblock.get(currentsuperscript))-1; xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(index)+subblockwidth.get(supparentblock.get(currentsuperscript)).get(index);}; break ; } } else if (supparentkey.get(currentsuperscript).equals("csp")){ ypos = ypos+blockdepth.get(supparentblock.get(currentsuperscript))-blockheight.get(supparentblock.get(currentsuperscript)); }else { if (aftersubscript.get(currentsuperscript)){xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(0)+blockwidth.get(supparentblock.get(currentsuperscript))-blockwidth.get(homeblock.get(opensubscript.get(previoussubscript)));}; } j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals(stringcsp)) { // close superscript; index2=currentblock; closesuperscript.set(currentsuperscript, subblocknumber.get(tid)); closeblock.set(currentblock, subblocknumber.get(tid)); parentkey=supparentkey.get(currentsuperscript); if (Symbol.symboltype.containsKey(parentkey) && (Symbol.symboltype.get(parentkey)<=7 || (Symbol.symboltype.get(parentkey)>=19 && Symbol.symboltype.get(parentkey)<=24)) ){ switch(Symbol.symboltype.get(parentkey)){ case 2 : case 3 : tempy=(blockheight.get(currentblock)-blockdepth.get(currentblock))/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)+tempy); } blockheight.set(currentblock, blockheight.get(supparentblock.get(currentsuperscript))+blockheight.get(currentblock)-blockdepth.get(currentblock)-tempy); blockdepth.set(currentblock, blockdepth.get(supparentblock.get(currentsuperscript))); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (!aftersubscript.get(currentsuperscript)){ insert(tid,previousblock, currentblock,blockwidth.get(previousblock), blockheight.get(previousblock), blockdepth.get(previousblock)); } else { width1=blockwidth.get(homeblock.get(opensubscript.get(previoussubscript))); width2=blockwidth.get(previousblock); maxwidth=Math.max(width1,width2); insert(tid,previousblock, currentblock,maxwidth-width1, blockheight.get(previousblock),blockdepth.get(previousblock)); } index2=+currentblock; ypos=subblockypos.get(index2).get(0); xpos=subblockxpos.get(index2).get(0)+maxwidth; break; case 5 : for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)+blockdepth.get(supparentblock.get(currentsuperscript))-blockheight.get(supparentblock.get(currentsuperscript))-blockdepth.get(currentblock)); } index=subblock.get(supparentblock.get(currentsuperscript)).size()-1; maxwidth=Math.max(subblockwidth.get(supparentblock.get(currentsuperscript)).get(index), blockwidth.get(currentblock)); tempy=(subblockwidth.get(supparentblock.get(currentsuperscript)).get(index)-blockwidth.get(currentblock))/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+tempy); } ypos=subblockypos.get(supparentblock.get(currentsuperscript)).get(0); xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(1)+blockwidth.get(supparentblock.get(currentsuperscript)); blockdepth.set(currentblock, blockdepth.get(supparentblock.get(currentsuperscript))); blockheight.set(currentblock, blockheight.get(supparentblock.get(currentsuperscript))+blockheight.get(currentblock)+gap); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } index2=+currentblock; for (i=1;i<=index;i++){ subblockxpos.get(index2).set(openblock.get(supparentblock.get(currentsuperscript))-openblock.get(currentblock)+i, subblockxpos.get(supparentblock.get(currentsuperscript)).get(i)); } insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock),blockdepth.get(previousblock)); break ; case 7 : tempy=blockdepth.get(supparentblock.get(currentsuperscript))-blockheight.get(supparentblock.get(currentsuperscript))-blockdepth.get(currentblock)+blockheight.get(currentblock)/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)+tempy); } index=subblock.get(supparentblock.get(currentsuperscript)).size()-1; maxwidth=Math.max(subblockwidth.get(supparentblock.get(currentsuperscript)).get(index), blockwidth.get(currentblock)); ypos=subblockypos.get(supparentblock.get(currentsuperscript)).get(0); xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(1)+blockwidth.get(supparentblock.get(currentsuperscript)); blockdepth.set(currentblock, blockdepth.get(supparentblock.get(currentsuperscript))); blockheight.set(currentblock, blockheight.get(supparentblock.get(currentsuperscript))+blockheight.get(currentblock)/2+gap); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } index2=+currentblock; for (i=1;i<=index;i++){ subblockxpos.get(index2).set(openblock.get(supparentblock.get(currentsuperscript))-openblock.get(currentblock)+i, subblockxpos.get(supparentblock.get(currentsuperscript)).get(i)); } insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock), blockdepth.get(previousblock)); break ; case 19 : case 20 : case 21 : if (!aftersubscript.get(currentsuperscript)){ for (i=1;i<=subblock.get(index2).size()-1;i++){ index=subblock.get(supparentblock.get(currentsuperscript)).size()-1; subblockypos.get(index2).set(i,subblockypos.get(index2).get(i) -subblockheight.get(supparentblock.get(currentsuperscript)).get(index) +subblockdepth.get(supparentblock.get(currentsuperscript)).get(index)-gap); } } else { index=subblock.get(supparentblock.get(currentsuperscript)).size()-1-subblock.get(homeblock.get(opensubscript.get(previoussubscript))).size(); for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i) -subblockheight.get(supparentblock.get(currentsuperscript)).get(index) +subblockdepth.get(supparentblock.get(currentsuperscript)).get(index)-gap); } } if (!aftersubscript.get(currentsuperscript)){ index=subblock.get(supparentblock.get(currentsuperscript)).size()-1; width1=subblockwidth.get(supparentblock.get(currentsuperscript)).get(index); width2=blockwidth.get(currentblock); maxwidth=Math.max(width1,width2); if (width1 > width2){ float td=(maxwidth-width2)/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+td); } ypos=subblockypos.get(supparentblock.get(currentsuperscript)).get(0); xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(index)+subblockwidth.get(supparentblock.get(currentsuperscript)).get(index); } else { float td=(maxwidth-width1)/2; subblockxpos.get(supparentblock.get(currentsuperscript)).set(index, subblockxpos.get(supparentblock.get(currentsuperscript)).get(index)+td); ypos=subblockypos.get(supparentblock.get(currentsuperscript)).get(0); xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(index)+width1+td; } blockdepth.set(currentblock, subblockdepth.get(supparentblock.get(currentsuperscript)).get(index)); blockheight.set(currentblock, subblockheight.get(supparentblock.get(currentsuperscript)).get(index)+blockheight.get(currentblock)+gap); } else { index=subblock.get(supparentblock.get(currentsuperscript)).size()-subblock.get(homeblock.get(opensubscript.get(previoussubscript))).size()-1; width1=subblockwidth.get(supparentblock.get(currentsuperscript)).get(index); width2=blockwidth.get(homeblock.get(opensubscript.get(previoussubscript))); width3=blockwidth.get(currentblock); // undo the position shift in subscript if (width1 > width2) { float td=subblockxpos.get(supparentblock.get(currentsuperscript)).get(index+2)-subblockxpos.get(supparentblock.get(currentsuperscript)).get(index); for (i=index+2;i<=index+subblock.get(homeblock.get(opensubscript.get(previoussubscript))).size();i++){ subblockxpos.get(supparentblock.get(currentsuperscript)).set(i, subblockxpos.get(supparentblock.get(currentsuperscript)).get(i)-td); } }else { subblockxpos.get(supparentblock.get(currentsuperscript)).set(index, subblockxpos.get(supparentblock.get(currentsuperscript)).get(index+2)); } xpos=subblockxpos.get(supparentblock.get(currentsuperscript)).get(index); maxwidth1=Math.max(width1,width2);maxwidth=Math.max(maxwidth1, width3); if (maxwidth > width3){ float td=(maxwidth-width3)/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+td); } } if (maxwidth > width2){ float td=(maxwidth-width2)/2; for (i=index+2;i<=index+subblock.get(homeblock.get(opensubscript.get(previoussubscript))).size();i++){ subblockxpos.get(supparentblock.get(currentsuperscript)).set(i, subblockxpos.get(supparentblock.get(currentsuperscript)).get(i)+td); } } if (maxwidth > width1){ float td=(maxwidth-width1)/2; subblockxpos.get(supparentblock.get(currentsuperscript)).set(index, subblockxpos.get(supparentblock.get(currentsuperscript)).get(index)+td); } xpos=xpos+maxwidth; blockdepth.set(currentblock, blockdepth.get(homeblock.get(opensubscript.get(previoussubscript)))); blockheight.set(currentblock, blockheight.get(homeblock.get(opensubscript.get(previoussubscript)))+blockheight.get(currentblock)+gap); } ypos=subblockypos.get(supparentblock.get(currentsuperscript)).get(0); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (!aftersubscript.get(currentsuperscript)){ if (subblockwidth.get(supparentblock.get(currentsuperscript)).get(index) maxwidth){ insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock),blockdepth.get(previousblock)); } else { insert(tid,previousblock, currentblock,maxwidth-maxwidth1, blockheight.get(previousblock), blockdepth.get(previousblock)); } } break ; case 22 : case 23 : case 24 : if (!aftersubscript.get(currentsuperscript)){ index=subblock.get(supparentblock.get(currentsuperscript)).size()-1; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)-subblockheight.get(supparentblock.get(currentsuperscript)).get(index)+subblockdepth.get(supparentblock.get(currentsuperscript)).get(index)); } }else { index=subblock.get(supparentblock.get(currentsuperscript)).size()-1-subblock.get(homeblock.get(opensubscript.get(previoussubscript))).size(); for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)-subblockheight.get(supparentblock.get(currentsuperscript)).get(index)+subblockdepth.get(supparentblock.get(currentsuperscript)).get(index)); } } blockheight.set(currentblock, subblockheight.get(supparentblock.get(currentsuperscript)).get(index)+blockheight.get(currentblock)-blockdepth.get(currentblock)); blockdepth.set(currentblock, subblockdepth.get(supparentblock.get(currentsuperscript)).get(index)); thisblocklevel--; closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (!aftersubscript.get(currentsuperscript)){ insert(tid,previousblock, currentblock,blockwidth.get(previousblock), blockheight.get(previousblock), blockdepth.get(previousblock)); } else { symbolpaint.setTextSize(Integer.parseInt(subblockattribute.get(supparentblock.get(currentsuperscript)).get(1).substring(1,4))); symbolpaint.getTextBounds(Symbol.symbolunicode.get("int"),0,Symbol.symbolunicode.get("int").length(),symbolbounds); twidth = symbolbounds.width()/3; tempy=Math.max(blockwidth.get(homeblock.get(opensubscript.get(previoussubscript)))-twidth,0); tempy=Math.max(blockwidth.get(previousblock),tempy)-tempy; insert(tid,previousblock, currentblock,tempy, blockheight.get(previousblock), blockdepth.get(previousblock)); } index2=+currentblock; ypos=subblockypos.get(index2).get(0); xpos=subblockxpos.get(index2).get(0)+blockwidth.get(currentblock); break ; } }else { textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(fontinteger)); spacewidth=textpaint.measureText(" ")/2; if (!aftersubscript.get(currentsuperscript)){ index=subblock.get(supparentblock.get(currentsuperscript)).size()-1; tempx=subblockheight.get(supparentblock.get(currentsuperscript)).get(index)-subblockdepth.get(supparentblock.get(currentsuperscript)).get(index); tempy=tempx/4-blockdepth.get(currentblock); for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)-tempx+tempy); subblockxpos.get(index2).set(i,subblockxpos.get(index2).get(i)+spacewidth); } }else { index=subblock.get(supparentblock.get(currentsuperscript)).size()-1-subblock.get(homeblock.get(opensubscript.get(previoussubscript))).size(); tempx=subblockheight.get(supparentblock.get(currentsuperscript)).get(index)-subblockdepth.get(supparentblock.get(currentsuperscript)).get(index); tempy=tempx/4-blockdepth.get(currentblock); for (i=1;i<=subblock.get(currentblock).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)-tempx+tempy); subblockxpos.get(index2).set(i,subblockxpos.get(index2).get(i)+spacewidth); } } blockheight.set(currentblock, subblockheight.get(supparentblock.get(currentsuperscript)).get(index)+blockheight.get(currentblock)-blockdepth.get(currentblock)-tempy); blockdepth.set(currentblock, subblockdepth.get(supparentblock.get(currentsuperscript)).get(index)); blockwidth.set(currentblock, blockwidth.get(currentblock)+spacewidth); closeblock.set(currentblock,subblocknumber.get(tid)); thisblocklevel-=2; previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (!aftersubscript.get(currentsuperscript)){ insert(tid,previousblock, currentblock,blockwidth.get(previousblock), blockheight.get(previousblock),blockdepth.get(previousblock)); } else { tempy=Math.max(blockwidth.get(previousblock),blockwidth.get(homeblock.get(opensubscript.get(previoussubscript))))-blockwidth.get(homeblock.get(opensubscript.get(previoussubscript))); insert(tid,previousblock, currentblock,tempy, blockheight.get(previousblock), blockdepth.get(previousblock)); } index2=+currentblock; ypos=subblockypos.get(index2).get(0); xpos=subblockxpos.get(index2).get(0)+blockwidth.get(currentblock); } thisfractionlevel = blockfractionlevel.get(currentblock); thisenclosurelevel = blockenclosurelevel.get(currentblock); previoussuperscript=currentsuperscript;thissuperscriptlevel--; for (i=subblocknumber.get(tid);currentsuperscript >= 0 && closesuperscript.get(currentsuperscript)>=0;i--){ currentsuperscript--; } if (thissubscriptlevel >= 0 || thissuperscriptlevel >= 0){ thisfontsize=fontsize/3; }else if (thisfractionlevel<=2){ thisfontsize=(int)((double)fontsize*fractionfontfactor[thisfractionlevel]); }else { thisfontsize=(int)((double)fontsize*fractionfontfactor[2]); }; if (thisfontsize<8){thisfontsize=8;}; j+=5; temp = molecule.charAt(j); parentkey="csp";parentblock=previousblock; if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals(stringosu)) { // open subscript thissubscriptlevel++; subscriptnumber++; currentsubscript=subscriptnumber; aftersuperscript.add(false); subparentkey.add(parentkey); if (Symbol.symboltype.containsKey(parentkey) && (Symbol.symboltype.get(parentkey)<=3)){ subparentblock.add(previousblock); } else if (Symbol.symboltype.containsKey(parentkey) && (Symbol.symboltype.get(parentkey)==6 || Symbol.symboltype.get(parentkey)==8 )){ subparentblock.add(previousblock); } else if (subparentkey.get(currentsubscript).equals("csu")){ subparentblock.add(parentblock); } else if (subparentkey.get(currentsubscript).equals("csp")){ subparentkey.set(currentsubscript, supparentkey.get(previoussuperscript)); subparentblock.add(supparentblock.get(previoussuperscript)); aftersuperscript.set(currentsubscript, true); } else { subparentblock.add(currentblock); } previousblock=currentblock; blocknumber++; currentblock= blocknumber; thisblocklevel++; thisfractionlevel=0; thisenclosurelevel = -1; synchronized(this){ create(tid,currentblock, thisblocklevel, thisfractionlevel, thisenclosurelevel, thissuperscriptlevel, thissubscriptlevel, thistabularlevel); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,0.0f,0.0f,0.0f,xpos,ypos,thisattribute); } homeblock.add(currentblock); openblock.add(subblocknumber.get(tid)); closeblock.add(-1); opensubscript.add(subblocknumber.get(tid));closesubscript.add(-1); thisfontsize=fontsize*5/12;if (thisfontsize<8){thisfontsize=8;}; if (Symbol.symboltype.containsKey(subparentkey.get(currentsubscript))){ switch(Symbol.symboltype.get(subparentkey.get(currentsubscript))){ case 1 : case 5 : case 7 : case 10 : case 11 : case 12 : case 17 : synchronized(this){ Block.error.put(tid, true); Block.errormessage.put(tid, key+" does not have subscript, parsing failed!");} return; case 2 : case 3 : ypos = ypos+blockdepth.get(subparentblock.get(currentsubscript)); if (aftersuperscript.get(currentsubscript)){xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(0)+blockwidth.get(subparentblock.get(currentsubscript));}; break; case 6 : case 8 : xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(0); break ; case 13 : case 14 : if (aftersuperscript.get(currentsubscript)){xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(0)+blockwidth.get(subparentblock.get(currentsubscript))-blockwidth.get(homeblock.get(opensuperscript.get(previoussuperscript)));}; break ; case 15 : xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(subblock.get(parentblock).size()-1); break ; case 19 : case 20 : case 21 : if (!aftersuperscript.get(currentsubscript)){ xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(subblock.get(subparentblock.get(currentsubscript)).size()-1); } else { index=subblock.get(subparentblock.get(currentsubscript)).size()-subblock.get(homeblock.get(opensuperscript.get(previoussuperscript))).size()-1; xpos=Math.min(subblockxpos.get(subparentblock.get(currentsubscript)).get(index), subblockxpos.get(subparentblock.get(currentsubscript)).get(index+2)); } break; case 22 : case 23 : case 24 : symbolpaint.setTextSize(Integer.parseInt(subblockattribute.get(subparentblock.get(currentsubscript)).get(1).substring(1,4))); symbolpaint.getTextBounds(Symbol.symbolunicode.get("int"),0,Symbol.symbolunicode.get("int").length(),symbolbounds); twidth = symbolbounds.width()/3; if (!aftersuperscript.get(currentsubscript)){ xpos=xpos-twidth; } else { index=opensuperscript.get(previoussuperscript)-openblock.get(subparentblock.get(currentsubscript))-1; xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(index)+subblockwidth.get(subparentblock.get(currentsubscript)).get(index)-twidth; } ypos = ypos+blockdepth.get(subparentblock.get(currentsubscript)); break ; } } else if (subparentkey.get(currentsubscript).equals("csu")){ ypos = ypos+blockdepth.get(subparentblock.get(currentsubscript)); }else { if (aftersuperscript.get(currentsubscript)){xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(0)+blockwidth.get(subparentblock.get(currentsubscript))-blockwidth.get(homeblock.get(opensuperscript.get(previoussuperscript)));}; } j+=5; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals(stringcsu)) { // close subscript index2=currentblock; closesubscript.set(currentsubscript, subblocknumber.get(tid)); closeblock.set(currentblock, subblocknumber.get(tid)); parentkey=subparentkey.get(currentsubscript); if (Symbol.symboltype.containsKey(parentkey) && (Symbol.symboltype.get(parentkey)<=8 || Symbol.symboltype.get(parentkey)==15 || (Symbol.symboltype.get(parentkey)>=19 && Symbol.symboltype.get(parentkey)<=24)) ){ switch(Symbol.symboltype.get(parentkey)){ case 2 : case 3 : blockheight.set(currentblock, blockheight.get(subparentblock.get(currentsubscript))+blockdepth.get(currentblock)); blockdepth.set(currentblock, blockdepth.get(subparentblock.get(currentsubscript))+blockdepth.get(currentblock)); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } index2=+currentblock; if (!aftersuperscript.get(currentsubscript)){ insert(tid,previousblock, currentblock,blockwidth.get(previousblock), blockheight.get(previousblock),blockdepth.get(previousblock)); } else { width1=blockwidth.get(homeblock.get(opensuperscript.get(previoussuperscript))); width2=blockwidth.get(previousblock); maxwidth=Math.max(width1,width2); insert(tid,previousblock, currentblock,maxwidth-width1, blockheight.get(previousblock), blockdepth.get(previousblock)); } ypos=subblockypos.get(index2).get(0); xpos=subblockxpos.get(index2).get(0)+maxwidth; break; case 6 : for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)+blockdepth.get(subparentblock.get(currentsubscript))+blockheight.get(currentblock)-blockdepth.get(currentblock)); } index=subblock.get(subparentblock.get(currentsubscript)).size()-1; maxwidth=Math.max(subblockwidth.get(subparentblock.get(currentsubscript)).get(index), blockwidth.get(currentblock)); tempy=(subblockwidth.get(subparentblock.get(currentsubscript)).get(index)-blockwidth.get(currentblock))/2; for (i=1;i<=subblock.get(currentblock).size()-1;i++){ subblockxpos.get(currentblock).set(i, subblockxpos.get(currentblock).get(i)+tempy-case6xmargin); } ypos=subblockypos.get(subparentblock.get(currentsubscript)).get(0); xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(1)+blockwidth.get(subparentblock.get(currentsubscript)); blockdepth.set(currentblock, blockdepth.get(subparentblock.get(currentsubscript))+blockheight.get(currentblock)+gap); blockheight.set(currentblock, blockheight.get(subparentblock.get(currentsubscript))+blockheight.get(currentblock)+gap); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } index2=+currentblock; for (i=1;i<=index;i++){ subblockxpos.get(index2).set(openblock.get(subparentblock.get(currentsubscript))-openblock.get(currentblock)+i, subblockxpos.get(subparentblock.get(currentsubscript)).get(i)); } insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock),blockdepth.get(previousblock)); break ; case 8 : float thisgap=gap*fontsize/thisfontsize; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)+blockdepth.get(subparentblock.get(currentsubscript))+blockheight.get(currentblock)-blockdepth.get(currentblock)+thisgap); } index=subblock.get(subparentblock.get(currentsubscript)).size()-1; maxwidth=Math.max(subblockwidth.get(subparentblock.get(currentsubscript)).get(index), blockwidth.get(currentblock)); tempy=(subblockwidth.get(subparentblock.get(currentsubscript)).get(index)-blockwidth.get(currentblock))/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+tempy); } ypos=subblockypos.get(subparentblock.get(currentsubscript)).get(0); xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(1)+blockwidth.get(subparentblock.get(currentsubscript)); blockdepth.set(currentblock, blockdepth.get(subparentblock.get(currentsubscript))+blockheight.get(currentblock)+gap); blockheight.set(currentblock, blockheight.get(subparentblock.get(currentsubscript))+blockheight.get(currentblock)+gap); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } index2=+currentblock; for (i=1;i<=index;i++){ subblockxpos.get(index2).set(openblock.get(subparentblock.get(currentsubscript))-openblock.get(currentblock)+i, subblockxpos.get(subparentblock.get(currentsubscript)).get(i)); } insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock),blockdepth.get(previousblock)); break ; case 19 : case 20 : case 21 : if (!aftersuperscript.get(currentsubscript)){ for (i=1;i<=subblock.get(index2).size()-1;i++){ index=subblock.get(subparentblock.get(currentsubscript)).size()-1; subblockypos.get(index2).set(i,subblockypos.get(index2).get(i) +subblockdepth.get(subparentblock.get(currentsubscript)).get(index) +blockheight.get(currentblock)-blockdepth.get(currentblock)+gap); } } else { index=subblock.get(subparentblock.get(currentsubscript)).size()-1-subblock.get(homeblock.get(opensuperscript.get(previoussuperscript))).size(); for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i) +subblockdepth.get(subparentblock.get(currentsubscript)).get(index) +blockheight.get(currentblock)-blockdepth.get(currentblock)+gap); } } if (!aftersuperscript.get(currentsubscript)){ index=subblock.get(subparentblock.get(currentsubscript)).size()-1; width1=subblockwidth.get(subparentblock.get(currentsubscript)).get(index); width2=blockwidth.get(currentblock); maxwidth=Math.max(width1,width2); if (width1 > width2){ float td=(maxwidth-width2)/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+td); } xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(index)+subblockwidth.get(subparentblock.get(currentsubscript)).get(index); } else { float td=(maxwidth-width1)/2; subblockxpos.get(subparentblock.get(currentsubscript)).set(index, subblockxpos.get(subparentblock.get(currentsubscript)).get(index)+td); xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(index)+width1+td; } blockdepth.set(currentblock, subblockdepth.get(subparentblock.get(currentsubscript)).get(index)+blockheight.get(currentblock)+gap); blockheight.set(currentblock, subblockheight.get(subparentblock.get(currentsubscript)).get(index)+blockheight.get(currentblock)+gap); } else { index=subblock.get(subparentblock.get(currentsubscript)).size()-subblock.get(homeblock.get(opensuperscript.get(previoussuperscript))).size()-1; width1=subblockwidth.get(subparentblock.get(currentsubscript)).get(index); width2=blockwidth.get(homeblock.get(opensuperscript.get(previoussuperscript))); width3=blockwidth.get(currentblock); // undo the position shift in superscript if (width1 > width2) { float td=subblockxpos.get(subparentblock.get(currentsubscript)).get(index+2)-subblockxpos.get(subparentblock.get(currentsubscript)).get(index); for (i=index+2;i<=index+subblock.get(homeblock.get(opensuperscript.get(previoussuperscript))).size();i++){ subblockxpos.get(subparentblock.get(currentsubscript)).set(i, subblockxpos.get(subparentblock.get(currentsubscript)).get(i)-td); } }else { subblockxpos.get(subparentblock.get(currentsubscript)).set(index, subblockxpos.get(subparentblock.get(currentsubscript)).get(index+2)); } xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(index); maxwidth1=Math.max(width1,width2);maxwidth=Math.max(maxwidth1, width3); if (maxwidth > width3){ float td=(maxwidth-width3)/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+td); } } if (maxwidth > width2){ float td=(maxwidth-width2)/2; for (i=index+2;i<=index+subblock.get(homeblock.get(opensuperscript.get(previoussuperscript))).size();i++){ subblockxpos.get(subparentblock.get(currentsubscript)).set(i, subblockxpos.get(subparentblock.get(currentsubscript)).get(i)+td); } } if (maxwidth > width1){ float td=(maxwidth-width1)/2; subblockxpos.get(subparentblock.get(currentsubscript)).set(index, subblockxpos.get(subparentblock.get(currentsubscript)).get(index)+td); } xpos=xpos+maxwidth; blockdepth.set(currentblock, blockdepth.get(homeblock.get(opensuperscript.get(previoussuperscript)))+blockheight.get(currentblock)+gap); blockheight.set(currentblock, blockheight.get(homeblock.get(opensuperscript.get(previoussuperscript)))+blockheight.get(currentblock)+gap); } ypos=subblockypos.get(subparentblock.get(currentsubscript)).get(0); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (!aftersuperscript.get(currentsubscript)){ if (subblockwidth.get(subparentblock.get(currentsubscript)).get(index) maxwidth){ insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock),blockdepth.get(previousblock)); } else { insert(tid,previousblock, currentblock,maxwidth-maxwidth1, blockheight.get(previousblock),blockdepth.get(previousblock)); } } break ; case 22 : case 23 : case 24 : symbolpaint.setTextSize(Integer.parseInt(subblockattribute.get(subparentblock.get(currentsubscript)).get(1).substring(1,4))); symbolpaint.getTextBounds(Symbol.symbolunicode.get("int"),0,Symbol.symbolunicode.get("int").length(),symbolbounds); twidth = symbolbounds.width()/3; tempy=(blockheight.get(currentblock)-blockdepth.get(currentblock))/2; index=subblock.get(subparentblock.get(currentsubscript)).size()-1; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i)+tempy); } blockheight.set(currentblock, subblockheight.get(subparentblock.get(currentsubscript)).get(index)+blockdepth.get(currentblock)+tempy); blockdepth.set(currentblock, subblockdepth.get(subparentblock.get(currentsubscript)).get(index)+blockdepth.get(currentblock)+tempy); closeblock.set(currentblock,subblocknumber.get(tid)); thisblocklevel--; previousblock=currentblock; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (!aftersuperscript.get(currentsubscript)){ tempy=Math.max(blockwidth.get(previousblock)-twidth, 0); insert(tid,previousblock, currentblock,tempy, blockheight.get(previousblock),blockdepth.get(previousblock)); } else { tempy=Math.max(blockwidth.get(previousblock)-twidth,blockwidth.get(homeblock.get(opensuperscript.get(previoussuperscript))))-blockwidth.get(homeblock.get(opensuperscript.get(previoussuperscript))); insert(tid,previousblock, currentblock,tempy, blockheight.get(previousblock),blockdepth.get(previousblock)); } index2=+currentblock; ypos=subblockypos.get(index2).get(0); xpos=subblockxpos.get(index2).get(0)+blockwidth.get(currentblock); break ; case 15 : for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockypos.get(index2).set(i,subblockypos.get(index2).get(i) +subblockdepth.get(subparentblock.get(currentsubscript)).get(subblock.get(subparentblock.get(currentsubscript)).size()-1) +blockheight.get(currentblock)-blockdepth.get(currentblock)+gap); } index=subblock.get(subparentblock.get(currentsubscript)).size()-1; width1=subblockwidth.get(subparentblock.get(currentsubscript)).get(index); width2=blockwidth.get(currentblock); maxwidth=Math.max(width1,width2); if (width1 > width2){ float td=(maxwidth-width2)/2; for (i=1;i<=subblock.get(index2).size()-1;i++){ subblockxpos.get(index2).set(i, subblockxpos.get(index2).get(i)+td); } ypos=subblockypos.get(subparentblock.get(currentsubscript)).get(0); xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(index)+subblockwidth.get(subparentblock.get(currentsubscript)).get(index); } else { float td=(maxwidth-width1)/2; subblockxpos.get(subparentblock.get(currentsubscript)).set(index, subblockxpos.get(subparentblock.get(currentsubscript)).get(index)+td); ypos=subblockypos.get(subparentblock.get(currentsubscript)).get(0); xpos=subblockxpos.get(subparentblock.get(currentsubscript)).get(index)+width1+td; } blockdepth.set(currentblock, subblockdepth.get(subparentblock.get(currentsubscript)).get(index)+blockheight.get(currentblock)); blockheight.set(currentblock, subblockheight.get(subparentblock.get(currentsubscript)).get(index)+blockheight.get(currentblock)+gap); closeblock.set(currentblock,subblocknumber.get(tid)); previousblock=currentblock;thisblocklevel--; for (i=subblocknumber.get(tid);currentblock >=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (subblockwidth.get(subparentblock.get(currentsubscript)).get(index)=0 && closeblock.get(currentblock)>=0;i--){ currentblock--; } if (!aftersuperscript.get(currentsubscript)){ insert(tid,previousblock, currentblock,blockwidth.get(previousblock), blockheight.get(previousblock), blockdepth.get(previousblock)); } else { tempy=Math.max(blockwidth.get(previousblock),blockwidth.get(homeblock.get(opensuperscript.get(previoussuperscript))))-blockwidth.get(homeblock.get(opensuperscript.get(previoussuperscript))); insert(tid,previousblock, currentblock,tempy, blockheight.get(previousblock),blockdepth.get(previousblock)); } index2=+currentblock; ypos=subblockypos.get(index2).get(0); xpos=subblockxpos.get(index2).get(0)+blockwidth.get(currentblock); } thisfractionlevel = blockfractionlevel.get(currentblock); thisenclosurelevel = blockenclosurelevel.get(currentblock); previoussubscript=currentsubscript;thissubscriptlevel--; for (i=subblocknumber.get(tid);currentsubscript >= 0 && closesubscript.get(currentsubscript)>=0;i--){ currentsubscript--; } if (thissubscriptlevel >= 0 || thissuperscriptlevel >= 0){ thisfontsize=fontsize/3; }else if (thisfractionlevel<=2){ thisfontsize=(int)((double)fontsize*fractionfontfactor[thisfractionlevel]); }else { thisfontsize=(int)((double)fontsize*fractionfontfactor[2]); }; if (thisfontsize<8){thisfontsize=8;}; j+=5; temp = molecule.charAt(j); parentkey="csu";parentblock=previousblock; if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam && key.equals("hsp")){ // hspace j+=5; key=molecule.substring(j,molecule.indexOf("}",j));j=j+key.length()+1; twidth=Float.parseFloat(key); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stringdnot,twidth,0.0f,0.0f,xpos,ypos,thisattribute); homeblock.add(currentblock); xpos=xpos+twidth; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); }} }else if (temp == charExclam && key.equals("vsp")){ // vspace synchronized(this){ Block.error.put(tid, true); Block.errormessage.put(tid, "vspace inserted in wrong place, parse failed!");} return; } else { for (i = 0 ; (temp != charExclam) || (temp == charExclam && Symbol.symboltype.containsKey(key) && Symbol.symboltype.get(key) >= 10 ) ; i++) { if (temp != charExclam) { // italic text sfontsize=Integer.toString(thisfontsize); ij=sfontsize.length(); if (ij==1){ thisattribute=thisattribute.substring(0,1)+"00"+sfontsize+thisattribute.substring(4); } else if (ij==2){ thisattribute=thisattribute.substring(0,1)+"0"+sfontsize+thisattribute.substring(4); } else if (ij==3){ thisattribute=thisattribute.substring(0,1)+sfontsize+thisattribute.substring(4); } textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(Integer.parseInt(thisattribute.substring(4,7)))); ii=molecule.indexOf('!',j); String stemp=molecule.substring(j,ii); textpaint.getTextBounds(stemp,0,stemp.length(),textbounds); subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stemp,textpaint.measureText(stemp),(float)textbounds.height(),(float)textbounds.bottom, xpos,ypos,thisattribute); homeblock.add(currentblock); xpos=xpos+textpaint.measureText(stemp); parentkey=stemp.substring(stemp.length()-1); parentblock=currentblock; j=ii; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); }} } else if (temp == charExclam){ // symbol if (Symbol.symboltype.get(key)==20 || Symbol.symboltype.get(key)==23){ sfontsize=Integer.toString((int) ((float)thisfontsize*Header.bigopsize)); symbolpaint.setTextSize((int)(float)thisfontsize*Header.bigopsize); } else if (Symbol.symboltype.get(key)==21 || Symbol.symboltype.get(key)==24){ sfontsize=Integer.toString((int) ((float)thisfontsize*Header.bigbigopsize)); symbolpaint.setTextSize((int)(float)thisfontsize*Header.bigbigopsize); } else { sfontsize=Integer.toString(thisfontsize); symbolpaint.setTextSize(thisfontsize); } textpaint.setTextSize(thisfontsize); textpaint.setTypeface(tf.get(fontinteger)); String stemp="a"; textpaint.getTextBounds(stemp,0,stemp.length(),textbounds); Float sizeofa=(float) textbounds.height(); if (Symbol.symboltype.get(key)==15 || Symbol.symboltype.get(key)==14) { ij=sfontsize.length(); if (ij==1){ attribute2=thisattribute.substring(0,1)+"00"+sfontsize+"005"+thisattribute.substring(7); } else if (ij==2){ attribute2=thisattribute.substring(0,1)+"0"+sfontsize+"005"+thisattribute.substring(7); } else if (ij==3){ attribute2=thisattribute.substring(0,1)+sfontsize+"005"+thisattribute.substring(7); } textpaint5.setTextSize(thisfontsize); textpaint5.getTextBounds(Symbol.symbolunicode.get(key),0,Symbol.symbolunicode.get(key).length(),textbounds5); twidth = textpaint5.measureText(Symbol.symbolunicode.get(key)); theight = textbounds5.height(); tdepth = textbounds5.bottom; }else { ij=sfontsize.length(); if (ij==1){ attribute2=thisattribute.substring(0,1)+"00"+sfontsize+"004"+thisattribute.substring(7); } else if (ij==2){ attribute2=thisattribute.substring(0,1)+"0"+sfontsize+"004"+thisattribute.substring(7); } else if (ij==3){ attribute2=thisattribute.substring(0,1)+sfontsize+"004"+thisattribute.substring(7); } symbolpaint.getTextBounds(Symbol.symbolunicode.get(key),0,Symbol.symbolunicode.get(key).length(),symbolbounds); twidth = symbolpaint.measureText(Symbol.symbolunicode.get(key)); theight = symbolbounds.height(); tdepth = symbolbounds.bottom; } parentkey=key; parentblock=currentblock; theight=Math.max(theight, sizeofa); ii=j+key.length()+1; stemp=molecule.substring(j,ii).trim()+" "; subblocknumber.put(tid, subblocknumber.get(tid)+1); add(tid,currentblock,stemp,twidth,theight,tdepth,xpos,ypos,attribute2); homeblock.add(currentblock); xpos=xpos+twidth; j=j+key.length()+1; temp = molecule.charAt(j); if (temp == charExclam){ key = ""; for (ii=j+1;!(molecule.charAt(ii)==' ' ||molecule.charAt(ii)=='}' || molecule.charAt(ii)=='{'|| molecule.charAt(ii)=='!');ii++){ key = key + molecule.charAt(ii); }} if(molecule.charAt(ii)==' ' && molecule.charAt(ii+1)!='!'){j=j+1;} }; }; } } synchronized(this){ block.result(tid, blocknumber, subblock, subblockwidth, subblockheight, subblockdepth, subblockxpos, subblockypos, subblockattribute, blockwidth, blockheight, blockdepth);} } public void add(int tid, int blocknumber, String block, Float width, Float height, Float depth, Float xpos, Float ypos, String attribute) { int index=blocknumber; subblock.get(index).add(block); subblockwidth.get(index).add(width); subblockheight.get(index).add(height); subblockdepth.get(index).add(depth); subblockxpos.get(index).add(xpos); subblockypos.get(index).add(ypos); subblockattribute.get(index).add(attribute); blockwidth.set(blocknumber, blockwidth.get(blocknumber)+width); float maxtop=Math.max(blockheight.get(blocknumber)-blockdepth.get(blocknumber), height-depth); blockdepth.set(blocknumber, Math.max(blockdepth.get(blocknumber),depth)); blockheight.set(blocknumber,maxtop+blockdepth.get(blocknumber)); return; } public void create(int tid, int blocknumber, int thisblocklevel, int thisfractionlevel, int thisenclosurelevel, int thissuperscriptlevel, int thissubscriptlevel, int thistabularlevel) { int index=blocknumber; subblock.add(index,new ArrayList()); subblockwidth.add(index,new ArrayList()); subblockheight.add(index,new ArrayList()); subblockdepth.add(index,new ArrayList()); subblockxpos.add(index,new ArrayList()); subblockypos.add(index,new ArrayList()); subblockattribute.add(index,new ArrayList()); blocklevel.add(thisblocklevel); blockfractionlevel.add(thisfractionlevel); blockenclosurelevel.add(thisenclosurelevel); blocksuperscriptlevel.add(thissuperscriptlevel); blocksubscriptlevel.add(thissubscriptlevel); blocktabularlevel.add(thistabularlevel); blockwidth.add(0.0f); blockheight.add(0.0f); blockdepth.add(0.0f); return; } public void insert(int tid, int blocknumber1, int blocknumber2 , Float width, Float height, Float depth) { int index1=blocknumber1; int index2=blocknumber2; int l=subblock.get(index1).size(); for (int i=0;i<=l-1;i++){ subblock.get(index2).add(subblock.get(index1).get(i)); subblockwidth.get(index2).add(subblockwidth.get(index1).get(i)); subblockheight.get(index2).add(subblockheight.get(index1).get(i)); subblockdepth.get(index2).add(subblockdepth.get(index1).get(i)); subblockxpos.get(index2).add(subblockxpos.get(index1).get(i)); subblockypos.get(index2).add(subblockypos.get(index1).get(i)); subblockattribute.get(index2).add(subblockattribute.get(index1).get(i)); } float maxtop=Math.max(blockheight.get(blocknumber2)-blockdepth.get(blocknumber2), height-depth); blockdepth.set(blocknumber2, Math.max(blockdepth.get(blocknumber2),depth)); blockheight.set(blocknumber2, maxtop+blockdepth.get(blocknumber2)); blockwidth.set(blocknumber2, blockwidth.get(blocknumber2)+width); return; } public void adjustfraction(int tid, int blocknumber, int maxblocknumber, ArrayList blocklist, ArrayList openblock,ArrayList closeblock,int thisfractionlevel, int thisblocklevel, int thisenclosurelevel, int thissuperscriptlevel, int thissubscriptlevel, Float off, Float linewidth) { ArrayList liney= new ArrayList(); ArrayList line = new ArrayList(); int numfrac=0; int index2=blocknumber; int index = openblock.get(blocknumber); for (int i=index;i<=closeblock.get(blocknumber);i++){ if(blockenclosurelevel.get(blocklist.get(i)) == thisenclosurelevel && blocksuperscriptlevel.get(blocklist.get(i)) == thissuperscriptlevel && blocksubscriptlevel.get(blocklist.get(i)) == thissubscriptlevel && blockfractionlevel.get(blocklist.get(i))==thisfractionlevel+1 && subblock.get(index2).get(i-index).equals("!hlin ")){ numfrac++; liney.add(subblockypos.get(index2).get(i-index)); line.add(i-index); } } ArrayList adjustedblock = new ArrayList(); ArrayList adjustedfrac = new ArrayList(); int numblock=0; for (int i=0;i<=numfrac-1;i++){ adjustedblock.add(blocklist.get(line.get(i)+index)-1); adjustedfrac.add(i); numblock++; } float minliney=10000; for (int i=0;i<=numfrac-1;i++){ minliney=Math.min(minliney, liney.get(i)); } Float maxtop1=0.0f; Float maxbottom1=0.0f; int i=0; Float top1=0.0f; Float bottom1 =0.0f; for (i=0;i adjusted = new ArrayList(); for (i=0;i<=lengthofblock;i++){ adjusted.add(false); } for (i=0;i