private void draw() { Utils.log("draw", "Lookahead({0}), TokenType({1}), Caret({2})", getCurrentToken(), lookahead(), this.currentDrawToken); LayoutGroup lg; if (getCurrentToken() == this.currentDrawToken) { DrawCaret(); } switch (lookahead()) { // Basic Terminals case TokenType.DIGIT: Utils.log("draw", "Drawing digit"); AddTextBox(lexeme(), fontSizes.Peek()); accept(TokenType.DIGIT); break; case TokenType.OPEN_PAREN: accept(TokenType.OPEN_PAREN); lg = new LayoutGroup(LayoutGroupType.REL_POS_RIGHT); lg.setWrapperParens(); layoutGroupCurrent.Push(lg); while (lookahead() != TokenType.CLOSE_PAREN && !atEndOfStream()) { draw(); } if (getCurrentToken() == this.currentDrawToken) { DrawCaret(); } layoutGroupCurrent.Pop(); layoutGroupCurrent.Peek().Add(lg); accept(TokenType.CLOSE_PAREN); break; case TokenType.OP_SQRT: accept(TokenType.OP_SQRT); accept(TokenType.OPEN_RADICAL); lg = new LayoutGroup(LayoutGroupType.REL_POS_RIGHT); lg.setWrapperRadical(); layoutGroupCurrent.Push(lg); while (lookahead() != TokenType.CLOSE_RADICAL && !atEndOfStream()) { draw(); } if (getCurrentToken() == this.currentDrawToken) { DrawCaret(); } //this.centrelineYs.Pop(); accept(TokenType.CLOSE_RADICAL); layoutGroupCurrent.Pop(); layoutGroupCurrent.Peek().Add(lg); break; /* * Drawing fractions by having equidistant 'lines', * We draw numbers between the lines and the fraction lines ON the lines. * * We do this by 2 principles: * Fractions on the same level should have their centre lines drawn at the same y-value. * Fractions which may overlap with above or below lines should create space by pushing them up. * */ case TokenType.OPEN_FRAC_UP: //Debugger.Log(0, "[draw]", String.Format("OPEN_FRAC_UP")); // Opening a fraction: accept(TokenType.OPEN_FRAC_UP); lg = new LayoutGroup(LayoutGroupType.REL_POS_FRACTION); layoutGroupCurrent.Push(lg); lg = new LayoutGroup(LayoutGroupType.REL_POS_FRACTION_NUMERATOR); layoutGroupCurrent.Push(lg); // Draw Numerator while (lookahead() != TokenType.CLOSE_FRAC_UP && !atEndOfStream()) { draw(); } if (getCurrentToken() == this.currentDrawToken) { DrawCaret(); } accept(TokenType.CLOSE_FRAC_UP); accept(TokenType.OPEN_FRAC_DOWN); lg = new LayoutGroup(LayoutGroupType.REL_POS_FRACTION_DENOMINATOR); layoutGroupCurrent.Push(lg); // Draw Denominator while (lookahead() != TokenType.CLOSE_FRAC_DOWN && !atEndOfStream()) { draw(); } if (getCurrentToken() == this.currentDrawToken) { DrawCaret(); } accept(TokenType.CLOSE_FRAC_DOWN); // Pop Denominator LayoutGroup denom = layoutGroupCurrent.Pop(); LayoutGroup num = layoutGroupCurrent.Pop(); LayoutGroup frac = layoutGroupCurrent.Pop(); frac.Add(num); frac.Add(denom); layoutGroupCurrent.Peek().Add(frac); break; case TokenType.OPEN_SUPER: accept(TokenType.OPEN_SUPER); lg = new LayoutGroup(LayoutGroupType.REL_POS_SUPER); layoutGroupCurrent.Push(lg); while (lookahead() != TokenType.CLOSE_SUPER && !atEndOfStream()) { draw(); } if (getCurrentToken() == this.currentDrawToken) { DrawCaret(); } accept(TokenType.CLOSE_SUPER); lg = layoutGroupCurrent.Pop(); layoutGroupCurrent.Peek().Add(lg); break; case TokenType.PLACEHOLDER: double h = this.fontSizes.Peek(); AddRectangle(10, h); accept(TokenType.PLACEHOLDER); break; default: AddTextBox(lexRepr(), fontSizes.Peek()); accept(lookahead()); break; } }