Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vertical layout feature from chunlinyao/fop added, #1 #6

Open
wants to merge 13 commits into
base: 2.10.0-Metanorma
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.io.IOException;
import java.io.ObjectInputStream;

import org.apache.fop.fonts.Font;

/**
* Always (pre-) resolved page number area. Needed by BIDI code to distinguish
* from UnresolvedPageNumber.
Expand All @@ -30,8 +32,27 @@ public class ResolvedPageNumber extends TextArea {

private static final long serialVersionUID = -1758369835371647979L;

//Transient fields
transient Font font;

private boolean isVertical;

public ResolvedPageNumber(Font f, boolean v) {
font = f;
isVertical = v;
}

private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
}

@Override
public void addWord(String word, int offset, int level) {
if(isVertical) {
for(int i=0; i<word.length(); i++) {
addWord(word.substring(i, i+1), font.getFontSize(), null, null, null, offset, false, true);
}
} else
super.addWord(word, offset, level);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,24 @@ public void addWord(String word, int offset, int level) {
* or null if default level
* @param gposAdjustments array of general position adjustments or null if none apply
* @param blockProgressionOffset the offset for the next area
* @param isUpright
*/
public void addWord(String word, int ipd, int[] letterAdjust, int[] levels, int[][] gposAdjustments,
int blockProgressionOffset, boolean nextIsSpace) {
int blockProgressionOffset, boolean nextIsSpace, boolean isUpright) {
int minWordLevel = findMinLevel(levels, getBidiLevel());
WordArea wordArea = new WordArea(blockProgressionOffset, minWordLevel, word, letterAdjust, levels,
gposAdjustments, false, nextIsSpace);
wordArea.setIPD(ipd);
wordArea.setChangeBarList(getChangeBarList());
addChildArea(wordArea);
wordArea.setParentArea(this);
wordArea.setUpright(isUpright);
updateLevel(minWordLevel);
}

public void addWord(String word, int ipd, int[] letterAdjust, int[] levels, int[][] gposAdjustments,
int blockProgressionOffset) {
addWord(word, ipd, letterAdjust, levels, gposAdjustments, blockProgressionOffset, false);
addWord(word, ipd, letterAdjust, levels, gposAdjustments, blockProgressionOffset, false, false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
* This is a word area that resolves itself to a page number
* from an id reference.
*/
public class UnresolvedPageNumber extends TextArea implements Resolvable {
public class UnresolvedPageNumber extends ResolvedPageNumber implements Resolvable {


private static final long serialVersionUID = -1758090835371647980L;
Expand All @@ -48,11 +48,8 @@ public class UnresolvedPageNumber extends TextArea implements Resolvable {
/** Indicates that the reference refers to the last area generated by a formatting object. */
public static final boolean LAST = false;

//Transient fields
private transient Font font;

public UnresolvedPageNumber() {
this(null, null, FIRST);
this(null, null, FIRST, false);
}

/**
Expand All @@ -62,7 +59,7 @@ public UnresolvedPageNumber() {
* @param f the font for formatting the page number
*/
public UnresolvedPageNumber(String id, Font f) {
this(id, f, FIRST);
this(id, f, FIRST, false);
}

/**
Expand All @@ -74,8 +71,21 @@ public UnresolvedPageNumber(String id, Font f) {
* a formatting object
*/
public UnresolvedPageNumber(String id, Font f, boolean type) {
this(id, f, FIRST, false);
}

/**
* Create a new unresolved page number.
*
* @param id the id reference for resolving this
* @param f the font for formatting the page number
* @param type indicates whether the reference refers to the first or last area generated by
* a formatting object
* @param vert indicates whether the writing mode is vertical
*/
public UnresolvedPageNumber(String id, Font f, boolean type, boolean v) {
super(f, v);
pageIDRef = id;
font = f;
text = "?";
pageType = type;
}
Expand Down
19 changes: 19 additions & 0 deletions fop-core/src/main/java/org/apache/fop/area/inline/WordArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class WordArea extends InlineArea {
* its original logical order.
*/
protected boolean reversed;
protected boolean upright;
private boolean nextIsSpace;

/**
Expand Down Expand Up @@ -241,6 +242,24 @@ public boolean isNextIsSpace() {
return nextIsSpace;
}

/**
* CJK Glyph keep upright in vertical mode
*
* @return if the word should rotate to upright
*/
public boolean isUpright() {
return upright;
}

/**
* CJK Glyph keep upright in vertical mode
*
* @param upright
*/
public void setUpright(boolean upright) {
this.upright = upright;
}

/*
* If int[] array is not of specified length, then create
* a new copy of the first length entries.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,11 @@ public GlyphDefinitionTable(List subtables, Map<String, ScriptProcessor> process
* @param gpa associated glyph position adjustments (also reordered)
* @param script a script identifier
* @param language a language identifier
* @param isVertical
* @return the reordered (output) glyph sequence
*/
public GlyphSequence reorderCombiningMarks(GlyphSequence gs, int[] widths, int[][] gpa, String script, String language) {
ScriptProcessor sp = ScriptProcessor.getInstance(script, processors);
public GlyphSequence reorderCombiningMarks(GlyphSequence gs, int[] widths, int[][] gpa, String script, String language, boolean isVertical) {
ScriptProcessor sp = ScriptProcessor.getInstance(script, processors, isVertical);
return sp.reorderCombiningMarks(this, gs, widths, gpa, script, language);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,12 +230,13 @@ public static GlyphSubtable createSubtable(int type, String id, int sequence, in
* @param widths array of default advancements for each glyph
* @param adjustments accumulated adjustments array (sequence) of 4-tuples of placement [PX,PY] and advance [AX,AY] adjustments, in that order,
* with one 4-tuple for each element of glyph sequence
* @param isVertical
* @return true if some adjustment is not zero; otherwise, false
*/
public boolean position(GlyphSequence gs, String script, String language, int fontSize, int[] widths, int[][] adjustments) {
public boolean position(GlyphSequence gs, String script, String language, int fontSize, int[] widths, int[][] adjustments, boolean isVertical) {
Map<LookupSpec, List<LookupTable>> lookups = matchLookups(script, language, "*");
if ((lookups != null) && (lookups.size() > 0)) {
ScriptProcessor sp = ScriptProcessor.getInstance(script, processors);
ScriptProcessor sp = ScriptProcessor.getInstance(script, processors, isVertical);
return sp.position(this, gs, script, language, fontSize, lookups, widths, adjustments);
} else {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,23 @@ public GlyphSubstitutionTable(GlyphDefinitionTable gdef, Map lookups, List subta
* @param gs an input glyph sequence
* @param script a script identifier
* @param language a language identifier
* @param isVertical
* @return the substituted (output) glyph sequence
*/
public GlyphSequence substitute(GlyphSequence gs, String script, String language) {
public GlyphSequence substitute(GlyphSequence gs, String script, String language, boolean isVertical) {
GlyphSequence ogs;
Map<LookupSpec, List<LookupTable>> lookups = matchLookups(script, language, "*");
if ((lookups != null) && (lookups.size() > 0)) {
ScriptProcessor sp = ScriptProcessor.getInstance(script, processors);
ScriptProcessor sp = ScriptProcessor.getInstance(script, processors, isVertical);
ogs = sp.substitute(this, gs, script, language, lookups);
} else {
ogs = gs;
}
return ogs;
}

public CharSequence preProcess(CharSequence charSequence, String script, MultiByteFont font, List associations) {
ScriptProcessor scriptProcessor = ScriptProcessor.getInstance(script, processors);
public CharSequence preProcess(CharSequence charSequence, String script, MultiByteFont font, List associations, boolean isVertical) {
ScriptProcessor scriptProcessor = ScriptProcessor.getInstance(script, processors, isVertical);
return scriptProcessor.preProcess(charSequence, font, associations);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,21 @@ public interface Positionable {
* @param script a script identifier
* @param language a language identifier
* @param fontSize font size
* @param isVertical
* @return array (sequence) of 4-tuples of placement [PX,PY] and advance [AX,AY] adjustments, in that order,
* with one 4-tuple for each element of glyph sequence, or null if no non-zero adjustment applies
*/
int[][] performPositioning(CharSequence cs, String script, String language, int fontSize);
int[][] performPositioning(CharSequence cs, String script, String language, int fontSize, boolean isVertical);

/**
* Perform glyph positioning using an implied font size.
* @param cs character sequence to map to position offsets (advancement adjustments)
* @param script a script identifier
* @param language a language identifier
* @param isVertical
* @return array (sequence) of 4-tuples of placement [PX,PY] and advance [AX,AY] adjustments, in that order,
* with one 4-tuple for each element of glyph sequence, or null if no non-zero adjustment applies
*/
int[][] performPositioning(CharSequence cs, String script, String language);
int[][] performPositioning(CharSequence cs, String script, String language, boolean isVertical);

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ public interface Substitutable {
* @param language a language identifier
* @param associations optional list to receive list of character associations
* @param retainControls if true, then retain control characters and their glyph mappings, otherwise remove
* @param isVertical
* @return output sequence (represented as a character sequence, where each character in the returned sequence
* denotes "font characters", i.e., character codes that map directly (1-1) to their associated glyphs
*/
CharSequence performSubstitution(CharSequence cs, String script, String language, List associations, boolean retainControls);
CharSequence performSubstitution(CharSequence cs, String script, String language, List associations, boolean retainControls, boolean isVertical);

/**
* Reorder combining marks in character sequence so that they precede (within the sequence) the base
Expand All @@ -62,8 +63,9 @@ public interface Substitutable {
* @param script a script identifier
* @param language a language identifier
* @param associations optional list of associations to be reordered
* @param isVertical
* @return output sequence containing reordered "font characters"
*/
CharSequence reorderCombiningMarks(CharSequence cs, int[][] gpa, String script, String language, List associations);
CharSequence reorderCombiningMarks(CharSequence cs, int[][] gpa, String script, String language, List associations, boolean isVertical);

}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public GlyphContextTester getTester(String feature) {
private final ScriptContextTester posContextTester;

ArabicScriptProcessor(String script) {
super(script);
super(script, false);
this.subContextTester = new SubstitutionScriptContextTester();
this.posContextTester = new PositioningScriptContextTester();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ public class DefaultScriptProcessor extends ScriptProcessor {
"locl" // localized forms
};

/** features to use for substitutions vertical */
private static final String[] GSUB_FEATURES_V =
{
"ccmp", // glyph composition/decomposition
"liga", // common ligatures
"locl", // localized forms
"vert" // vertical writing
};

/** features to use for positioning */
private static final String[] GPOS_FEATURES =
{
Expand All @@ -50,14 +59,22 @@ public class DefaultScriptProcessor extends ScriptProcessor {
"mkmk" // mark to mark positioning
};

DefaultScriptProcessor(String script) {
/** do vert substitution.*/
private final boolean vertical;

DefaultScriptProcessor(String script, boolean vertical) {
super(script);
this.vertical = vertical;
}

@Override
/** {@inheritDoc} */
public String[] getSubstitutionFeatures() {
return GSUB_FEATURES;
if (vertical) {
return GSUB_FEATURES_V;
} else {
return GSUB_FEATURES;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;

public class HebrewScriptProcessor extends DefaultScriptProcessor {
HebrewScriptProcessor(String script) {
super(script);
HebrewScriptProcessor(String script, boolean vertical) {
super(script, vertical);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public static ScriptProcessor makeProcessor(String script) {
private final ScriptContextTester posContextTester;

IndicScriptProcessor(String script) {
super(script);
super(script, false);
this.subContextTester = new SubstitutionScriptContextTester();
this.posContextTester = new PositioningScriptContextTester();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,31 +226,33 @@ private GlyphTable.UseSpec[] assembledLookupsPut(AssembledLookupsKey key, Glyph
/**
* Obtain script processor instance associated with specified script.
* @param script a script identifier
* @param isVertical
* @return a script processor instance or null if none found
*/
public static synchronized ScriptProcessor getInstance(String script, Map<String, ScriptProcessor> processors) {
public static synchronized ScriptProcessor getInstance(String script, Map<String, ScriptProcessor> processors, boolean isVertical) {
ScriptProcessor sp = null;
assert processors != null;
if ((sp = processors.get(script)) == null) {
processors.put(script, sp = createProcessor(script));
String key = isVertical ? script + "_vert" : script;
if ((sp = processors.get(key)) == null) {
processors.put(key, sp = createProcessor(script, isVertical));
}
return sp;
}

// [TBD] - rework to provide more configurable binding between script name and script processor constructor
private static ScriptProcessor createProcessor(String script) {
private static ScriptProcessor createProcessor(String script, boolean isVertical) {
ScriptProcessor sp = null;
int sc = CharScript.scriptCodeFromTag(script);
if (sc == CharScript.SCRIPT_ARABIC) {
sp = new ArabicScriptProcessor(script);
} else if (CharScript.isIndicScript(sc)) {
sp = IndicScriptProcessor.makeProcessor(script);
} else if (sc == CharScript.SCRIPT_THAI) {
sp = new ThaiScriptProcessor(script);
sp = new ThaiScriptProcessor(script, isVertical);
} else if (sc == CharScript.SCRIPT_HEBREW) {
sp = new HebrewScriptProcessor(script);
sp = new HebrewScriptProcessor(script, isVertical);
} else {
sp = new DefaultScriptProcessor(script);
sp = new DefaultScriptProcessor(script, isVertical);
}
return sp;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;

public class ThaiScriptProcessor extends DefaultScriptProcessor {
ThaiScriptProcessor(String script) {
super(script);
ThaiScriptProcessor(String script, boolean vertical) {
super(script, vertical);
}

@Override
Expand Down
Loading