void JSummation::Render ( const JExprRenderer& renderer, const JExprRectList& rectList ) const { // find ourselves in the list JIndex ourIndex; const JBoolean found = rectList.FindFunction(this, &ourIndex); assert( found ); const JRect ourRect = rectList.GetRect(ourIndex); const JCoordinate ourMidline = rectList.GetMidline(ourIndex); const JSize fontSize = rectList.GetFontSize(ourIndex); // draw ourselves JCoordinate h = ourRect.left; const JSize spaceWidth = renderer.GetStringWidth(fontSize, " "); const JSize argCount = GetArgCount(); for (JIndex i=1; i<=argCount; i++) { const JFunction* f = this; const JFunction* arg = GetArg(i); if (arg->GetType() == kJNegationType) { renderer.DrawString(h, ourMidline, fontSize, JPGetSubtractionString()); f = arg; const JNegation* neg = dynamic_cast<const JNegation*>(arg); assert( neg != NULL ); arg = neg->GetArg(); } else if (i > 1) { renderer.DrawString(h, ourMidline, fontSize, JPGetAdditionString()); } arg->Render(renderer, rectList); JIndex argIndex; const JBoolean found = rectList.FindFunction(arg, &argIndex); assert( found ); const JRect argRect = rectList.GetRect(argIndex); h = argRect.right; if (ParenthesizeArgForRender(*f, *arg)) { renderer.DrawParentheses(argRect); h += renderer.GetParenthesisWidth(argRect.height()); } h += spaceWidth; } }
JSize JFunctionWithVar::GetStringWidth ( const JExprRenderer& renderer, const JSize fontSize, const JString& str ) const { JSize w = 0; const JCharacter* greekPrefix = JPGetGreekCharPrefixString(); const JSize greekPrefixLength = JPGetGreekCharPrefixLength(); JString s = str; JIndex greekIndex; while (s.LocateSubstring(greekPrefix, &greekIndex) && greekIndex < s.GetLength() - greekPrefixLength + 1) { if (greekIndex > 1) { const JString s1 = s.GetSubstring(1, greekIndex-1); w += renderer.GetStringWidth(fontSize, s1); } const JCharacter c = s.GetCharacter(greekIndex + greekPrefixLength); w += renderer.GetGreekCharWidth(fontSize, c); s.RemoveSubstring(1, greekIndex + greekPrefixLength); } if (!s.IsEmpty()) { w += renderer.GetStringWidth(fontSize, s); } return w; }
JIndex JFunction::PrepareToRender ( const JExprRenderer& renderer, const JPoint& upperLeft, const JSize fontSize, JExprRectList* rectList ) { const JString text = Print(); JRect ourRect; ourRect.top = upperLeft.y; ourRect.left = upperLeft.x; ourRect.bottom = upperLeft.y + renderer.GetLineHeight(fontSize); ourRect.right = upperLeft.x + renderer.GetStringWidth(fontSize, text); const JCoordinate ourMidline = ourRect.ycenter(); return rectList->AddRect(ourRect, ourMidline, fontSize, this); }
void JFunctionWithVar::DrawString ( const JExprRenderer& renderer, const JCoordinate left, const JCoordinate midline, const JSize fontSize, const JString& str ) const { JCoordinate x = left; const JCharacter* greekPrefix = JPGetGreekCharPrefixString(); const JSize greekPrefixLength = JPGetGreekCharPrefixLength(); JString s = str; JIndex greekIndex; while (s.LocateSubstring(greekPrefix, &greekIndex) && greekIndex < s.GetLength() - greekPrefixLength + 1) { if (greekIndex > 1) { const JString s1 = s.GetSubstring(1, greekIndex-1); renderer.DrawString(x, midline, fontSize, s1); x += renderer.GetStringWidth(fontSize, s1); } const JCharacter c = s.GetCharacter(greekIndex + greekPrefixLength); renderer.DrawGreekCharacter(x, midline, fontSize, c); x += renderer.GetGreekCharWidth(fontSize, c); s.RemoveSubstring(1, greekIndex + greekPrefixLength); } if (!s.IsEmpty()) { renderer.DrawString(x, midline, fontSize, s); } }
JIndex JLogB::PrepareToRender ( const JExprRenderer& renderer, const JPoint& upperLeft, const JSize fontSize, JExprRectList* rectList ) { // intialize our rectangle const JCharacter* name = GetName(); const JSize nameLength = strlen(name); assert( nameLength > 1 ); assert( name[ nameLength-1 ] == '(' ); const JString fnName = JString(name, nameLength-1); JRect ourRect; ourRect.top = upperLeft.y; ourRect.left = upperLeft.x; ourRect.bottom = upperLeft.y + renderer.GetLineHeight(fontSize); ourRect.right = upperLeft.x + renderer.GetStringWidth(fontSize, fnName); // get rectangle for base JPoint argUpperLeft(ourRect.right, ourRect.top); const JSize baseFontSize = renderer.GetSuperSubFontSize(fontSize); JFunction* base = GetArg1(); const JIndex baseIndex = base->PrepareToRender(renderer, argUpperLeft, baseFontSize, rectList); const JRect baseRect = rectList->GetRect(baseIndex); argUpperLeft.x = baseRect.right; // get rectangle for argument -- gives our midline JFunction* arg = GetArg2(); const JIndex argIndex = arg->PrepareToRender(renderer, argUpperLeft, fontSize, rectList); const JRect argRect = rectList->GetRect(argIndex); ourRect = JCovering(ourRect, argRect); const JCoordinate ourMidline = rectList->GetMidline(argIndex); // shift argument to make space for left parenthesis const JSize parenWidth = renderer.GetParenthesisWidth(argRect.height()); rectList->ShiftRect(argIndex, parenWidth, 0); // we need space for two parentheses ourRect.right += 2*parenWidth; // shift the base down rectList->ShiftRect(baseIndex, 0, ourMidline - ourRect.top); ourRect = JCovering(ourRect, rectList->GetRect(baseIndex)); // save our rectangle return rectList->AddRect(ourRect, ourMidline, fontSize, this); }
void JParallel::Render ( const JExprRenderer& renderer, const JExprRectList& rectList ) const { // find ourselves in the list JIndex ourIndex; const JBoolean found = rectList.FindFunction(this, &ourIndex); assert( found ); const JRect ourRect = rectList.GetRect(ourIndex); const JCoordinate ourMidline = rectList.GetMidline(ourIndex); const JSize fontSize = rectList.GetFontSize(ourIndex); // draw ourselves const JSize spaceWidth = renderer.GetStringWidth(fontSize, " "); const JSize barWidth = renderer.GetVertBarWidth(); const JSize lineHeight = renderer.GetLineHeight(fontSize); JSize maxBarLength; if (((JSize) ourRect.height()) > lineHeight) { maxBarLength = JLFloor(ourRect.height()/2.0); } else { maxBarLength = ourRect.height(); } JSize barLength; if (ourMidline > ourRect.ycenter()) { barLength = 2*(ourRect.bottom - ourMidline); } else { barLength = 2*(ourMidline - ourRect.top); } if (barLength > maxBarLength) { barLength = maxBarLength; } const JCoordinate barTop = ourMidline - barLength/2; const JSize argCount = GetArgCount(); for (JIndex i=1; i<=argCount; i++) { const JFunction* arg = GetArg(i); arg->Render(renderer, rectList); JIndex argIndex; const JBoolean found = rectList.FindFunction(arg, &argIndex); assert( found ); const JRect argRect = rectList.GetRect(argIndex); JCoordinate h = argRect.right + spaceWidth; if (ParenthesizeArgForRender(*this, *arg)) { renderer.DrawParentheses(argRect); h += renderer.GetParenthesisWidth(argRect.height()); } if (i < argCount) { renderer.DrawVertBar(h, barTop, barLength); renderer.DrawVertBar(h + barWidth, barTop, barLength); } } }
JIndex JParallel::PrepareToRender ( const JExprRenderer& renderer, const JPoint& upperLeft, const JSize fontSize, JExprRectList* rectList ) { // intialize our rectangle and midline JPoint argUpperLeft = upperLeft; JRect ourRect(upperLeft, argUpperLeft); ourRect.bottom += renderer.GetLineHeight(fontSize); JCoordinate ourMidline = (ourRect.top + ourRect.bottom)/2; const JCoordinate origMidline = ourMidline; // get rectangle for each argument const JSize opWidth = 2*(renderer.GetStringWidth(fontSize, " ") + renderer.GetVertBarWidth()); const JSize argCount = GetArgCount(); { for (JIndex i=1; i<=argCount; i++) { JFunction* arg = GetArg(i); const JIndex argIndex = arg->PrepareToRender(renderer, argUpperLeft, fontSize, rectList); JRect argRect = rectList->GetRect(argIndex); argUpperLeft.x = argRect.right + opWidth; if (ParenthesizeArgForRender(*this, *arg)) { const JSize parenWidth = renderer.GetParenthesisWidth(argRect.height()); rectList->ShiftRect(argIndex, parenWidth, 0); argRect = rectList->GetRect(argIndex); argUpperLeft.x += 2*parenWidth; ourRect.right = argRect.right + parenWidth; } ourRect = JCovering(ourRect, argRect); const JCoordinate argMidline = rectList->GetMidline(argIndex); if (argMidline > ourMidline) { ourMidline = argMidline; } } } // adjust the argument rectangles so all the midlines are the same // (ourMidline is guaranteed to stay constant) if (argCount > 1 && ourMidline > origMidline) { for (JIndex i=1; i<=argCount; i++) { const JFunction* arg = GetArg(i); JIndex argIndex; const JBoolean found = rectList->FindFunction(arg, &argIndex); assert( found ); rectList->SetMidline(argIndex, ourMidline); ourRect = JCovering(ourRect, rectList->GetRect(argIndex)); } } // save our rectangle return rectList->AddRect(ourRect, ourMidline, fontSize, this); }
JIndex JSummation::PrepareToRender ( const JExprRenderer& renderer, const JPoint& upperLeft, const JSize fontSize, JExprRectList* rectList ) { // intialize our rectangle and midline JPoint argUpperLeft = upperLeft; JRect ourRect(upperLeft, argUpperLeft); ourRect.bottom += renderer.GetLineHeight(fontSize); JCoordinate ourMidline = ourRect.ycenter(); const JCoordinate origMidline = ourMidline; // get rectangle for each argument const JSize spaceWidth = renderer.GetStringWidth(fontSize, " "); const JSize plusWidth = renderer.GetStringWidth(fontSize, JPGetAdditionString()); const JSize minusWidth = renderer.GetStringWidth(fontSize, JPGetSubtractionString()); const JSize argCount = GetArgCount(); { for (JIndex i=1; i<=argCount; i++) { JFunction* f = this; JFunction* arg = GetArg(i); if (arg->GetType() == kJNegationType) { argUpperLeft.x += minusWidth + spaceWidth; if (i > 1) { argUpperLeft.x += spaceWidth; } f = arg; JNegation* neg = dynamic_cast<JNegation*>(arg); assert( neg != NULL ); arg = neg->GetArg(); } else if (i > 1) { argUpperLeft.x += plusWidth + 2*spaceWidth; } const JIndex argIndex = arg->PrepareToRender(renderer, argUpperLeft, fontSize, rectList); JRect argRect = rectList->GetRect(argIndex); argUpperLeft.x = argRect.right; if (ParenthesizeArgForRender(*f, *arg)) { const JSize parenWidth = renderer.GetParenthesisWidth(argRect.height()); rectList->ShiftRect(argIndex, parenWidth, 0); argRect = rectList->GetRect(argIndex); argUpperLeft.x += 2*parenWidth; ourRect.right = argRect.right + parenWidth; } ourRect = JCovering(ourRect, argRect); const JCoordinate argMidline = rectList->GetMidline(argIndex); if (argMidline > ourMidline) { ourMidline = argMidline; } } } // adjust the argument rectangles so all the midlines are the same // (ourMidline is guaranteed to stay constant) if (argCount > 1 && ourMidline > origMidline) { for (JIndex i=1; i<=argCount; i++) { const JFunction* arg = GetArg(i); if (arg->GetType() == kJNegationType) { const JNegation* neg = dynamic_cast<const JNegation*>(arg); assert( neg != NULL ); arg = neg->GetArg(); } JIndex argIndex; const JBoolean found = rectList->FindFunction(arg, &argIndex); assert( found ); rectList->SetMidline(argIndex, ourMidline); ourRect = JCovering(ourRect, rectList->GetRect(argIndex)); } } // save our rectangle return rectList->AddRect(ourRect, ourMidline, fontSize, this); }