RowParameters calcRowParameters(Font f, String msg, int rowHeight, Integer fitWidth) {
		// first determine the maximum height for this font fitting in rowHeight
		RowParameters rpHeight = calculateOptimalFontHeight(f, rowHeight);

		// measure the width of the text using the previously selected height
		Object [] parts = CoffeeSaint.splitStringWithFontstyleEscapes(msg);
		int width = 0;
		String [] strings = (String [])parts[0];
		Boolean [] bold = (Boolean [])parts[1];
		Boolean [] italic = (Boolean [])parts[2];
		Boolean [] underline = (Boolean [])parts[3];
		Boolean [] ss = (Boolean [])parts[4];
		Boolean [] useTabStop = (Boolean [])parts[5];
		int tabstop = 0;
		for(int index=0; index<strings.length; index++) {
			Font cur = setFontStyle(rpHeight.getAdjustedFont(), bold[index], italic[index], ss[index], underline[index]);

			if (useTabStop[index] != null && useTabStop[index] == true && tabstop < config.getLineScrollSplitter().size())
				width = config.getLineScrollSplitter().get(tabstop++);
			width += measureTextWidth(cur, strings[index], rowHeight);
		}

		RowParameters result = rpHeight;
		result.setTextWidth(width);

                if (fitWidth != null) {
			Graphics g2 = new BufferedImage(10, rowHeight, BufferedImage.TYPE_INT_RGB).createGraphics();
			g2.setFont(f);
			FontMetrics fm = g2.getFontMetrics();
                        double shrink = (double)Math.max(0, fitWidth) / (double)width;
			double newSize = (double)rowHeight * shrink;
			double newAsc  = (double)fm.getAscent() * shrink;
			double heightDiff = (double)fm.getAscent() - newAsc;
			f = f.deriveFont((float)newSize);
			result.setAdjustedFont(f);
		}

		return result;
	}