</td>
<td>disabled</td>
</tr>
+ <tr>
+ <td>hyphenation-pattern</td>
+ <td>String, attribute lang, attribute country (optional)</td>
+ <td>Register a file name for the hyphenation pattern for the mentioned language and country. Language ll and country CC must both consist of two letters.</td>
+ <td>ll_CC</td>
+ </tr>
<tr>
<td>source-resolution</td>
<td>Integer, dpi</td>
<!-- default page-height and page-width, in case
value is specified as auto -->
<default-page-settings height="11in" width="8.26in"/>
+
+ <!-- Use file name nl_Bel instead of the default nl_BE -->
+ <hyphenation-pattern lang="nl" country="BE">nl_Bel</hyphenation-pattern>
<!-- etc. etc..... -->
</fop>]]></source>
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
import javax.xml.transform.Source;
/** The base URL for all hyphen URL resolutions. */
private String hyphenBase = null;
+ /**
+ * Map of configured names of hyphenation pattern file names: ll_CC => name
+ */
+ private Map/*<String,String>*/ hyphPatNames = null;
+
/**
* FOP has the ability, for some FO's, to continue processing even if the
* input XSL violates that FO's content model. This is the default
this.hyphenBase = foURIResolver.checkBaseURL(hyphenBase);
}
+ /**
+ * @return the hyphPatNames
+ */
+ public Map getHyphPatNames() {
+ return hyphPatNames;
+ }
+
+ /**
+ * @param hyphPatNames the hyphPatNames to set
+ */
+ public void setHyphPatNames(Map hyphPatNames) {
+ if (hyphPatNames == null) {
+ hyphPatNames = new HashMap();
+ }
+ this.hyphPatNames = hyphPatNames;
+ }
+
/**
* Sets the URI Resolver. It is used for resolving factory-level URIs like hyphenation
* patterns and as backup for URI resolution performed during a rendering run.
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Map;
import org.xml.sax.SAXException;
import org.apache.xmlgraphics.image.loader.util.Penalty;
import org.apache.fop.fonts.FontManagerConfigurator;
+import org.apache.fop.hyphenation.HyphenationTreeCache;
import org.apache.fop.util.LogUtil;
/**
}
}
+ /**
+ * Read configuration elements hyphenation-pattern,
+ * construct a map ll_CC => filename, and set it on the factory
+ */
+ Configuration[] hyphPatConfig = cfg.getChildren("hyphenation-pattern");
+ if (hyphPatConfig.length != 0) {
+ Map/*<String,String>*/ hyphPatNames = new HashMap/*<String,String>*/();
+ for (int i = 0; i < hyphPatConfig.length; ++i) {
+ String lang, country, filename;
+ StringBuffer error = new StringBuffer();
+ String location = hyphPatConfig[i].getLocation();
+
+ lang = hyphPatConfig[i].getAttribute("lang", null);
+ if (lang == null) {
+ addError("The lang attribute of a hyphenation-pattern configuration"
+ + " element must exist (" + location + ")", error);
+ } else if (!lang.matches("[a-zA-Z]{2}")) {
+ addError("The lang attribute of a hyphenation-pattern configuration"
+ + " element must consist of exactly two letters (" + location + ")", error);
+ }
+ lang = lang.toLowerCase();
+
+ country = hyphPatConfig[i].getAttribute("country", null);
+ if ("".equals(country)) {
+ country = null;
+ }
+ if (country != null) {
+ if (!country.matches("[a-zA-Z]{2}")) {
+ addError("The country attribute of a hyphenation-pattern configuration"
+ + " element must consist of exactly two letters (" + location + ")", error);
+ }
+ country = country.toUpperCase();
+ }
+
+ filename = hyphPatConfig[i].getValue(null);
+ if (filename == null) {
+ addError("The value of a hyphenation-pattern configuration"
+ + " element may not be empty (" + location + ")", error);
+ }
+
+ if (error.length() != 0) {
+ LogUtil.handleError(log, error.toString(), strict);
+ continue;
+ }
+
+ String llccKey = HyphenationTreeCache.constructLlccKey(lang, country);
+ hyphPatNames.put(llccKey, filename);
+ if (log.isDebugEnabled()) {
+ log.debug("Using hyphenation pattern filename " + filename
+ + " for lang=\"" + lang + "\""
+ + (country != null?", country=\"" + country + "\"":""));
+ }
+ }
+ factory.setHyphPatNames(hyphPatNames);
+ }
+
// renderer options
if (cfg.getChild("source-resolution", false) != null) {
factory.setSourceResolution(
configureImageLoading(cfg.getChild("image-loading", false), strict);
}
+ private static void addError(String message, StringBuffer error) {
+ if (error.length() != 0) {
+ error.append(". ");
+ }
+ error.append(message);
+ }
+
private void configureImageLoading(Configuration parent, boolean strict) throws FOPException {
if (parent == null) {
return;
package org.apache.fop.hyphenation;
import java.util.Hashtable;
+import java.util.Map;
import java.util.Set;
/**
* @return the HyhenationTree instance or null if it's not in the cache
*/
public HyphenationTree getHyphenationTree(String lang, String country) {
- String key = constructKey(lang, country);
+ String key = constructLlccKey(lang, country);
// first try to find it in the cache
if (hyphenTrees.containsKey(key)) {
* @param country the country (may be null or "none")
* @return the resulting key
*/
- public static String constructKey(String lang, String country) {
+ public static String constructLlccKey(String lang, String country) {
String key = lang;
// check whether the country code has been used
if (country != null && !country.equals("none")) {
return key;
}
+ /**
+ * If the user configured a hyphenation pattern file name
+ * for this (lang,country) value, return it. If not, return null.
+ * @param lang the language
+ * @param country the country (may be null or "none")
+ * @param hyphPatNames the map of user-configured hyphenation pattern file names
+ * @return the hyphenation pattern file name or null
+ */
+ public static String constructUserKey(String lang, String country, Map hyphPatNames) {
+ String userKey = null;
+ if (hyphPatNames != null) {
+ String key = constructLlccKey(lang, country);
+ key.replace('_', '-');
+ userKey = (String) hyphPatNames.get(key);
+ }
+ return userKey;
+ }
+
/**
* Cache a hyphenation tree under its key.
* @param key the key (ex. "de_CH" or "en")
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
+import java.util.Map;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
*/
public static HyphenationTree getHyphenationTree(String lang,
String country) {
- return getHyphenationTree(lang, country, null);
+ return getHyphenationTree(lang, country, null, null);
}
/**
* @return the hyphenation tree
*/
public static HyphenationTree getHyphenationTree(String lang,
- String country, HyphenationTreeResolver resolver) {
- String key = HyphenationTreeCache.constructKey(lang, country);
+ String country, HyphenationTreeResolver resolver, Map hyphPatNames) {
+ String llccKey = HyphenationTreeCache.constructLlccKey(lang, country);
HyphenationTreeCache cache = getHyphenationTreeCache();
// See if there was an error finding this hyphenation tree before
- if (cache.isMissing(key)) {
+ if (cache.isMissing(llccKey)) {
return null;
}
return hTree;
}
+ String key = HyphenationTreeCache.constructUserKey(lang, country, hyphPatNames);
+ if (key == null) {
+ key = llccKey;
+ }
if (resolver != null) {
hTree = getUserHyphenationTree(key, resolver);
}
// put it into the pattern cache
if (hTree != null) {
- cache.cache(key, hTree);
+ cache.cache(llccKey, hTree);
} else {
- log.error("Couldn't find hyphenation pattern " + key);
- cache.noteMissing(key);
+ log.error("Couldn't find hyphenation pattern " + llccKey);
+ cache.noteMissing(llccKey);
}
return hTree;
}
*/
public static Hyphenation hyphenate(String lang, String country,
HyphenationTreeResolver resolver,
+ Map hyphPatNames,
String word,
int leftMin, int rightMin) {
- HyphenationTree hTree = getHyphenationTree(lang, country, resolver);
+ HyphenationTree hTree = getHyphenationTree(lang, country, resolver, hyphPatNames);
if (hTree == null) {
return null;
}
public static Hyphenation hyphenate(String lang, String country,
String word,
int leftMin, int rightMin) {
- return hyphenate(lang, country, null, word, leftMin, rightMin);
+ return hyphenate(lang, country, null, null, word, leftMin, rightMin);
}
/**
public static Hyphenation hyphenate(String lang, // CSOK: ParameterNumber
String country,
HyphenationTreeResolver resolver,
+ Map hyphPatNames,
char[] word, int offset, int len,
int leftMin, int rightMin) {
- HyphenationTree hTree = getHyphenationTree(lang, country, resolver);
+ HyphenationTree hTree = getHyphenationTree(lang, country, resolver, hyphPatNames);
if (hTree == null) {
return null;
}
public static Hyphenation hyphenate(String lang, String country,
char[] word, int offset, int len,
int leftMin, int rightMin) {
- return hyphenate(lang, country, null, word, offset, len, leftMin, rightMin);
+ return hyphenate(lang, country, null, null, word, offset, len, leftMin, rightMin);
}
/**
= Hyphenator.hyphenate(hyphenationProperties.language.getString(),
hyphenationProperties.country.getString(),
getFObj().getUserAgent().getFactory().getHyphenationTreeResolver(),
+ getFObj().getUserAgent().getFactory().getHyphPatNames(),
sbChars.toString(),
hyphenationProperties.hyphenationRemainCharacterCount.getValue(),
hyphenationProperties.hyphenationPushCharacterCount.getValue());