void
JFunctionWithVar::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 base name

	JString baseName, subscript;
	itsVariableList->GetVariableName(itsVariableIndex, &baseName, &subscript);
	DrawString(renderer, ourRect.left, ourMidline, fontSize, baseName);

	// draw subscript

	if (!subscript.IsEmpty())
		{
		const JCoordinate subLeft =
			ourRect.left + GetStringWidth(renderer, fontSize, baseName);
		const JSize subFontSize = renderer.GetSuperSubFontSize(fontSize);
		const JSize subHeight   = renderer.GetLineHeight(subFontSize);
		DrawString(renderer, subLeft, ourMidline + subHeight/2, subFontSize, subscript);
		}

	// draw our array index

	if (itsArrayIndex != NULL)
		{
		itsArrayIndex->Render(renderer, rectList);

		JIndex argIndex;
		const JBoolean found = rectList.FindFunction(itsArrayIndex, &argIndex);
		assert( found );
		renderer.DrawSquareBrackets(rectList.GetRect(argIndex));
		}
}
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);
}
JIndex
JFunctionWithVar::PrepareToRender
	(
	const JExprRenderer&	renderer,
	const JPoint&			upperLeft,
	const JSize				fontSize,
	JExprRectList*			rectList
	)
{
	// intialize our rectangle and midline

	JString baseName, subscript;
	itsVariableList->GetVariableName(itsVariableIndex, &baseName, &subscript);

	JRect ourRect;
	ourRect.top    = upperLeft.y;
	ourRect.left   = upperLeft.x;
	ourRect.bottom = upperLeft.y + renderer.GetLineHeight(fontSize);
	ourRect.right  = upperLeft.x + GetStringWidth(renderer, fontSize, baseName);

	JCoordinate ourMidline = ourRect.ycenter();

	// add in subscript

	if (!subscript.IsEmpty())
		{
		const JSize subFontSize     = renderer.GetSuperSubFontSize(fontSize);
		const JCoordinate subHeight = renderer.GetLineHeight(subFontSize);
		if (ourMidline + subHeight > ourRect.bottom)
			{
			ourRect.bottom = ourMidline + subHeight;
			}
		ourRect.right += GetStringWidth(renderer, subFontSize, subscript);
		}

	// add in array index

	if (itsArrayIndex != NULL)
		{
		// get rectangle for array index

		JPoint argUpperLeft(ourRect.right, ourRect.top);
		const JIndex argIndex =
			itsArrayIndex->PrepareToRender(renderer, argUpperLeft, fontSize, rectList);
		ourRect    = JCovering(ourRect, rectList->GetRect(argIndex));
		ourMidline = rectList->GetMidline(argIndex);

		// shift array index to make space for left bracket

		const JSize bracketWidth = renderer.GetSquareBracketWidth(ourRect.height());
		rectList->ShiftRect(argIndex, bracketWidth, 0);

		// we need space for two brackets

		ourRect.right += 2*bracketWidth;
		}

	// save our rectangle

	return rectList->AddRect(ourRect, ourMidline, fontSize, this);
}