
com.adobe.fontengine.inlineformatting.infontformatting.InFontFormatter Maven / Gradle / Ivy
/*
*
* File: InFontFormatter.java
*
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2004-2005 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property of
* Adobe Systems Incorporated and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe Systems
* Incorporated and its suppliers and may be covered by U.S. and Foreign
* Patents, patents in process, and are protected by trade secret or
* copyright law. Dissemination of this information or reproduction of this
* material is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*
*/
package com.adobe.fontengine.inlineformatting.infontformatting;
import java.util.HashSet;
import java.util.Set;
import com.adobe.agl.lang.UScript;
import com.adobe.fontengine.font.FontData;
import com.adobe.fontengine.font.FontLoadingException;
import com.adobe.fontengine.font.InvalidFontException;
import com.adobe.fontengine.font.UnsupportedFontException;
import com.adobe.fontengine.inlineformatting.AttributedRun;
import com.adobe.fontengine.inlineformatting.ElementAttribute;
/** Interprets the styling constraints which are implement by in-font processing. */
final public class InFontFormatter {
private InFontFormatter () {
// this class only hold static methods and data
}
private static final BaseFormatter[] scriptFormatters = new BaseFormatter [UScript.CODE_LIMIT];
private static final BaseFormatter glyphFormatter = new GlyphFormatter ();
static {
BaseFormatter genericFormatter = new GenericFormatter ();
for (int i = 0; i < scriptFormatters.length; i++) {
scriptFormatters [i] = genericFormatter; }
scriptFormatters [UScript.ARABIC] = new ArabicFormatter ();
scriptFormatters [UScript.BENGALI] = new BengaliFormatter ();
scriptFormatters [UScript.DEVANAGARI] = new DevanagariFormatter ();
scriptFormatters [UScript.GUJARATI] = new GujaratiFormatter ();
scriptFormatters [UScript.GURMUKHI] = new GurmukhiFormatter ();
scriptFormatters [UScript.HANGUL] = new HangulFormatter ();
scriptFormatters [UScript.KANNADA] = new KannadaFormatter ();
scriptFormatters [UScript.LAO] = new LaoFormatter ();
// scriptFormatters [UScript.MYANMAR] = new MyanmarFormatter ();
scriptFormatters [UScript.ORIYA] = new OriyaFormatter ();
scriptFormatters [UScript.TAMIL] = new TamilFormatter ();
scriptFormatters [UScript.TELUGU] = new TeluguFormatter ();
scriptFormatters [UScript.THAI] = new ThaiFormatter ();
scriptFormatters [UScript.TIBETAN] = new TibetanFormatter ();
BaseFormatter hanKanaFormatter = new HanKanaFormatter ();
scriptFormatters [UScript.HIRAGANA] = hanKanaFormatter;
scriptFormatters [UScript.KATAKANA] = hanKanaFormatter;
scriptFormatters [UScript.KATAKANA_OR_HIRAGANA] = hanKanaFormatter;
scriptFormatters [UScript.HAN] = hanKanaFormatter;
}
/** the resolved Unicode script of an element.
* The value is a {@link com.adobe.agl.lang.UScript}, which is neither
* INHERITED nor COMMON. */
public static final ElementAttribute scriptAttribute = new ElementAttribute ("script");
protected static final Set /**/ typographicSystem;
static {
typographicSystem = new HashSet ();
typographicSystem.add (scriptAttribute);
typographicSystem.add (ElementAttribute.locale);
typographicSystem.add (ElementAttribute.isGlyph);
}
protected static final Set /**/ fontAtts;
static {
fontAtts = new HashSet ();
fontAtts.add (ElementAttribute.font);
}
/** Set the script attribute.
*/
static void resolveScript (AttributedRun run, int first, int limit) {
int ambientScriptNumber = UScript.COMMON;
Integer ambientScript = null;
int lastToFix = first-1;
for (int i = first; i < limit; i++) {
if (run.getElementStyle (i, ElementAttribute.isGlyph) != Boolean.TRUE) {
int script = UScript.getScript (run.elementAt (i));
if (script == UScript.COMMON || script == UScript.INHERITED) {
if (ambientScript != null) {
run.setElementStyle (i, scriptAttribute, ambientScript); }
else {
lastToFix = i; }}
else {
if (script != ambientScriptNumber) {
ambientScriptNumber = script;
ambientScript = new Integer (script);
if (lastToFix != first-1) {
for (int k = first; k <= lastToFix; k++) {
run.setElementStyle (k, scriptAttribute, ambientScript); }
lastToFix = first - 1;}}
run.setElementStyle (i, scriptAttribute, ambientScript); }}}
if (lastToFix != first-1) {
for (int k = first; k <= lastToFix; k++) {
run.setElementStyle (k, scriptAttribute, new Integer (UScript.LATIN)); }}
}
public static int preFormat (AttributedRun run, int start, int limit) {
while (start < limit) {
int glyphLimit = run.getSubrunLimit (start, limit, ElementAttribute.isGlyph);
boolean isGlyph = ((Boolean) run.getElementStyle (start, ElementAttribute.isGlyph)).booleanValue ();
if (isGlyph) {
start = glyphLimit; }
else {
resolveScript (run, start, glyphLimit);
start = glyphLimit; }}
return limit;
}
public static int firstPass (AttributedRun run, int start, int limit) {
while (start < limit) {
int glyphLimit = run.getSubrunLimit (start, limit, ElementAttribute.isGlyph);
boolean isGlyph = ((Boolean) run.getElementStyle (start, ElementAttribute.isGlyph)).booleanValue ();
if (isGlyph) {
start = glyphLimit; }
else {
while (start < glyphLimit) {
int scriptLimit = run.getSubrunLimit (start, glyphLimit, scriptAttribute);
int script = ((Integer) run.getElementStyle (start, scriptAttribute)).intValue ();
int newScriptLimit = scriptFormatters [script].firstPass (run, start, scriptLimit);
start = newScriptLimit;
glyphLimit += (newScriptLimit - scriptLimit);
limit += (newScriptLimit - scriptLimit); }}}
return limit;
}
/**
* Indentify a minimum character sequence and determine if it can be rendered
* using a given font.
*
* When rendering characters, some sequences of characters should be
* considered atomic, in the sense that it is not meaningfull to break the
* rendering of those sequences across fonts. For example, a combining
* sequence can hardly be rendered by rendering separately the base and the
* combining character(s). Similarly, a Hangul jamo sequence can hardly be
* rendered by handling separately the jamos. The first step of this method is
* to identify the atomic sequence which starts at start
in the
* run, and extends at most to limit
.
*
* The second step is to determine if that atomic sequence can be rendered
* without .notdef by font
. If that is not possible, this
* method returns 0. If that is possible, this method return the number of
* characters in the atomic sequence.
*
* It may be necessary to determine the length of an atomic sequence, even
* if its rendering will produce one or more.notdef. To do this, set
* the notdefOK
parameter to true
.
*
* When this method is called, at least the element at index
* start
must be a character.
*
* This method does not modify the run. In particular, it is up to the
* caller to put the ElementAttribute.font attribute if desired.
*/
public static int canRenderWithFont (FontData font, AttributedRun run, int start, int limit)
throws InvalidFontException, UnsupportedFontException, FontLoadingException {
int script = ((Integer) run.getElementStyle (start, scriptAttribute)).intValue ();
return scriptFormatters [script].canRenderWithFont (font, run, start, limit);
}
public static int canRenderWithNotdef (AttributedRun run, int start, int limit)
throws InvalidFontException, UnsupportedFontException, FontLoadingException {
int script = ((Integer) run.getElementStyle (start, scriptAttribute)).intValue ();
return scriptFormatters [script].canRenderWithNotdef (run, start, limit);
}
/** Format the run.
*
* The run can contain a mixture of characters and glyphs; the latter are
* not changed, but are positioned.
*/
public static int format (AttributedRun run, int start, int limit, boolean shouldKern)
throws InvalidFontException, UnsupportedFontException, FontLoadingException {
while (start < limit) {
int typographicSystemLimit = run.getSubrunLimit (start, limit, typographicSystem);
int newTypographicSystemLimit;
boolean isGlyph = ((Boolean) run.getElementStyle (start, ElementAttribute.isGlyph)).booleanValue ();
if (isGlyph) {
newTypographicSystemLimit = glyphFormatter.format (run, start, typographicSystemLimit, shouldKern); }
else {
int script = ((Integer) run.getElementStyle (start, scriptAttribute)).intValue ();
newTypographicSystemLimit = scriptFormatters [script].format (run, start, typographicSystemLimit, shouldKern); }
start = newTypographicSystemLimit;
limit += (newTypographicSystemLimit - typographicSystemLimit); }
return limit;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy