All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.xfa.text.TextMeasurement Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
package com.adobe.xfa.text;

import com.adobe.xfa.font.FontInstance;
import com.adobe.xfa.ut.UnitSpan;

/**
 * @exclude from published api.
 */

public class TextMeasurement {
/**
 * An absolute measurement on the document.  Manifested as a UnitSpan
 * value.
 */
	public static final int TYPE_LENGTH = 0;
/**
 * Proportional to the font em width (normally the font height).  The
 * value is a scale factor of type double.	A value of 1 yields the em
 * width.
 */
	public static final int TYPE_EM = 1;
/**
 * Proportional to the width of the space character, but expressed as a
 * percentage in markup.  A value of 1 yields the space width, but will
 * appear in markup as "100%".
 */
	public static final int TYPE_PERCENT = 2;

	public static final int DEFAULT_PRECISION = 6;

	public final static TextMeasurement ZERO = new TextMeasurement(); 

	private final int meType;
	private final UnitSpan moLength;
	private final double mdScale;

/**
 * Default constructor.
 * The measurement is of type length, with a value of zero.
 */
	public TextMeasurement () {
		meType = TYPE_LENGTH;
		moLength = UnitSpan.ZERO;
		mdScale = 0;
	}

/**
 * Create a length type measurement, given a length value.
 * @param oLength - Initial length value to be stored in this
 * measurement.
 */
	public TextMeasurement (UnitSpan oLength) {
		meType = TYPE_LENGTH;
		moLength = (oLength == null) ? UnitSpan.ZERO : oLength;
		mdScale = 0;
	}

/**
 * Create a relative measurement.
 * @param eType - Type of the measurement.	Must be either TYPE_EM or
 * TYPE_PERCENT.
 * @param dScale - Scale factor for the measurement.  Note that for
 * percentage measurement the given value is not scaled by 100 (e.g,
 * pass 1.0 to get 100%).
 */
	public TextMeasurement (int eType, double dScale) {
		meType = eType;
		moLength = null;
		mdScale = dScale;
	}

/**
 * Determine the absolute value of this measurement.
 * 

* Used at run-time, this method returns an absolute length * corresponding to the measurement, irrespective of the measurement * type. If the measurement is of type length, it already represents an * absolute amount. Otherwise, the given font is used to scale the * relative value appropriately. * @param oFontInstance - Font instance to use to scale relative * amounts. If this is a null reference, zero is returned. If the * measurement type is percent and the font has no space character, the * measurement is treated as being of type em. * @return Resulting absolute measurement. */ public UnitSpan flatten (FontInstance oFontInstance) { if (meType == TYPE_LENGTH) { return moLength; } if (mdScale == 0) { return UnitSpan.ZERO; } assert (oFontInstance != null); UnitSpan oResult = oFontInstance.getSize(); // oResult = oResult.multiply (oFontInstance.getHorizontalScale()); // TODO: if (meType == TYPE_PERCENT) { double dWidth = oFontInstance.getDoubleCharWidth (' ', true); // TODO: vertical glyphs? if (dWidth > 0) { oResult = new UnitSpan (dWidth, UnitSpan.POINTS_1K); } } return oResult.multiply (mdScale); } /** * Determine the absolute value of this measurement in the absence of * font information. *

* This is a sort of poor person's Flatten() method. If the font * information is not available, one call call this overload, typically * with the font height. If the measurement type is relative, it * applies the scale to the given unit span. Otherwise it simply * returns the (absolute) length. * @param oBaseValue - Base unit span to apply relative scales to. * @return Resulting absolute measurement. */ public UnitSpan flatten (UnitSpan oBaseValue) { return (meType == TYPE_LENGTH) ? moLength : oBaseValue.multiply (mdScale); } /** * Return the type of this measurement object. * @return Measurement type. */ public int getType () { return meType; } /** * Return the length value for this measurement object. * @return Absolute length value of this measurement. Return value is * not predictable if the measurement type is percent or em. */ public UnitSpan getLength () { return moLength; } /** * Return the integer value of the length. * This is a convenience method for callers. Assuming that the * measurement type is length, it returns the value of the length unit * span. * @return Integer value of the length unit span if the type is length. * Otherwise, the return value is undefined. */ public int getLengthValue () { return moLength.value(); } /** * Get the scale value for relative measurements. * @return Scale value. Return value is not predictable if the * measurement type length. */ public double getScale () { return mdScale; } /** * Determine whether this measurement represents a zero value. * An absolute measurement is zero if its length is zero. A relative * measurement is zero if its scale factor is zero. * @return True if this measurement represents a zero value; false if it * does not. */ public boolean isZero () { return (meType == TYPE_LENGTH) ? (moLength.value() == 0) : (mdScale == 0); } /** * Populate this measurement from the content of a given string. * @param sValue - String value to use. This is essentially an * extension of the allowable syntax for creating unit spans. * @return True if the string was valid; false if not. If this method * returns false, the content of the measurement is not altered. */ public static TextMeasurement fromString (String sValue, int eDefaultUnits, boolean bValuePerUnit) { UnitSpan.ParseData oParseData = UnitSpan.validatingParse (sValue, eDefaultUnits, true, bValuePerUnit, true); if (oParseData == null) { return null; } if (oParseData.mbValuePerUnit) { return null; } if (oParseData.meUnits != UnitSpan.UNIT_UNKNOWN) { return new TextMeasurement (new UnitSpan (oParseData.meUnits, oParseData.mnValue)); } int eType; double dValue = oParseData.mnValue; if (oParseData.mnFraction != 0) { dValue += ((double) oParseData.mnFraction) / ((double) oParseData.mnFractionScale); } if (oParseData.mbPercent) { eType = TYPE_PERCENT; dValue /= 100; } else { if (oParseData.mcUnit2 != 0) return null; eType = TYPE_EM; char c0 = oParseData.mcUnit0; char c1 = oParseData.mcUnit1; if (((c0 != 'e') && (c0 != 'E')) || ((c1 != 'm') && (c1 != 'M'))) { return null; } } return new TextMeasurement (eType, dValue); } public static TextMeasurement fromString (String sValue, int eDefaultUnits) { return fromString (sValue, eDefaultUnits, false); } public static TextMeasurement fromString (String sValue) { return fromString (sValue, UnitSpan.UNIT_UNKNOWN, false); } /** * Generate a string from the current value of this measurement object. * @param nPrecision - (optional) Maximum number of decimal places in * the result. Default is six. * @return String value. This can be persisted and subsequently passed * to the FromString() method to populate a measurement. */ public String toString (int nPrecision) { StringBuilder sResult = new StringBuilder(); switch (meType) { case TYPE_EM: sResult.append (Units.doubleToString (mdScale, nPrecision)); sResult.append ('e'); sResult.append ('m'); break; case TYPE_PERCENT: sResult.append (Units.doubleToString (mdScale * 100, nPrecision)); sResult.append ('%'); break; default: sResult.append (moLength.text (nPrecision, true, false)); break; } return sResult.toString(); } public static boolean match (TextMeasurement m1, TextMeasurement m2) { if (m1 == m2) { return true; } if ((m1 == null) || (m2 == null)) { return false; } return m1.equals (m2); } public String toString () { return toString (DEFAULT_PRECISION); } /** * Equality comparison. *

* Two measurements are considered equal if they have the same type and * the appropriate values match (length for length types, scale for * relative types). * @param object Measurement to compare against. * @return True if the measurements are considered equal; false if not. */ public boolean equals (Object object) { if (this == object) return true; // This overrides Object.equals(boolean) directly, so... if (object == null) return false; if (object.getClass() != getClass()) return false; TextMeasurement compare = (TextMeasurement) object; if (meType != compare.meType) { return false; } if (meType == TYPE_LENGTH) { return UnitSpan.match (moLength, compare.moLength); } return mdScale == compare.mdScale; } /** * Returns a hash code value for the object. * @exclude from published api. */ public int hashCode() { int hash = Integer.valueOf(meType).hashCode(); if (meType == TYPE_LENGTH) hash = (hash * 31) ^ moLength.hashCode(); long bits = Double.doubleToLongBits(mdScale); hash = (hash * 31) ^ (int) (bits ^ (bits >>> 32)); return hash; } public static TextMeasurement zero () { return ZERO; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy