summaryrefslogtreecommitdiff
path: root/systems/android/hktex/HKtex2/src/worker4math/hktex2/Parseblock.java
diff options
context:
space:
mode:
Diffstat (limited to 'systems/android/hktex/HKtex2/src/worker4math/hktex2/Parseblock.java')
-rw-r--r--systems/android/hktex/HKtex2/src/worker4math/hktex2/Parseblock.java2554
1 files changed, 2554 insertions, 0 deletions
diff --git a/systems/android/hktex/HKtex2/src/worker4math/hktex2/Parseblock.java b/systems/android/hktex/HKtex2/src/worker4math/hktex2/Parseblock.java
new file mode 100644
index 0000000000..19bd8d08df
--- /dev/null
+++ b/systems/android/hktex/HKtex2/src/worker4math/hktex2/Parseblock.java
@@ -0,0 +1,2554 @@
+//
+// 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<Integer> blockfractionlevel = new ArrayList<Integer>();
+ private ArrayList<Integer> blocklevel = new ArrayList<Integer>();
+ private ArrayList<Integer> blockenclosurelevel = new ArrayList<Integer>();
+ private ArrayList<Integer> blocksuperscriptlevel = new ArrayList<Integer>();
+ private ArrayList<Integer> blocksubscriptlevel = new ArrayList<Integer>();
+ private ArrayList<Integer> blocktabularlevel = new ArrayList<Integer>();
+ private ArrayList<Float> blockwidth = new ArrayList<Float>();
+ private ArrayList<Float> blockheight = new ArrayList<Float>();
+ private ArrayList<Float> blockdepth = new ArrayList<Float>();
+
+ private ArrayList<ArrayList<String>> subblock = new ArrayList<ArrayList<String>>();
+ private ArrayList<ArrayList<Float>> subblockwidth = new ArrayList<ArrayList<Float>>();
+ private ArrayList<ArrayList<Float>> subblockheight = new ArrayList<ArrayList<Float>>();
+ private ArrayList<ArrayList<Float>> subblockdepth = new ArrayList<ArrayList<Float>>();
+ private ArrayList<ArrayList<Float>> subblockxpos = new ArrayList<ArrayList<Float>>();
+ private ArrayList<ArrayList<Float>> subblockypos = new ArrayList<ArrayList<Float>>();
+ private ArrayList<ArrayList<String>> subblockattribute = new ArrayList<ArrayList<String>>();
+
+ public void parseblock(int tid, Canvas canvas, Block block, String molecule, ArrayList<Typeface> 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<Boolean> showopenenclosure = new ArrayList<Boolean>();
+ ArrayList<Boolean> aftersuperscript = new ArrayList<Boolean>();
+ ArrayList<Boolean> aftersubscript = new ArrayList<Boolean>();
+
+ ArrayList<Float> numeratorwidth = new ArrayList<Float>();
+ ArrayList<Float> numeratorheight = new ArrayList<Float>();
+ ArrayList<Float> numeratordepth = new ArrayList<Float>();
+ ArrayList<Float> denominatorwidth = new ArrayList<Float>();
+ ArrayList<Float> denominatorheight = new ArrayList<Float>();
+ ArrayList<Float> denominatordepth = new ArrayList<Float>();
+ ArrayList<Float> fractionwidth = new ArrayList<Float>();
+ ArrayList<Float> fractionheight = new ArrayList<Float>();
+ ArrayList<Float> fractiondepth = new ArrayList<Float>();
+ ArrayList<Float> columnwidth = new ArrayList<Float>();
+
+ ArrayList<Integer> openblock = new ArrayList<Integer>();
+ ArrayList<Integer> closeblock = new ArrayList<Integer>();
+ ArrayList<Integer> subparentblock = new ArrayList<Integer>();
+ ArrayList<Integer> supparentblock = new ArrayList<Integer>();
+ ArrayList<Integer> linenu = new ArrayList<Integer>();
+ ArrayList<Integer> openfraction = new ArrayList<Integer>();
+ ArrayList<Integer> closefraction = new ArrayList<Integer>();
+ ArrayList<Integer> opennumerator = new ArrayList<Integer>();
+ ArrayList<Integer> closenumerator = new ArrayList<Integer>();
+ ArrayList<Integer> opendenominator = new ArrayList<Integer>();
+ ArrayList<Integer> closedenominator = new ArrayList<Integer>();
+ ArrayList<Integer> homeblock = new ArrayList<Integer>();
+ ArrayList<Integer> numeratorindex = new ArrayList<Integer>();
+ ArrayList<Integer> denominatorindex = new ArrayList<Integer>();
+ ArrayList<Integer> opensubscript = new ArrayList<Integer>();
+ ArrayList<Integer> closesubscript = new ArrayList<Integer>();
+ ArrayList<Integer> opensuperscript = new ArrayList<Integer>();
+ ArrayList<Integer> closesuperscript = new ArrayList<Integer>();
+ ArrayList<Integer> openenclosure = new ArrayList<Integer>();
+ ArrayList<Integer> closeenclosure = new ArrayList<Integer>();
+ ArrayList<Integer> opentabular = new ArrayList<Integer>();
+ ArrayList<Integer> closetabular = new ArrayList<Integer>();
+ ArrayList<Integer> opentabularline = new ArrayList<Integer>();
+ ArrayList<Integer> closetabularline = new ArrayList<Integer>();
+ ArrayList<Integer> opentabularlineblock = new ArrayList<Integer>();
+ ArrayList<Integer> closetabularlineblock = new ArrayList<Integer>();
+
+ ArrayList<String> supparentkey = new ArrayList<String>();
+ ArrayList<String> subparentkey = new ArrayList<String>();
+
+ 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)<blockwidth.get(previousblock)){
+ float td=(maxwidth-subblockwidth.get(supparentblock.get(currentsuperscript)).get(index));
+ insert(tid,previousblock, currentblock,td, blockheight.get(previousblock),blockdepth.get(previousblock));
+ } else {
+ insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock),blockdepth.get(previousblock));
+ }} else {
+ if (maxwidth1 > 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)<blockwidth.get(previousblock)){
+ float td=(maxwidth-subblockwidth.get(subparentblock.get(currentsubscript)).get(index));
+ insert(tid,previousblock, currentblock,td, blockheight.get(previousblock),blockdepth.get(previousblock));
+ } else {
+ insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock),blockdepth.get(previousblock));
+ }
+ } else {
+ if (maxwidth1 > 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)<blockwidth.get(previousblock)){
+ float td=(maxwidth-subblockwidth.get(subparentblock.get(currentsubscript)).get(index))/2;
+ insert(tid,previousblock, currentblock,td, blockheight.get(previousblock),blockdepth.get(previousblock));
+ }
+ else {
+ insert(tid,previousblock, currentblock,0.0f, blockheight.get(previousblock), blockdepth.get(previousblock));
+ }
+ break ;
+ }
+ }else {
+ 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);
+ }
+ tempy=Math.max(subblockdepth.get(subparentblock.get(currentsubscript)).get(index),(blockdepth.get(currentblock)+ blockheight.get(currentblock))/2);
+ maxtop=subblockheight.get(subparentblock.get(currentsubscript)).get(index)-subblockdepth.get(subparentblock.get(currentsubscript)).get(index);
+ blockdepth.set(currentblock, tempy);
+ blockheight.set(currentblock,maxtop+blockdepth.get(currentblock));
+
+ closeblock.set(currentblock,subblocknumber.get(tid));
+ thisblocklevel-=2;
+ previousblock=currentblock;
+ for (i=subblocknumber.get(tid);currentblock >=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<String>());
+ subblockwidth.add(index,new ArrayList<Float>());
+ subblockheight.add(index,new ArrayList<Float>());
+ subblockdepth.add(index,new ArrayList<Float>());
+ subblockxpos.add(index,new ArrayList<Float>());
+ subblockypos.add(index,new ArrayList<Float>());
+ subblockattribute.add(index,new ArrayList<String>());
+
+ 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<Integer> blocklist, ArrayList<Integer> openblock,ArrayList<Integer> closeblock,int thisfractionlevel, int thisblocklevel, int thisenclosurelevel, int thissuperscriptlevel, int thissubscriptlevel, Float off, Float linewidth) {
+
+ ArrayList<Float> liney= new ArrayList<Float>();
+ ArrayList<Integer> line = new ArrayList<Integer>();
+ 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<Integer> adjustedblock = new ArrayList<Integer>();
+ ArrayList<Integer> adjustedfrac = new ArrayList<Integer>();
+ 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<numblock;i++){
+ float diff = liney.get(adjustedfrac.get(i))-minliney;
+ bottom1=blockdepth.get(adjustedblock.get(i))-diff;
+ top1=blockheight.get(adjustedblock.get(i))-bottom1;
+ maxtop1=Math.max(maxtop1, top1);
+ maxbottom1=Math.max(maxbottom1, bottom1);
+ blockfractionlevel.set(adjustedfrac.get(i), 0);
+ }
+
+ int lengthofblock=closeblock.get(blocknumber)-openblock.get(blocknumber);
+ ArrayList<Boolean> adjusted = new ArrayList<Boolean>();
+ for (i=0;i<=lengthofblock;i++){
+ adjusted.add(false);
+ }
+
+ for (i=0;i<numblock;i++){
+ float diff = liney.get(adjustedfrac.get(i))-minliney;
+ for (int ii=openblock.get(adjustedblock.get(i));ii<=closeblock.get(adjustedblock.get(i));ii++){
+ index=ii-openblock.get(blocknumber);
+ subblockypos.get(index2).set(index,subblockypos.get(index2).get(index)-diff);
+ adjusted.set(index, true);
+ }
+ }
+ Float diff=subblockypos.get(index2).get(0)-minliney-off;
+ Float maxtop2=0.0f;
+ Float maxbottom2=0.0f;
+ for (i=1;i<=lengthofblock;i++){
+ Float top2=0.0f;
+ Float bottom2 = 0.0f;
+ if(!adjusted.get(i)){
+ subblockypos.get(index2).set(i, subblockypos.get(index2).get(i)-diff);
+ bottom2=subblockdepth.get(index2).get(i)-diff;
+ top2=subblockheight.get(index2).get(i)-bottom2;
+ maxtop2=Math.max(maxtop2, top2);
+ maxbottom2=Math.max(maxbottom2, bottom2);
+ }
+ }
+ Float maxtop=Math.max(maxtop1, maxtop2);
+ Float maxbottom=Math.max(maxbottom1, maxbottom2);
+ blockheight.set(blocknumber, maxtop+maxbottom);
+ blockdepth.set(blocknumber, maxbottom);
+
+ maxtop1=0.0f;maxbottom1=0.0f;maxtop2=0.0f;maxbottom2=0.0f;maxtop=0.0f;maxbottom=0.0f;
+ liney.clear();line.clear();
+ return;
+ }
+ } \ No newline at end of file