
com.adobe.fontengine.inlineformatting.PDF16RichTextFormatter Maven / Gradle / Ivy
Show all versions of aem-sdk-api Show documentation
/*
*
* File: PDF16RichTextFormatter.java
*
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2004-2006 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;
import java.util.List;
import com.adobe.fontengine.font.FontException;
import com.adobe.fontengine.font.FontLoadingException;
import com.adobe.fontengine.font.InvalidFontException;
import com.adobe.fontengine.font.UnsupportedFontException;
import com.adobe.fontengine.inlineformatting.css20.CSS20Attribute;
import com.adobe.fontengine.inlineformatting.css20.CSS20FontDatabase;
import com.adobe.fontengine.inlineformatting.css20.CSS20FontSelector;
import com.adobe.fontengine.inlineformatting.css20.CSS20FontSet;
import com.adobe.fontengine.inlineformatting.css20.FamilyNameNormalizer;
import com.adobe.fontengine.inlineformatting.infontformatting.InFontFormatter;
import com.adobe.fontengine.inlineformatting.infontformatting.ZapfDingbatsEncoding;
/**
* Inline formatter for PDF 1.6 rich text form fields.
*
* The client must first pass a run corresponding to a whole paragraph to the
* {@link #preFormat} method. It can then pass fragments of the run to the
* {@link #format(AttributedRun, int, int)} or {@link #format(AttributedRun, int, int, boolean)} method.
*
*/
final public class PDF16RichTextFormatter
{
private final CSS20FontSelector cssFontSelector;
/**
* Constructor. PDF16RichTextFormatter instances are created with a provided factory
* method.
* @see com.adobe.fontengine.inlineformatting#getFormatterInstance
*/
private PDF16RichTextFormatter (CSS20FontSet fontSet) {
this.cssFontSelector = new CSS20FontSelector (fontSet);
}
/**
* Create a PDF16RichTextFormatter for formatting text.
*
*
Concurrency
*
* The PDF16RichTextFormatter instance that is returned from this method is not in general thread safe.
* @param fontSet A {@link CSS20FontSet} that has had all fonts and fallbacks fonts that are relevant to the
* caller added.
* @return A PDF16RichTextFormatter to be used for formatting text
*/
public static PDF16RichTextFormatter getFormatterInstance (CSS20FontSet fontSet) {
if (fontSet == null) {
return null; }
return new PDF16RichTextFormatter (fontSet);
}
/**
* Create a CSS20FontSet for use with a PDF16RichTextFormatter.
*
* The returned CSS20FontSet is intended to be shared among thread and documents. Optimal
* performance will be achieved by sharing them in this way.
*
* Concurrency
*
* The instance implementing the CSS20FontSet
interface that is returned from this method offers some tighter
* thread safety guarantees than that guaranteed by the CSS20FontSet
interface. It is safe
* to use the CSS20FontSet
* object for font resolution from multiple threads at one time as long as the methods which
* change the state of the CSS20FontSet
object are not called at any time that
* the PDF16RichTextFormatter
objects
* to which it has been given may be using it for font resolution. There is no mechanism
* within CSSPPDF16Formatter
or
* CSS20FontSet
to guarantee that this doesn't occur. A client program can guarantee this by modifying the
* CSS20FontSet
object fully before giving it to one or more PDF16RichTextFormatter
objects in one or more
* threads. A client program could also use some synchronization constructs of its own to guarantee this.
* This means that the addFont()
, setFallbackFonts()
, setGenericFont()
,
* and setResolutionPriority()
methods can not be called while there is any chance that the CSS20FontSet
* object may be being used for font resolution.
*
* It is also safe to copy this CSS20FontSet
object except when it is possible that it may be being modified.
* It is again the responsibility of the client to ensure that this doesn't happen.
*
* @return An empty CSS20FontSet that can be used with a PDF16RichTextFormatter
*/
static public CSS20FontSet getFontSetInstance () {
return new CSS20FontDatabase (true /*ignoreVariant*/);
}
/**
* Create a CSS20FontSet for use with a PDF16RichTextFormatter.
*
* This method allows a client to specify a
* {@link com.adobe.fontengine.inlineformatting.css20.FamilyNameNormalizer FamilyNameNormalizer} object
* that is used to modify the font family name of every {@link com.adobe.fontengine.font.Font Font} object
* added to the CSS20FontSet. It is also used to modify the font names inside of any search request.
*
* Concurrency
*
* The instance implementing the CSS20FontSet
interface that is returned from this method offers some tighter
* thread safety guarantees than that guaranteed by the CSS20FontSet
interface. It is safe
* to use the CSS20FontSet
* object for font resolution from multiple threads at one time as long as the methods which
* change the state of the CSS20FontSet
object are not called at any time that
* the PDF16RichTextFormatter
objects
* to which it has been given may be using it for font resolution. There is no mechanism
* within CSSPPDF16Formatter
or
* CSS20FontSet
to guarantee that this doesn't occur. A client program can guarantee this by modifying the
* CSS20FontSet
object fully before giving it to one or more PDF16RichTextFormatter
objects in one or more
* threads. A client program could also use some synchronization constructs of its own to guarantee this.
* This means that the addFont()
, setFallbackFonts()
, setGenericFont()
,
* and setResolutionPriority()
methods can not be called while there is any chance that the CSS20FontSet
* object may be being used for font resolution.
*
* It is also safe to copy this CSS20FontSet
object except when it is possible that it may be being modified.
* It is again the responsibility of the client to ensure that this doesn't happen.
* @param normalizer A {@link com.adobe.fontengine.inlineformatting.css20.FamilyNameNormalizer FamilyNameNormalizer}
* used for adjusting font family names.
* @return An empty CSS20FontSet that can be used with a PDF16RichTextFormatter
*/
static public CSS20FontSet getFontSetInstance (FamilyNameNormalizer normalizer) {
return new CSS20FontDatabase (normalizer, true /*ignoreVariant*/);
}
/**
* Create a copy of a CSS20FontSet for use with a PDF16RichTextFormatter.
*
* Concurrency
*
* The instance implementing the CSS20FontSet
interface that is returned from this method offers some tighter
* thread safety guarantees than that guaranteed by the CSS20FontSet
interface. It is safe
* to use the CSS20FontSet
* object for font resolution from multiple threads at one time as long as the methods which
* change the state of the CSS20FontSet
object are not called at any time that
* the PDF16RichTextFormatter
objects
* to which it has been given may be using it for font resolution. There is no mechanism
* within CSSPPDF16Formatter
or
* CSS20FontSet
to guarantee that this doesn't occur. A client program can guarantee this by modifying the
* CSS20FontSet
object fully before giving it to one or more PDF16RichTextFormatter
objects in one or more
* threads. A client program could also use some synchronization constructs of its own to guarantee this.
* This means that the addFont()
, setFallbackFonts()
, setGenericFont()
,
* and setResolutionPriority()
methods can not be called while there is any chance that the CSS20FontSet
* object may be being used for font resolution.
*
* It is also safe to copy this CSS20FontSet
object except when it is possible that it may be being modified.
* It is again the responsibility of the client to ensure that this doesn't happen.
* @param original the CSS20FontSet to copy
* @return A copy of a CSS20FontSet that can be used with a PDF16RichTextFormatter
*/
public static CSS20FontSet getFontSetInstance (CSS20FontSet original) {
if (original instanceof CSS20FontDatabase) {
return new CSS20FontDatabase ((CSS20FontDatabase) original); }
else {
return null; }
}
/**
* Preformat an {@link AttributedRun}.
*
* This method should be called on a portion of an AttributedRun
* corresponding to a whole paragraph, before the {@link #format(AttributedRun, int, int)}
* or {@link #format(AttributedRun, int, int, boolean)} method.
*
* @param run an AttributedRun that contains the text to be formatted
* @param start the index in the AttributedRun to start formatting from
* @param limit the index in the AttributedRun at which formatting should cease (one
* more than the last position that formatting should done to)
* @return The new limit of the original range in the AttributedRun after the formatting operation.
*/
public int preFormat (AttributedRun run, int start, int limit)
throws FontException, FormattingException {
limit = InFontFormatter.preFormat (run, start, limit);
return limit;
}
/**
* Format an {@link AttributedRun} by resolving the styling constraints
* to actual fonts, glyphs and positions for those glyphs.
*
* This method should be called after the {@link #preFormat} method.
*
*
* On input:
*
* - each element in the run can be either a character or a glyph, and
* this is recorded by the {@link ElementAttribute#isGlyph} attribute.
*
*
- each element must have {@link ElementAttribute#locale} set
*
*
- each element must have {@link ElementAttribute#bidiLevel} set
*
*
- each glyph element must have {@link ElementAttribute#joiningType} set
*
*
- each element must have {@link ElementAttribute#CSS20Attribute} set
*
*
- each character element can have {@link ElementAttribute#digitCase} set;
* if not set, equivalent to {@link DigitCase#DEFAULT}
*
*
- each character element can have {@link ElementAttribute#digitWidth} set;
* if not set, equivalent to {@link DigitWidth#DEFAULT}
*
*
- each interelement can have {@link InterElementAttribute#ligatureLevel} set;
* if not set, equivalent to {@link LigatureLevel#COMMON}
*
*
*
* At some point during formatting,
* {@link AttributedRun#startWorkingWithPositions startWorkingWithPositions}
* will be called on the run.
*
*
* On output:
*
* - each element in the run will be a glyph
*
*
- each element will have a placement and advance vector
*
*
- each element will have {@link ElementAttribute#font} set to the
* actual font to use
*
*
- each element will have {@link ElementAttribute#pointSize} set to
* the actual point size to use
*
*
* @param run an AttributedRun that contains the text to be formatted
* @param start the index in the AttributedRun to start formatting from
* @param limit the index in the AttributedRun at which formatting should cease (one
* more than the last position that formatting should done to)
*
* @return The new limit of the original range in the AttributedRun after the formatting operation.
* @throws UnsupportedFontException
* @throws InvalidFontException
* @throws FormattingException
* @throws FontLoadingException
*/
public int format (AttributedRun run, int start, int limit)
throws FontException, FormattingException
{
return format(run, start, limit, true /*kern*/);
}
/**
* Format an {@link AttributedRun} by resolving the styling constraints
* to actual fonts, glyphs and positions for those glyphs.
*
* This method should be called after the {@link #preFormat} method.
*
*
* On input:
*
* - each element in the run can be either a character or a glyph, and
* this is recorded by the {@link ElementAttribute#isGlyph} attribute.
*
*
- each element must have {@link ElementAttribute#locale} set
*
*
- each element must have {@link ElementAttribute#bidiLevel} set
*
*
- each glyph element must have {@link ElementAttribute#joiningType} set
*
*
- each element must have {@link ElementAttribute#CSS20Attribute} set
*
*
- each character element can have {@link ElementAttribute#digitCase} set;
* if not set, equivalent to {@link DigitCase#DEFAULT}
*
*
- each character element can have {@link ElementAttribute#digitWidth} set;
* if not set, equivalent to {@link DigitWidth#DEFAULT}
*
*
- each interelement can have {@link InterElementAttribute#ligatureLevel} set;
* if not set, equivalent to {@link LigatureLevel#COMMON}
*
*
*
* At some point during formatting,
* {@link AttributedRun#startWorkingWithPositions startWorkingWithPositions}
* will be called on the run.
*
*
* On output:
*
* - each element in the run will be a glyph
*
*
- each element will have a placement and advance vector
*
*
- each element will have {@link ElementAttribute#font} set to the
* actual font to use
*
*
- each element will have {@link ElementAttribute#pointSize} set to
* the actual point size to use
*
*
* @param run an AttributedRun that contains the text to be formatted
* @param start the index in the AttributedRun to start formatting from
* @param limit the index in the AttributedRun at which formatting should cease (one
* more than the last position that formatting should done to)
* @param shouldKern whether or not to apply kerning to the glyphs
* @return The new limit of the original range in the AttributedRun after the formatting operation.
* @throws UnsupportedFontException
* @throws InvalidFontException
* @throws FormattingException
* @throws FontLoadingException
*/
public int format (AttributedRun run, int start, int limit, boolean shouldKern)
throws FontException, FormattingException
{
//---------------------------------------------- Adobe Pi Std handling ---
int i = start;
while (i < limit) {
int attLimit = run.getSubrunLimit (i, limit, ElementAttribute.CSS20Attribute);
List familyNames = ((CSS20Attribute) run.getElementStyle(start, ElementAttribute.CSS20Attribute)).getFamilyNamesList ();
if (familyNames.size () > 0 && "Adobe Pi Std".equals (familyNames.get (0))) {
ZapfDingbatsEncoding.remap (run, i, attLimit); }
i = attLimit; }
//------------------------------------------------------------------------
limit = InFontFormatter.firstPass (run, start, limit);
limit = cssFontSelector.format (run, start, limit);
return InFontFormatter.format (run, start, limit, shouldKern);
}
}