/* 
______________________________________________________________________
*
* Copyright (c) 1996-2004 QUEST SOFTWARE INC.  All Rights Reserved.
* http://java.quest.com
*
* This software is the confidential and proprietary information of
* Quest Software Inc. ("Confidential Information").  You shall not disclose
* such Confidential Information and shall use it only in accordance with the
* terms of the license agreement you entered into with Quest Software.
*
* QUEST SOFTWARE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. QUEST SOFTWARE SHALL NOT BE LIABLE FOR ANY
* DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
* ______________________________________________________________________
*/

// RCSID -- $RCSfile: GlyphVectorPCL.java,v $ $Revision: 1.2 $ $Date: 2006-03-17 21:13:25 $ $Locker:  $  Quest Software Inc.

package com.klg.jclass.page.pcl;

import java.awt.Rectangle;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Shape;

import com.klg.jclass.page.JCUnit;
import com.klg.jclass.page.GlyphVectorBase;




import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;


/**
 * Create a GlyphVector which will report metrics using
 * underlying pcl font metrics.
 */
 // It is necessary to use this class because the plain
 // Font/FontMetrics combo do not offer sufficient 
 // granularity. Their methods return int's fot ascender,
 // descender, etc. We can do better.

public class GlyphVectorPCL extends GlyphVectorBase {

/**
 * Constructor
 */
public GlyphVectorPCL(FontMetrics metrics, FontRenderContext frc, String s) {
	super(metrics, frc, s);
}

/**
 *   Returns the glyphcode of the specified glyph.
 *   This return value is meaningless to anything other
 *   than a <code>Font</code> object and can be used to ask the 
 *   <code>Font</code> object about the existence of ligatures and
 *   other context sensitive information.
 *   @param glyphIndex the index into this <code>GlyphVector</code>
 *   that corresponds to the glyph from which to retrieve the 
 *   glyphcode.
 *   @return the glyphcode of the glyph corresponding the the specified
 *   <code>glyphIndex</code>.
 */
public  int getGlyphCode(int glyphIndex) {
	FontPCL f 			= (FontPCL) metrics.getFont();
	char ch 			= string.charAt(glyphIndex);
	CharSetEntryPCL metric = f.getCharMetric(ch);

	return metric == null ? -1 : metric.getCode();
}

// methods associated with the GlyphVector as a whole,
// after layout.
/**
 *   Returns the logical bounds of this <code>GlyphVector</code>.
 *   This method is used when positioning this <code>GlyphVector</code> 
 *   in relation to visually adjacent <code>GlyphVector</code> objects.
 *   @return a {@link Rectangle2D} that is the logical bounds of this
 *   <code>GlyphVector</code>.
 */
public  Rectangle2D getLogicalBounds() {

	

	
	Rectangle r = new Rectangle(0, 0, 0, 0);
	
	
	if (string != null && string.length() > 0) {
		FontPCL font	= (FontPCL) metrics.getFont();
		FontMetricsPCL m = (FontMetricsPCL) metrics;
		int size		= m.getFont().getSize();
		double width	= m.stringWidth(JCUnit.POINTS, size, string);	
		double x 		= m.getLeadingSpace(JCUnit.POINTS, size, string) +
						  m.getTrailingSpace(JCUnit.POINTS, size,string);
	
		// find the highest and lowest character ascent and descent
		double ascent 	= 0;
		double descent 	= 0;
		for (int i = 0; i < string.length(); i++) {
	  		CharSetEntryPCL cse	= font.getCharMetric(string.charAt(i));
			CharacterPCL metric	= cse.getMetrics();        
			double tmpAscent	= metric.characterAscent;
			double tmpDescent	= metric.characterDescent;
			ascent 				= tmpAscent > ascent ? tmpAscent : ascent;
			descent				= tmpDescent < descent ? tmpDescent : descent;
		}
		
		// convert to points
		ascent 	= convertToDecipoints(ascent, size, font) / 10.0;
		descent	= convertToDecipoints(descent, size, font) / 10.0;
		
		// set the bounds on the rectangle
		r.setRect(x, -ascent, width, Math.abs(ascent) + Math.abs(descent) );
	}
	
	// finally return the logical bounds
	return r;
}

/* Convert to decipoints (PCL driver units) */
double convertToDecipoints(double dimension, int font_size, FontPCL font) {
	TypeFacePCL typeface = font.getTypeface();
	MetricsPCL metrics = typeface.getTypefaceMetrics();
	return((double) (dimension * font_size * 10) /
				(double) metrics.getDesignUnits());
}

	
} // end class
