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;
		}
}
void
JLogB::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 JCharacter* name = GetName();
	const JSize nameLength = strlen(name);
	assert( nameLength > 1 );
	assert( name[ nameLength-1 ] == '(' );
	const JString fnName = JString(name, nameLength-1);
	renderer.DrawString(ourRect.left, ourMidline, fontSize, fnName);

	// draw the base

	(GetArg1())->Render(renderer, rectList);

	// draw the argument

	const JFunction* arg = GetArg2();
	arg->Render(renderer, rectList);

	JIndex argIndex;
	const JBoolean foundArg = rectList.FindFunction(arg, &argIndex);
	assert( foundArg );
	renderer.DrawParentheses(rectList.GetRect(argIndex));
}
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);
			}
		}
}