void
JDiagBandMatrix::AddRowToRow
	(
	const JIndex	sourceIndex,
	const JFloat	scaleFactor,
	const JIndex	destIndex
	)
{
	JIndex minSrcCol = 1;
	if (sourceIndex > itsLowerBandCount)
		{
		minSrcCol = sourceIndex - itsLowerBandCount;
		}

	const JIndex maxSrcCol = JMin(sourceIndex + itsUpperBandCount, itsSize);

	JIndex minDestCol = 1;
	if (destIndex > itsLowerBandCount)
		{
		minDestCol = destIndex - itsLowerBandCount;
		}

	const JIndex maxDestCol = JMin(destIndex + itsUpperBandCount, itsSize);

	const JIndex minCol = JMax(minSrcCol, minDestCol);
	const JIndex maxCol = JMin(maxSrcCol, maxDestCol);

	for (JIndex i=minCol; i<=maxCol; i++)
		{
		SetElement(destIndex,i, GetElement(destIndex,i) +
				   scaleFactor * GetElement(sourceIndex,i));
		}
}
void
JXColorWheel::SetColor
	(
	const JPoint& pt
	)
{
	if (itsImage == NULL)
		{
		Redraw();
		}

	const JRect bounds       = GetBoundsGlobal();
	const JCoordinate max    = JMin(bounds.height(), bounds.width() - kSliderWidth - kSliderMargin);
	const JCoordinate size   = max - 2*kWheelMargin - 1;
	const JCoordinate center = size/2 + kWheelMargin;

	const JCoordinate dx = - pt.x + center;
	const JCoordinate dy = pt.y - center;

	const JFloat r = JMin(sqrt(dx*dx + dy*dy) / center, 1.0);
	const JFloat a = 0.5 + atan2(dy, dx) / (2.0 * kJPi);

	const JSize b = JRound(itsBrightnessSlider->GetValue());
	SetColor(JHSB(JRound(a * kJMaxHSBValue), JRound(r * kJMaxHSBValue), b));
}
JBoolean
PadColormap
	(
	gdImagePtr image
	)
{
	JSize colorCount = gdImageColorsTotal(image);
	if (colorCount >= kMinColorCount)
		{
		return kJFalse;
		}

	const JSize extraColorCount = kMinColorCount - colorCount;

	int x = gdImageSX(image) - extraColorCount;
	if (x < 0)
		{
		cerr << "image is too small to fit extra colors on single raster line" << endl;
		exit(1);
		}

	int y = gdImageSY(image) - 1;

	int c = gdImageGetPixel(image, x,y);
	int r = gdImageRed  (image, c);
	int g = gdImageGreen(image, c);
	int b = gdImageBlue (image, c);

	int delta = -1;
	if (r < 127 || g < 127 || b < 127)
		{
		delta = +1;
		}

	for (JIndex i=1; i<=extraColorCount; i++)
		{
		assert( x < gdImageSX(image) );

		while ((c = gdImageColorExact(image, r,g,b)) != -1)
			{
			r = JMax(0, JMin(r + delta, 255));
			g = JMax(0, JMin(g + delta, 255));
			b = JMax(0, JMin(b + delta, 255));
			}

		c = gdImageColorAllocate(image, r,g,b);
		assert( c != -1 );
		gdImageSetPixel(image, x,y, c);

		x++;
		}

	return kJTrue;
}
Example #4
0
JRect::JRect
(
    const JPoint& p1,
    const JPoint& p2
)
    :
    top    ( JMin(p1.y, p2.y)   ),
    left   ( JMin(p1.x, p2.x)   ),
    bottom ( JMax(p1.y, p2.y)+1 ),
    right  ( JMax(p1.x, p2.x)+1 )
{
}
Example #5
0
JRect
JCovering
(
    const JRect& r1,
    const JRect& r2
)
{
    JRect result;
    result.top    = JMin(r1.top,    r2.top);
    result.left   = JMin(r1.left,   r2.left);
    result.bottom = JMax(r1.bottom, r2.bottom);
    result.right  = JMax(r1.right,  r2.right);
    return result;
}
JIndexRange
JCovering
	(
	const JIndexRange& r1,
	const JIndexRange& r2
	)
{
	const JBoolean n1 = r1.IsNothing();
	const JBoolean n2 = r2.IsNothing();
	if (n1 && n2)
		{
		return JIndexRange();
		}
	else if (n1)
		{
		return r2;
		}
	else if (n2)
		{
		return r1;
		}
	else
		{
		return JIndexRange( JMin(r1.first, r2.first),
							JMax((r1.IsEmpty() ? r1.first-1 : r1.last),
								 (r2.IsEmpty() ? r2.first-1 : r2.last)) );
		}
}
Example #7
0
JPoint
JPinInRect
	(
	const JPoint&	pt,
	const JRect&	r
	)
{
	JPoint newPt = pt;

	newPt.x = JMax(newPt.x, r.left);
	newPt.x = JMin(newPt.x, (JCoordinate) (r.right-1));

	newPt.y = JMax(newPt.y, r.top);
	newPt.y = JMin(newPt.y, (JCoordinate) (r.bottom-1));

	return newPt;
}
JBoolean
JXDockDragData::ConvertData
	(
	const Atom		requestType,
	Atom*			returnType,
	unsigned char**	data,
	JSize*			dataLength,
	JSize*			bitsPerBlock
	)
	const
{
	if (requestType == (JXGetDockManager())->GetDNDMinSizeAtom())
		{
		*returnType   = XA_POINT;
		*bitsPerBlock = 16;
		*dataLength   = sizeof(XPoint);
		*data         = new unsigned char[ *dataLength ];
		if (*data != NULL)
			{
			const JPoint minSize = itsWindow->GetMinSize();
			XPoint* xpt          = (XPoint*) *data;
			xpt->x               = JMin(minSize.x, (JCoordinate) SHRT_MAX);
			xpt->y               = JMin(minSize.y, (JCoordinate) SHRT_MAX);
			return kJTrue;
			}
		}

	else if (requestType == (JXGetDockManager())->GetDNDWindowAtom())
		{
		*returnType   = XA_WINDOW;
		*bitsPerBlock = 32;
		*dataLength   = sizeof(Window);
		*data         = new unsigned char[ *dataLength ];
		if (*data != NULL)
			{
			*((Window*) *data) = itsWindow->GetXWindow();
			return kJTrue;
			}
		}

	*bitsPerBlock = 8;
	*data         = NULL;
	*dataLength   = 0;
	*returnType   = None;
	return kJFalse;
}
void
JXGC::DrawString
	(
	Drawable			drawable,
	XftDraw*			fdrawable,
	const JCoordinate	origX,
	const JCoordinate	y,
	const JCharacter*	str
	)
	const
{
	JXFontManager::XFont xfont = (itsDisplay->GetXFontManager())->GetXFontInfo(itsLastFont);

	XftColor color;
	if (xfont.type == JXFontManager::kTrueType)
		{
		JSize red, green, blue;
		itsColormap->GetRGB(itsLastColor, &red, &green, &blue);

		XRenderColor renderColor;
		renderColor.red   = red;
		renderColor.green = green;
		renderColor.blue  = blue;
		renderColor.alpha = 65535;

		XftColorAllocValue(*itsDisplay, itsDisplay->GetDefaultVisual(),
						   itsColormap->GetXColormap(), &renderColor, &color);
		}

	const JFontManager* fontMgr = itsDisplay->GetFontManager();

	const JSize length          = strlen(str);
	const JSize maxStringLength = itsDisplay->GetMaxStringLength();

	JCoordinate x = origX;
	JSize offset  = 0;
	while (offset < length)
		{
		const JSize count = JMin(length - offset, maxStringLength);

		if (xfont.type == JXFontManager::kStdType)
			{
			XDrawString(*itsDisplay, drawable, itsXGC, x,y, str + offset, count);
			}
		else
			{
			assert( xfont.type == JXFontManager::kTrueType );
			XftDrawString8(fdrawable, &color, xfont.xftrue, x,y, (FcChar8*) (str + offset), count);
			}

		if (offset + count < length)
			{
			x += fontMgr->GetStringWidth(itsLastFont, 0, JFontStyle(),
										 str + offset, count);
			}
		offset += count;
		}
}
GLUndoElementsChange::GLUndoElementsChange
	(
	GXRaggedFloatTable* 				table,
	const JPoint&						start,
	const JPoint&						end,
	const GLUndoElementsBase::UndoType	type
	)
	:
	GLUndoElementsBase(table, start, end, type)
{
	itsValues = new JPtrArray<JArray<JFloat> >(JPtrArrayT::kDeleteAll);
	assert(itsValues != NULL);

	GRaggedFloatTableData* data = GetData();

	JIndex colstart;
	JIndex colend;
	if (type == GLUndoElementsBase::kRows)
		{
		colstart 	= 1;
		colend 		= data->GetDataColCount();
		}
	else
		{
		colstart	= start.x;
		colend 		= end.x;
		}

	for (JSize i = colstart; i <= colend; i++)
		{
		JArray<JFloat>* col = new JArray<JFloat>;
		assert(col != NULL);
		itsValues->Append(col);
		
		JIndex rowstart;
		JIndex rowend;
		if (type == GLUndoElementsBase::kCols)
			{
			rowstart	= 1;
			rowend 		= data->GetDataRowCount(i);
			}
		else 
			{
			rowstart 	= start.y;
			rowend 		= JMin((JSize)end.y, data->GetDataRowCount(i));
			}
		
		for (JSize j = rowstart; j <= rowend; j++)
			{
			JFloat value;
			if (data->GetElement(j, i, &value))
				{
				col->AppendElement(value);
				}
			}
		}
}
Example #11
0
void
JTEStyler::ExtendCheckRange
	(
	const JIndex newEndIndex
	)
{
	if (itsCheckRange.last < newEndIndex)
		{
		itsCheckRange.last = JMin(newEndIndex, itsText->GetLength());
		}
}
JIntRange
JCovering
	(
	const JIntRange& r1,
	const JIntRange& r2
	)
{
	return JIntRange( JMin(r1.first, r2.first),
					  JMax((r1.IsEmpty() ? r1.first-1 : r1.last),
						   (r2.IsEmpty() ? r2.first-1 : r2.last)) );
}
JBoolean
JIntersection
	(
	const JIntRange&	r1,
	const JIntRange&	r2,
	JIntRange*			result
	)
{
	result->Set(JMax(r1.first, r2.first), JMin(r1.last,  r2.last));
	return !result->IsEmpty();
}
Example #14
0
JBoolean
JIntersection
(
    const JRect&	r1,
    const JRect&	r2,
    JRect*			result
)
{
    result->top    = JMax(r1.top,    r2.top);
    result->left   = JMax(r1.left,   r2.left);
    result->bottom = JMin(r1.bottom, r2.bottom);
    result->right  = JMin(r1.right,  r2.right);

    if (result->top < result->bottom && result->left < result->right)
    {
        return kJTrue;
    }
    else
    {
        *result = JRect(0,0,0,0);
        return kJFalse;
    }
}
Example #15
0
JSize
JXFontManager::GetStringWidth16
	(
	const JFontID		fontID,
	const JSize			size,
	const JFontStyle&	style,
	const JCharacter16*	str,
	const JSize			charCount
	)
	const
{
#ifdef _J_USE_XFT
	XftFont* xftfont = GetXftFont(fontID);
	XGlyphInfo extents;
	unsigned short test = 0x00FF;
	bool bigE = ((const char*)&test)[0] == 0x00;
	XftTextExtentsUtf16(*itsDisplay, xftfont, (XftChar8*)str, bigE ? FcEndianBig : FcEndianLittle, charCount * sizeof(JCharacter16), &extents);
	return extents.xOff;
#else
	XFontStruct* xfont = GetXFontInfo(fontID);
	if (IsMonospace(*xfont))
		{
		return charCount * xfont->min_bounds.width;
		}
	else
		{
		JString16 utf16(str, charCount);
		JString str_ascii = utf16.ToASCII();
		const JCharacter* _str = str_ascii.GetCString();
		JSize actualCount = str_ascii.GetLength();
		const JSize maxStringLength = itsDisplay->GetMaxStringLength();

		JSize width  = 0;
		JSize offset = 0;
		while (offset < actualCount)
			{
			const JSize count = JMin(actualCount - offset, maxStringLength);
			width  += XTextWidth(xfont, _str + offset, count);
			offset += count;
			}

		return width;
		}
#endif
}
Example #16
0
JSize
JXFontManager::GetStringWidth
	(
	const JFontID		fontID,
	const JSize			size,
	const JFontStyle&	style,
	const JCharacter*	str,
	const JSize			charCount
	)
	const
{
	const FontInfo info = itsFontList->GetElement(fontID);
	if (info.monoWidth > 0)
		{
		return charCount * info.monoWidth;
		}
	else
		{
		const JSize maxStringLength = itsDisplay->GetMaxStringLength();

		JSize width  = 0;
		JSize offset = 0;
		XGlyphInfo g;
		while (offset < charCount)
			{
			const JSize count = JMin(charCount - offset, maxStringLength);

			if (info.xfont.type == kStdType)
				{
				width += XTextWidth(info.xfont.xfstd, str + offset, count);
				}
			else
				{
				assert( info.xfont.type == kTrueType );
				XftTextExtents8(*itsDisplay, info.xfont.xftrue, (FcChar8*) (str + offset), count, &g);
				width += g.xOff;
				}

			offset += count;
			}

		return width;
		}
}
void
JXGC::DrawLines
	(
	const Drawable	drawable,
	const JSize		ptCount,
	XPoint			xpt[]
	)
	const
{
	const JSize kMaxPointCount = 1 + (XMaxRequestSize(*itsDisplay) - 3) / 2;

	JSize offset = 0;
	while (offset < ptCount-1)
		{
		const JSize count = JMin(ptCount - offset, kMaxPointCount);
		XDrawLines(*itsDisplay, drawable, itsXGC, &(xpt[offset]), count, CoordModeOrigin);
		offset += count - 1;
		}
}
JOrderedSetT::CompareResult
JXComposeRuleList::CompareRulesWithPrefix
	(
	const Rule&	r1,
	const Rule&	r2,
	JBoolean*	r1IsPrefixOfr2
	)
{
	*r1IsPrefixOfr2 = kJFalse;

	const JSize c1 = (r1.inputSeq)->GetElementCount();
	const JSize c2 = (r2.inputSeq)->GetElementCount();

	const JSize count = JMin(c1, c2);
	for (JIndex i=1; i<=count; i++)
		{
		const KeySym ks1 = (r1.inputSeq)->GetElement(i);
		const KeySym ks2 = (r2.inputSeq)->GetElement(i);

		if (ks1 < ks2)
			{
			return JOrderedSetT::kFirstLessSecond;
			}
		else if (ks1 > ks2)
			{
			return JOrderedSetT::kFirstGreaterSecond;
			}
		}

	if (c1 < c2)
		{
		*r1IsPrefixOfr2 = kJTrue;
		return JOrderedSetT::kFirstLessSecond;
		}
	else if (c1 > c2)
		{
		return JOrderedSetT::kFirstGreaterSecond;
		}
	else
		{
		return JOrderedSetT::kFirstEqualSecond;
		}
}
JPlotFunctionBase::JPlotFunctionBase
(
    const Type		type,
    J2DPlotWidget*	plot,
    const JFloat	xMin,
    const JFloat	xMax
)
    :
    JPlotDataBase(type)
{
    itsPlot = plot;
    itsXMin = JMin(xMin, xMax);
    itsXMax = JMax(xMin, xMax);

    itsValues = new JArray<Point>(kDefSampleCount);
    assert( itsValues != NULL );

    ListenTo(itsPlot);
}
void
JDiagBandMatrix::ScaleRow
	(
	const JIndex	rowIndex,
	const JFloat	scaleFactor
	)
{
	JIndex minCol = 1;
	if (rowIndex > itsLowerBandCount)
		{
		minCol = rowIndex - itsLowerBandCount;
		}

	const JIndex maxCol = JMin(rowIndex + itsUpperBandCount, itsSize);

	for (JIndex i=minCol; i<=maxCol; i++)
		{
		SetElement(rowIndex,i, scaleFactor * GetElement(rowIndex,i));
		}
}
JBoolean
JIntersection
	(
	const JIndexRange&	r1,
	const JIndexRange&	r2,
	JIndexRange*		result
	)
{
	const JIndex min = JMax(r1.first, r2.first);
	const JIndex max = JMin(r1.last,  r2.last);
	if (max >= min)
		{
		result->Set(min, max);
		return kJTrue;
		}
	else
		{
		result->SetToNothing();
		return kJFalse;
		}
}
Example #22
0
JSize
JXFontManager::GetStringWidth
	(
	const JFontID		fontID,
	const JSize			size,
	const JFontStyle&	style,
	const JCharacter*	str,
	const JSize			charCount
	)
	const
{
#ifdef _J_USE_XFT
	XftFont* xftfont = GetXftFont(fontID);
	XGlyphInfo extents;
	//XftTextExtents8(*itsDisplay, xftfont, (XftChar8*)str, charCount, &extents);
	XftTextExtentsUtf8(*itsDisplay, xftfont, (XftChar8*)str, charCount, &extents);
	return extents.xOff;
#else
	XFontStruct* xfont = GetXFontInfo(fontID);
	if (IsMonospace(*xfont))
		{
		return charCount * xfont->min_bounds.width;
		}
	else
		{
		const JSize maxStringLength = itsDisplay->GetMaxStringLength();

		JSize width  = 0;
		JSize offset = 0;
		while (offset < charCount)
			{
			const JSize count = JMin(charCount - offset, maxStringLength);
			width  += XTextWidth(xfont, str + offset, count);
			offset += count;
			}

		return width;
		}
#endif
}
void
CBEditStylerDialog::BuildWindow
	(
	const JCharacter*						windowTitle,
	const JBoolean							active,
	const JCharacter**						typeNames,
	const JArray<JFontStyle>&				typeStyles,
	const JArray<CBStylerBase::WordStyle>&	wordList,
	const CBTextFileType					fileType
	)
{
// begin JXLayout

	JXWindow* window = new JXWindow(this, 370,390, "");
	assert( window != NULL );

	JXScrollbarSet* scrollbarSet1 =
		new JXScrollbarSet(window,
					JXWidget::kHElastic, JXWidget::kVElastic, 20,110, 240,110);
	assert( scrollbarSet1 != NULL );

	JXTextButton* cancelButton =
		new JXTextButton(JGetString("cancelButton::CBEditStylerDialog::JXLayout"), window,
					JXWidget::kFixedLeft, JXWidget::kFixedBottom, 40,360, 70,20);
	assert( cancelButton != NULL );

	JXTextButton* okButton =
		new JXTextButton(JGetString("okButton::CBEditStylerDialog::JXLayout"), window,
					JXWidget::kFixedLeft, JXWidget::kFixedBottom, 250,360, 70,20);
	assert( okButton != NULL );

	JXStaticText* instrText =
		new JXStaticText(JGetString("instrText::CBEditStylerDialog::JXLayout"), window,
					JXWidget::kFixedLeft, JXWidget::kFixedTop, 20,50, 330,50);
	assert( instrText != NULL );

	JXTextButton* newWordButton =
		new JXTextButton(JGetString("newWordButton::CBEditStylerDialog::JXLayout"), window,
					JXWidget::kFixedRight, JXWidget::kFixedBottom, 280,240, 70,20);
	assert( newWordButton != NULL );
	newWordButton->SetShortcuts(JGetString("newWordButton::CBEditStylerDialog::shortcuts::JXLayout"));

	JXTextButton* removeButton =
		new JXTextButton(JGetString("removeButton::CBEditStylerDialog::JXLayout"), window,
					JXWidget::kFixedRight, JXWidget::kFixedBottom, 280,270, 70,20);
	assert( removeButton != NULL );
	removeButton->SetShortcuts(JGetString("removeButton::CBEditStylerDialog::shortcuts::JXLayout"));

	JXScrollbarSet* scrollbarSet2 =
		new JXScrollbarSet(window,
					JXWidget::kFixedLeft, JXWidget::kFixedBottom, 20,230, 240,110);
	assert( scrollbarSet2 != NULL );

	itsActiveCB =
		new JXTextCheckbox(JGetString("itsActiveCB::CBEditStylerDialog::JXLayout"), window,
					JXWidget::kFixedLeft, JXWidget::kFixedTop, 80,15, 220,20);
	assert( itsActiveCB != NULL );

	itsHelpButton =
		new JXTextButton(JGetString("itsHelpButton::CBEditStylerDialog::JXLayout"), window,
					JXWidget::kFixedLeft, JXWidget::kFixedBottom, 145,360, 70,20);
	assert( itsHelpButton != NULL );
	itsHelpButton->SetShortcuts(JGetString("itsHelpButton::CBEditStylerDialog::shortcuts::JXLayout"));

// end JXLayout

	window->SetTitle(windowTitle);
	SetButtons(okButton, cancelButton);

	itsActiveCB->SetState(active);
	instrText->SetText(JGetString(kInstructionsID));
	ListenTo(itsHelpButton);

	// create tables

	itsTypeTable =
		new CBStylerTable(typeNames, typeStyles, scrollbarSet1,
						  scrollbarSet1->GetScrollEnclosure(),
						  JXWidget::kHElastic, JXWidget::kVElastic, 0,0, 10,10);
	assert( itsTypeTable != NULL );
	itsTypeTable->FitToEnclosure();

	itsWordTable =
		new CBStylerTable(fileType, wordList, newWordButton, removeButton,
						  scrollbarSet2, scrollbarSet2->GetScrollEnclosure(),
						  JXWidget::kHElastic, JXWidget::kVElastic, 0,0, 10,10);
	assert( itsWordTable != NULL );
	itsWordTable->FitToEnclosure();

	// adjust window size

	JCoordinate rowBorderWidth;
	JColorIndex rowBorderColor;
	itsTypeTable->GetRowBorderInfo(&rowBorderWidth, &rowBorderColor);

	const JCoordinate bdh =
		JMin(itsTypeTable->GetBoundsHeight(),
			 kMaxTypeRowCount * itsTypeTable->GetDefaultRowHeight() +
			 (kMaxTypeRowCount-1) * rowBorderWidth);
	const JCoordinate aph = itsTypeTable->GetApertureHeight();
	window->AdjustSize(0, bdh - aph);

	scrollbarSet1->SetSizing(JXWidget::kHElastic, JXWidget::kFixedTop);
	scrollbarSet2->SetSizing(JXWidget::kHElastic, JXWidget::kVElastic);

	okButton->SetSizing(JXWidget::kFixedLeft, JXWidget::kFixedBottom);
	cancelButton->SetSizing(JXWidget::kFixedLeft, JXWidget::kFixedBottom);
	itsHelpButton->SetSizing(JXWidget::kFixedLeft, JXWidget::kFixedBottom);

	newWordButton->SetSizing(JXWidget::kFixedRight, JXWidget::kFixedTop);
	removeButton->SetSizing(JXWidget::kFixedRight, JXWidget::kFixedTop);

	UseModalPlacement(kJFalse);
	window->PlaceAsDialogWindow();
	window->LockCurrentMinSize();
}
void
JParseArgsForExec
	(
	const JCharacter*	cmd,
	JPtrArray<JString>*	argList
	)
{
	assert( !JStringEmpty(cmd) );

	argList->CleanOut();

	const JSize length = strlen(cmd);

	JIndex i = 0, j = i;
	while (i < length)
		{
		if (isspace(cmd[i]) || cmd[i] == ';')
			{
			if (j < i)
				{
				JString* s = new JString(cmd+j, i-j);
				assert( s != NULL );
				JCleanArg(s);	// clean out backslashes and quotes
				argList->Append(s);
				}
			if (cmd[i] == ';')
				{
				argList->Append(";");
				}
			i++;
			j = i;
			}
		else if (cmd[i] == '\\')
			{
			i += 2;
			}
		else if (cmd[i] == '"' || cmd[i] == '\'')
			{
			const JCharacter c = cmd[i];
			i++;
			while (i < length)
				{
				if (cmd[i] == '\\')
					{
					i++;
					}
				else if (cmd[i] == c)
					{
					i++;
					break;
					}
				i++;
				}
			}
		else
			{
			i++;
			}
		}
	i = JMin(i, length);

	// catch last argument

	if (j < i)
		{
		JString* s = new JString(cmd+j, i-j);
		assert( s != NULL );
		JCleanArg(s);	// clean out backslashes and quotes
		argList->Append(s);
		}
/*
	JSize length = str.GetLength();
	while (length > 0)
		{
		JString* arg = NULL;

		JIndex i;
		if (str.GetFirstCharacter() == '"')
			{
			i = 2;
			while (i <= length && str.GetCharacter(i) != '"')
				{
				if (str.GetCharacter(i) == '\\')
					{
					i++;
					}
				i++;
				}

			if (i <= length)
				{
				// use JIndexRange to allow empty string: ""
				arg = new JString(str.GetSubstring(JIndexRange(2, i-1)));
				assert( arg != NULL );
				str.RemoveSubstring(1,i);
				}
			else if (length > 1)
				{
				arg = new JString(str.GetSubstring(2, length));
				assert( arg != NULL );
				str.Clear();
				}
			else
				{
				str.Clear();
				}
			}
		else if (str.LocateSubstring(" ", &i))
			{
			arg = new JString(str.GetSubstring(1, i-1));
			assert( arg != NULL );
			str.RemoveSubstring(1,i);
			}
		else
			{
			arg = new JString(str);
			assert( arg != NULL );
			str.Clear();
			}

		if (arg != NULL)
			{
			JCleanArg(arg);
			argList->Append(arg);
			}

		str.TrimWhitespace();
		length = str.GetLength();
		}
*/
}
int
main
	(
	int		argc,
	char*	argv[]
	)
{
	// parse the command line options

	JPtrArray<JString> inputFileList(JPtrArrayT::kDeleteAll);
	JString dataVarName, outputFileName, databaseFileName;
	JBoolean debug;
	GetOptions(argc, argv, &inputFileList,
			   &dataVarName, &outputFileName, &databaseFileName, &debug);

	const JSize inputCount = inputFileList.GetElementCount();

	// check mod times of input files
/*
	This doesn't work because compiling different versions of the program
	requires different sets of string files, none of which may have been
	modified in a long time.  The output file still needs to be re-built,
	however!

	time_t outputTime;
	if ((JGetModificationTime(outputFileName, &outputTime)).OK())
		{
		JBoolean changed = kJFalse;

		for (JIndex i=1; i<=inputCount; i++)
			{
			const JString* inputFileName = inputFileList.NthElement(i);
			time_t t;
			if (!(JGetModificationTime(*inputFileName, &t)).OK())
				{
				cerr << argv[0] << ":  " << *inputFileName << " does not exist" << endl;
				return 1;
				}
			else if (t >= outputTime)
				{
				changed = kJTrue;
				break;
				}
			}

		if (!changed)
			{
			return 0;
			}
		}
*/
	// process the input files

	JStringManager mgr;

	for (JIndex i=1; i<=inputCount; i++)
		{
		const JString* inputFileName = inputFileList.NthElement(i);
		if (JDirectoryExists(*inputFileName))
			{
			continue;
			}

		ifstream input(*inputFileName);
		if (!input.good())
			{
			cerr << argv[0] << ":  unable to open " << *inputFileName << endl;
			return 1;
			}
		mgr.MergeFile(input, debug);
		if (input.fail())
			{
			cerr << argv[0] << ":  error while reading " << *inputFileName << endl;
			return 1;
			}
		}

	// generate the output file

	std::ostringstream data1;
	mgr.WriteFile(data1);

	JString data1Str = data1.str();
	if (!databaseFileName.IsEmpty())
		{
		ofstream dbOutput(databaseFileName);
		data1Str.Print(dbOutput);
		}

	if (!outputFileName.IsEmpty())
		{
		JIndex i = 1;
		while (data1Str.LocateNextSubstring("\\", &i))
			{
			data1Str.ReplaceSubstring(i,i, "\\\\");
			i += 2;
			}
		i = 1;
		while (data1Str.LocateNextSubstring("\"", &i))
			{
			data1Str.ReplaceSubstring(i,i, "\\\"");
			i += 2;
			}
		i = 1;
		while (data1Str.LocateNextSubstring("\n", &i))
			{
			data1Str.ReplaceSubstring(i,i, "\\n");
			i += 2;
			}

		std::ostringstream data2;
		data2 << "#include <jTypes.h>" << endl;
		data2 << "static const JCharacter* ";
		dataVarName.Print(data2);
		data2 << "[] = {" << endl;

		// Visual C++ cannot handle file with more than 2048 characters on a line
		// and cannot compile string constant more than 2048 characters!

		const JSize l1 = data1Str.GetLength();
		for (i=0; i<l1; )
			{
			JSize l2 = JMin((JSize) 2040, l1 - i);
			while (l2 > 0 && data1Str.GetCharacter(i+l2) == '\\')
				{
				l2--;
				}
			assert( l2 > 0 );

			data2 << "\"";
			data2.write(((const char*) data1Str) + i, l2);
			data2 << "\"," << endl;

			i += l2;
			}

		data2 << "NULL };" << endl;

		// if the file won't change, don't re-write it

		const JString s2 = data2.str();
		if (JFileExists(outputFileName))
			{
			JString origData;
			JReadFile(outputFileName, &origData);
			if (origData == s2)
				{
				JUpdateCVSIgnore(outputFileName);
				return 0;
				}
			}

		// write file

		ofstream output(outputFileName);
		s2.Print(output);

		if (!output.good())
			{
			cerr << argv[0] << ":  unable to write to " << outputFileName << endl;
			return 1;
			}

		JUpdateCVSIgnore(outputFileName);
		}

	return 0;
}
void
CBCommandTable::HandleDNDDrop
	(
	const JPoint&		pt,
	const JArray<Atom>&	typeList,
	const Atom			action,
	const Time			time,
	const JXWidget*		source
	)
{
	JXSelectionManager* selMgr = GetSelectionManager();
	JXDNDManager* dndMgr       = GetDNDManager();
	const Atom selName         = dndMgr->GetDNDSelectionName();

	if (source == this && action == dndMgr->GetDNDActionMoveXAtom())
		{
		JPoint cell;
		if ((GetTableSelection()).GetSingleSelectedCell(&cell) &&
			itsDNDRowIndex != JIndex(cell.y) && itsDNDRowIndex != JIndex(cell.y)+1)
			{
			JIndex newIndex = itsDNDRowIndex;
			if (newIndex > JIndex(cell.y))
				{
				newIndex--;
				}
			newIndex = JMin(newIndex, GetRowCount());

			itsCmdList->MoveElementToIndex(cell.y, newIndex);
			MoveRow(cell.y, newIndex);
			SelectSingleCell(JPoint(1, newIndex));
			}
		}
	else if (source == this)
		{
		JPoint cell;
		if ((GetTableSelection()).GetSingleSelectedCell(&cell))
			{
			itsCmdList->InsertElementAtIndex(
				itsDNDRowIndex, (itsCmdList->GetElement(cell.y)).Copy());
			InsertRows(itsDNDRowIndex, 1);
			SelectSingleCell(JPoint(1, itsDNDRowIndex));
			}
		}
	else
		{
		Atom returnType;
		unsigned char* data;
		JSize dataLength;
		JXSelectionManager::DeleteMethod delMethod;
		if (selMgr->GetData(selName, time, itsCommandXAtom,
							&returnType, &data, &dataLength, &delMethod))
			{
			if (returnType == itsCommandXAtom)
				{
				const std::string s((char*) data, dataLength);
				std::istringstream input(s);

				CBCommandManager::CmdInfo cmdInfo =
					CBCommandManager::ReadCmdInfo(input, CBCommandManager::GetCurrentCmdInfoFileVersion());
				if (!input.fail())
					{
					const JIndex newIndex = JMax(JIndex(1), itsDNDRowIndex);
					itsCmdList->InsertElementAtIndex(newIndex, cmdInfo);
					InsertRows(newIndex, 1);
					SelectSingleCell(JPoint(1, newIndex));

					if (action == dndMgr->GetDNDActionMoveXAtom())
						{
						selMgr->SendDeleteRequest(selName, time);
						}
					}
				}

			selMgr->DeleteData(&data, delMethod);
			}
		}

	HandleDNDLeave();
}
JBoolean
Solve
	(
	const JDiagBandMatrix&	A,
	const JVector&			b,
	JVector*				x
	)
{
JIndex i;

	*x = b;

	// deal with the trivial case

	const JSize rowCount = A.GetSize();
	if (rowCount == 1)
		{
		const JFloat value = A.GetElement(1,1);
		if (value != 0.0)
			{
			*x /= value;
			return kJTrue;
			}
		else
			{
			return kJFalse;
			}
		}

	// create workspace to hold row reduction results

	JDiagBandMatrix mx = A;

	// Pass 1:  eliminate bands below the diagonal

	for (i=1; i<=rowCount; i++)
		{
		// normalize mx(i,i) to 1

		JFloat scaleFactor = mx.GetElement(i,i);
		if (scaleFactor == 0.0)
			{
			return kJFalse;
			}

		mx.ScaleRow(i, 1.0/scaleFactor);
		x->SetElement(i, x->GetElement(i) / scaleFactor);

		// wipe out lower values in the ith column in mx

		const JSize jmax = JMin(i+mx.itsLowerBandCount, rowCount);
		for (JIndex j=i+1; j<=jmax; j++)
			{
			scaleFactor = -mx.GetElement(j,i);
			if (scaleFactor != 0.0)
				{
				mx.AddRowToRow(i, scaleFactor, j);
				mx.SetElement(j,i, 0.0);				// just to be sure
				x->SetElement(j, x->GetElement(j) + scaleFactor * x->GetElement(i));
				}
			}
		}

	// Pass 2:  eliminate bands above the diagonal

	for (i=rowCount; i>=2; i--)
		{
		JSize jmin = 1;
		if (i > mx.itsUpperBandCount)
			{
			jmin = i - mx.itsUpperBandCount;
			}

		for (JIndex j=i-1; j>=jmin; j--)
			{
			JFloat scaleFactor = -mx.GetElement(j,i);
			if (scaleFactor != 0.0)
				{
				mx.AddRowToRow(i, scaleFactor, j);
				mx.SetElement(j,i, 0.0);				// just to be sure
				x->SetElement(j, x->GetElement(j) + scaleFactor * x->GetElement(i));
				}
			}
		}

	return kJTrue;
}
void
JXColorWheel::Draw
	(
	JXWindowPainter&	p,
	const JRect&		rect
	)
{
	JXColormap* colormap    = GetColormap();
	const JColorIndex black = colormap->GetBlackColor();

	const JRect bounds       = GetBoundsGlobal();
	const JCoordinate max    = JMin(bounds.height(), bounds.width() - kSliderWidth - kSliderMargin);
	const JCoordinate size   = max - 2*kWheelMargin - 1;
	const JCoordinate center = size/2 + kWheelMargin;
	if (itsImage == NULL || itsImage->GetWidth() != max || itsColor.brightness != itsLastDrawBrightness)
		{
		p.SetFilling(kJTrue);
		p.SetPenColor(black);
		p.Ellipse(kWheelMargin, kWheelMargin, size, size);
		p.SetFilling(kJFalse);

		JRect r  = bounds;
		r.bottom = r.top  + max;
		r.right  = r.left + max;

		jdelete itsImage;
		itsImage = jnew JXImage(GetDisplay(), p.GetDrawable(), r);
		assert( itsImage != NULL );

		itsLastDrawBrightness = itsColor.brightness;
		for (JCoordinate x=0; x<max; x++)
			{
			const JCoordinate dx = - x + center;

			for (JCoordinate y=0; y<max; y++)
				{
				if (itsImage->GetColor(x,y) == black)
					{
					const JCoordinate dy = y - center;
					const JFloat r = sqrt(dx*dx + dy*dy) / center;
					const JFloat a = 0.5 + atan2(dy, dx) / (2.0 * kJPi);

					JHSB color(JRound(a * kJMaxHSBValue), JRound(r * kJMaxHSBValue), itsLastDrawBrightness);
					itsImage->SetColor(x,y, colormap->JColormap::GetColor(color));
					}
				}
			}

		itsImage->ConvertToRemoteStorage();
		}

	p.JPainter::Image(*itsImage, itsImage->GetBounds(), 0,0);

	const JFloat r = (itsColor.saturation / kJMaxHSBValueF) * size/2;
	const JFloat a = ((itsColor.hue / kJMaxHSBValueF) - 0.5) * 2.0 * kJPi;

	const JCoordinate x = center - JRound(r * cos(a));
	const JCoordinate y = center + JRound(r * sin(a));

	JRect mark(y-kWheelMargin, x-kWheelMargin, y+kWheelMargin+1, x+kWheelMargin+1);

	p.SetPenColor(colormap->GetWhiteColor());
	p.SetFilling(kJTrue);
	p.JPainter::Rect(mark);
	p.SetFilling(kJFalse);
	p.SetPenColor(black);
	p.JPainter::Rect(mark);
}