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

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

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

import java.util.Set;
import com.adobe.fontengine.inlineformatting.ElementAttribute;
import com.adobe.fontengine.inlineformatting.InterElementAttribute;
import com.adobe.xfa.font.FontInstance;
import com.adobe.xfa.font.FontItem;

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

class AFEElement {
	private final static int STATE_INITIAL_CHAR = 0; 
	private final static int STATE_FIRST_GLYPH = 1; 
	private final static int STATE_OTHER_GLYPH = 2; 
	private final static int STATE_EMBED = 2; 

	private final AFEAttrMap mAFEAttrMap;
	private TextEmbed mEmbed; 
	private int mElement;
	private int mElementState;
	private AFEFixedAttr mFixedAttrs;
	private AFEVarAttr mVarAttrs;
	private double mXPlacement;
	private double mYPlacement;
	private double mXAdvance;
	private double mYAdvance;
	private int mMapIndex;
	private int mMapLength;
	private boolean mRunBreak;
	private boolean mInMultiple;
	private boolean mIsRTL;
	private boolean mIsGlyph;
	private boolean mAllowKerning;

	AFEElement (AFEElement source) {
		mAFEAttrMap = source.mAFEAttrMap;
		mElement = source.mElement;
		mElementState = STATE_OTHER_GLYPH;
		mFixedAttrs = source.mFixedAttrs;
		mVarAttrs = source.mVarAttrs;
		mXPlacement = source.mXPlacement;
		mYPlacement = source.mYPlacement;
		mXAdvance = source.mXAdvance;
		mYAdvance = source.mYAdvance;
		mMapIndex = source.mMapIndex;
		mMapLength = 1;				// because this is a new glyph, not an exact copy
		mInMultiple = source.mInMultiple;
		mIsRTL = source.mIsRTL;
		mIsGlyph = source.mIsGlyph;
		mAllowKerning = source.mAllowKerning;
	}

	AFEElement (TextContext context, int elementChar, int mapIndex) {
		mAFEAttrMap = context.getAFEAttrMap();
		mVarAttrs = mAFEAttrMap.getEmptyVarAttr();
		mElement = elementChar;
		mElementState = STATE_INITIAL_CHAR;
		mMapIndex = mapIndex;
		mMapLength = 1;
	}

	AFEElement (TextContext context, TextEmbed embed, int mapIndex) {
		mAFEAttrMap = context.getAFEAttrMap();
		mVarAttrs = mAFEAttrMap.getEmptyVarAttr();
		mEmbed = embed;
		mElementState = STATE_EMBED;
		mMapIndex = mapIndex;
		mMapLength = 1;
		mRunBreak = true;
	}

	void populateChar (AFEElement prevElement, DispRun dispRun, DispRun prevRun, int bidiLevel) {
		assert (mEmbed == null);
		TextAttr textAttr = dispRun.getAttr();
		TextAttr prevAttr = (prevRun == null) ? null : prevRun.getAttr();
		boolean sameAttrs = TextAttr.match (textAttr, prevAttr);
		mAllowKerning = dispRun.allowKerning();
		if (sameAttrs) {
			assert (prevElement != null);
			mFixedAttrs = prevElement.mFixedAttrs;
		} else {
			mFixedAttrs = mAFEAttrMap.mapFixedAttr (dispRun, bidiLevel);
			if ((textAttr == null) || (prevAttr == null)) {
				mRunBreak = true;
			} else if (! FontInstance.match (textAttr.fontInstance(), prevAttr.fontInstance())) {
				mRunBreak = true;
			} else if (dispRun.allowKerning() != prevRun.allowKerning()) {
				mRunBreak = true;
			}
		}
		mIsRTL = (bidiLevel & 1) != 0;
	}

	void populateEmbed (DispRun dispRun, int bidiLevel) {
		mFixedAttrs = mAFEAttrMap.mapFixedAttr (dispRun, bidiLevel);
		mRunBreak = true;
		mIsRTL = (bidiLevel & 1) != 0;
	}

	TextEmbed getEmbed () {
		return mEmbed;
	}

	float getScaledXAdvance () {
		return (mEmbed != null) ? Units.toFloat (mEmbed.width()) : ctLegacyScale (mFixedAttrs.getCTXScale(), mXAdvance);
	}

	float getScaledXPlacement () {
		return (mEmbed != null) ? 0 : ctLegacyScale (mFixedAttrs.getCTXScale(), mXPlacement);
	}

	float getScaledYAdvance () {
		return (mEmbed != null) ? 0 : ((float) (mFixedAttrs.getFontYScale() * mYAdvance));		// TODO: do CT legacy scaling?
	}

	float getScaledYPlacement () {
		return (mEmbed != null) ? 0 : ((float) (mFixedAttrs.getFontYScale() * mYPlacement));	// TODO: do CT legacy scaling?
	}

	int getMapIndex () {
		return mMapIndex;
	}

	int getMapLength () {
		return mMapLength;
	}

	void setMapLength (int mapLength) {
		mMapLength = mapLength;
	}

	boolean isInMultiple () {
		return mInMultiple;
	}

	void setInMultiple (boolean inMultiple) {
		mInMultiple = inMultiple;
	}

	boolean getRunBreak () {
		return mRunBreak;
	}

	boolean isRTL () {
		return mIsRTL;
	}

	boolean allowKerning () {
		return mAllowKerning;
	}

	AFEAttrSet getAttrSet () {
		return mFixedAttrs;
	}

	boolean matchAttr (AFEElement compare, Object attribute) {
		assert (mEmbed == null);
		if (attribute == ElementAttribute.isGlyph) {
			return mIsGlyph == compare.mIsGlyph;
		} else if (AFEAttrSet.isFixedAttr (attribute)) {
			return mFixedAttrs.matchAttr (compare.mFixedAttrs, attribute);
		} else {
			return mVarAttrs.matchAttr (compare.mVarAttrs, attribute);
		}
	}

	boolean matchAttr (AFEElement compare, @SuppressWarnings("unchecked") Set attributes) {
		assert (mEmbed == null);
		for (Object attribute : attributes) {
			if (! matchAttr (compare, attribute)) {
				return false;
			}
		}
		return true;
	}

	boolean renderByGlyphID () {
		return mElementState == STATE_OTHER_GLYPH;
	}

	void setBIDILevel (int bidiLevel) {
		mIsRTL = (bidiLevel & 1) != 0;
	}

	void adjustPlacementAndAdvance (double xPlacementDelta, double yPlacementDelta, double xAdvanceDelta, double yAdvanceDelta) {
		assert (mEmbed == null);
		mXPlacement += xPlacementDelta;
		mYPlacement -= yPlacementDelta;		// subtracted because fonts measured in normal cartesian coordinates
		mXAdvance += xAdvanceDelta;
		mYAdvance -= yAdvanceDelta;
	}

	int elementAt () {
		return mElement;
	}

	Object getElementStyle (Object attribute) {
		assert (mEmbed == null);
		if (attribute == ElementAttribute.isGlyph) {
			return Boolean.valueOf(mIsGlyph);
		} else if (AFEAttrSet.isFixedAttr(attribute)) {
			return mFixedAttrs.getAttr (attribute);
		} else {
			return mVarAttrs.getAttr (attribute);
		}
	}

	double getElementXAdvance () {
		assert (mEmbed == null);
		return mXAdvance;
	}

	double getElementXPlacement () {
		assert (mEmbed == null);
		return mXPlacement;
	}

	double getElementYAdvance () {
		assert (mEmbed == null);
		return mYAdvance;
	}

	double getElementYPlacement () {
		assert (mEmbed == null);
		return mYPlacement;
	}

	Object getInterElementStyleBefore (InterElementAttribute attribute) {
		assert (mEmbed == null);
		return getElementStyle (attribute);
	}

	void setElement (int element, boolean isComplexSet) {
		assert (mEmbed == null);
		if (isComplexSet) {
			mElementState = STATE_OTHER_GLYPH;
		} else {
			switch (mElementState) {
				case STATE_INITIAL_CHAR:
					mElementState = STATE_FIRST_GLYPH;
					FontInstance fontInstance = mFixedAttrs.getFontInstance();
					if (fontInstance != null) {
						fontInstance.mapGlyph (mElement, element);
					}
					break;
				case STATE_FIRST_GLYPH:
					mElementState = STATE_OTHER_GLYPH;
					break;
			}
		}
		mElement = element;
	}

	void setElementPlacementAndAdvance (double xPlacement, double yPlacement, double xAdvance, double yAdvance) {
		assert (mEmbed == null);
		mXPlacement = xPlacement;
		mYPlacement = -yPlacement;		// -ve because fonts measured in normal cartesian coordinates
		mXAdvance = xAdvance;
		mYAdvance = -yAdvance;
	}

	void setElementStyle (Object attribute, Object value) {
		assert (mEmbed == null);
		if (attribute == ElementAttribute.isGlyph) {
			assert (value instanceof Boolean);
			Boolean bool = (Boolean) value;
			mIsGlyph = bool.booleanValue();
		} else {
			assert (! AFEAttrSet.isFixedAttr (attribute));
			mVarAttrs = mAFEAttrMap.mapVarAttr (mVarAttrs, attribute, value);
			mVarAttrs.setAttr (attribute, value);
		}
	}

	void setInterElementStyleBefore (InterElementAttribute attribute, Object value) {
		assert (mEmbed == null);
		setElementStyle (attribute, value);
	}

	void startWorkingWithPositions () {
	}

	public String toString () {
		StringBuilder result = new StringBuilder ("Element: ");
		if (mEmbed != null) {
			result.append ("embed: (");
			result.append (mEmbed.toString());
			result.append ("), XAdvance: ");
			result.append (mEmbed.width().toString());
		} else {
			result.append (Integer.toString (mElement));
			result.append (", XPlacement: ");
			result.append (Double.toString (mXPlacement * mFixedAttrs.getFontXScale()));
			result.append (", YPlacement: ");
			result.append (Double.toString (mYPlacement * mFixedAttrs.getFontYScale()));
			result.append (", XAdvance: ");
			result.append (Double.toString (mXAdvance * mFixedAttrs.getFontXScale()));
			result.append (", YAdvance: ");
			result.append (Double.toString (mYAdvance * mFixedAttrs.getFontYScale()));
			result.append (", Attributes: (");
			result.append (mFixedAttrs.toString());
			result.append (")");
		}
		return result.toString();
	}

	private float ctLegacyScale (double emScale, double advance) {
		double result = FontItem.ctLegacyScale (emScale, advance);
		result *= mFixedAttrs.getFontSize();
		return (float) result;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy