diff options
author | Simon Steiner <ssteiner@apache.org> | 2016-07-25 09:59:08 +0000 |
---|---|---|
committer | Simon Steiner <ssteiner@apache.org> | 2016-07-25 09:59:08 +0000 |
commit | 9087a4fbdff77080f7130a1e5b40760ef3226a2f (patch) | |
tree | b5c8a8cc9bae77bb7c776a82f91a19298f5886db | |
parent | bceb346d85ab15866ef899688e8087c1d8ecf136 (diff) | |
download | xmlgraphics-fop-9087a4fbdff77080f7130a1e5b40760ef3226a2f.tar.gz xmlgraphics-fop-9087a4fbdff77080f7130a1e5b40760ef3226a2f.zip |
FOP-2633: Generate bold/italic versions of fonts for PDF
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1753972 13f79535-47bb-0310-9956-ffa450edef68
28 files changed, 202 insertions, 39 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/fonts/CustomFont.java b/fop-core/src/main/java/org/apache/fop/fonts/CustomFont.java index 6f325d96d..d19f2161f 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/CustomFont.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/CustomFont.java @@ -80,6 +80,7 @@ public abstract class CustomFont extends Typeface /** the character map, mapping Unicode ranges to glyph indices. */ protected List<CMapSegment> cmap = new ArrayList<CMapSegment>(); private boolean useAdvanced = true; + private boolean simulateStyle; /** * @param resourceResolver the URI resource resolver for controlling file access @@ -490,6 +491,17 @@ public abstract class CustomFont extends Typeface this.useAdvanced = enabled; } + /** + * {@inheritDoc} + */ + public void setSimulateStyle(boolean enabled) { + this.simulateStyle = enabled; + } + + public boolean getSimulateStyle() { + return this.simulateStyle; + } + /** {@inheritDoc} */ public void putKerningEntry(Integer key, Map<Integer, Integer> value) { if (kerning == null) { diff --git a/fop-core/src/main/java/org/apache/fop/fonts/DefaultFontConfig.java b/fop-core/src/main/java/org/apache/fop/fonts/DefaultFontConfig.java index fcae13186..af162ee35 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/DefaultFontConfig.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/DefaultFontConfig.java @@ -69,6 +69,12 @@ public final class DefaultFontConfig implements FontConfig { } /** {@inheritDoc} */ + public DefaultFontConfig parse(Configuration cfg, boolean strict, + FontEventAdapter eventAdapter) throws FOPException { + return new ParserHelper(cfg, strict, eventAdapter).instance; + } + + /** {@inheritDoc} */ public FontConfig parse(Configuration cfg, FontManager fontManager, boolean strict, EventProducer eventProducer) throws FOPException { return parse(cfg, strict); @@ -81,10 +87,17 @@ public final class DefaultFontConfig implements FontConfig { private Configuration config; private Configuration fontInfoCfg; + private FontEventAdapter eventAdapter; private DefaultFontConfig instance; private ParserHelper(Configuration cfg, boolean strict) throws FOPException { + this(cfg, strict, null); + } + + private ParserHelper(Configuration cfg, boolean strict, FontEventAdapter eventAdapter) + throws FOPException { + this.eventAdapter = eventAdapter; if (cfg == null || cfg.getChild("fonts", false) == null) { instance = null; } else { @@ -118,6 +131,7 @@ public final class DefaultFontConfig implements FontConfig { fontCfg.getAttributeAsBoolean("advanced", true), fontCfg.getAttribute("encoding-mode", EncodingMode.AUTO.getName()), fontCfg.getAttribute("embedding-mode", EncodingMode.AUTO.getName()), + fontCfg.getAttributeAsBoolean("simulate-style", false), fontCfg.getAttributeAsBoolean("embed-as-type1", false)); instance.fonts.add(font); boolean hasTriplets = false; @@ -131,7 +145,12 @@ public final class DefaultFontConfig implements FontConfig { LogUtil.handleError(log, "font without font-triplet", strict); } try { - if (font.getEmbedAsType1() && !config.getAttribute("mime").equals("application/postscript")) { + if (eventAdapter != null && font.getSimulateStyle() + && !config.getAttribute("mime").equals("application/pdf")) { + eventAdapter.fontFeatureNotSuppprted(this, "simulate-style", "PDF"); + } + if (eventAdapter != null && font.getEmbedAsType1() + && !config.getAttribute("mime").equals("application/postscript")) { throw new FOPException("The embed-as-type1 attribute is only supported in postscript"); } } catch (ConfigurationException ex) { @@ -301,6 +320,7 @@ public final class DefaultFontConfig implements FontConfig { } private final boolean embedAsType1; + private final boolean simulateStyle; private final List<FontTriplet> tripletList = new ArrayList<FontTriplet>(); @@ -309,7 +329,8 @@ public final class DefaultFontConfig implements FontConfig { } private Font(String metrics, String embed, String afm, String pfm, String subFont, boolean kerning, - boolean advanced, String encodingMode, String embeddingMode, boolean embedAsType1) { + boolean advanced, String encodingMode, String embeddingMode, boolean simulateStyle, + boolean embedAsType1) { this.metrics = metrics; this.embedUri = embed; this.afm = afm; @@ -319,6 +340,7 @@ public final class DefaultFontConfig implements FontConfig { this.advanced = advanced; this.encodingMode = encodingMode; this.embeddingMode = embeddingMode; + this.simulateStyle = simulateStyle; this.embedAsType1 = embedAsType1; } @@ -370,6 +392,10 @@ public final class DefaultFontConfig implements FontConfig { return pfm; } + public boolean getSimulateStyle() { + return simulateStyle; + } + public boolean getEmbedAsType1() { return embedAsType1; } diff --git a/fop-core/src/main/java/org/apache/fop/fonts/DefaultFontConfigurator.java b/fop-core/src/main/java/org/apache/fop/fonts/DefaultFontConfigurator.java index b5fb68537..55a1dfa98 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/DefaultFontConfigurator.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/DefaultFontConfigurator.java @@ -166,8 +166,9 @@ public class DefaultFontConfigurator implements FontConfigurator<EmbedFontInfo> } EncodingMode encodingMode = EncodingMode.getValue(font.getEncodingMode()); EmbeddingMode embeddingMode = EmbeddingMode.getValue(font.getEmbeddingMode()); - EmbedFontInfo embedFontInfo = new EmbedFontInfo(fontUris, font.isKerning(), font.isAdvanced(), - tripletList, subFont, encodingMode, embeddingMode, font.getEmbedAsType1()); + EmbedFontInfo embedFontInfo = new EmbedFontInfo(fontUris, font.isKerning(), + font.isAdvanced(), tripletList, subFont, encodingMode, embeddingMode, + font.getSimulateStyle(), font.getEmbedAsType1()); if (fontCache != null) { if (!fontCache.containsFont(embedFontInfo)) { fontCache.addFont(embedFontInfo, resourceResolver); diff --git a/fop-core/src/main/java/org/apache/fop/fonts/EmbedFontInfo.java b/fop-core/src/main/java/org/apache/fop/fonts/EmbedFontInfo.java index 4ab371a14..44686c64d 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/EmbedFontInfo.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/EmbedFontInfo.java @@ -42,12 +42,14 @@ public class EmbedFontInfo implements Serializable { private final EncodingMode encodingMode; /** the requested embedding mode for this font */ private final EmbeddingMode embeddingMode; + /** simulates bold or italic on a regular font */ + private final boolean simulateStyle; + private final boolean embedAsType1; /** the PostScript name of the font */ protected String postScriptName; /** the sub-fontname of the font (used for TrueType Collections, null otherwise) */ protected String subFontName; - private boolean embedAsType1; /** the list of associated font triplets */ private List<FontTriplet> fontTriplets; @@ -67,8 +69,8 @@ public class EmbedFontInfo implements Serializable { * @param encodingMode the encoding mode to use for this font */ public EmbedFontInfo(FontUris fontUris, boolean kerning, boolean advanced, - List<FontTriplet> fontTriplets, String subFontName, - EncodingMode encodingMode, EmbeddingMode embeddingMode, boolean embedAsType1) { + List<FontTriplet> fontTriplets, String subFontName, EncodingMode encodingMode, + EmbeddingMode embeddingMode, boolean simulateStyle, boolean embedAsType1) { this.kerning = kerning; this.advanced = advanced; this.fontTriplets = fontTriplets; @@ -76,6 +78,7 @@ public class EmbedFontInfo implements Serializable { this.encodingMode = encodingMode; this.embeddingMode = embeddingMode; this.fontUris = fontUris; + this.simulateStyle = simulateStyle; this.embedAsType1 = embedAsType1; } @@ -90,7 +93,7 @@ public class EmbedFontInfo implements Serializable { public EmbedFontInfo(FontUris fontUris, boolean kerning, boolean advanced, List<FontTriplet> fontTriplets, String subFontName) { this(fontUris, kerning, advanced, fontTriplets, subFontName, EncodingMode.AUTO, - EmbeddingMode.AUTO, false); + EmbeddingMode.AUTO, false, false); } /** @@ -196,6 +199,14 @@ public class EmbedFontInfo implements Serializable { return this.encodingMode; } + /** + * Determines whether the font can simulate a style such as bold or italic. + * @return true if the font is being simulated as a different style. + */ + public boolean getSimulateStyle() { + return this.simulateStyle; + } + public boolean getEmbedAsType1() { return embedAsType1; } diff --git a/fop-core/src/main/java/org/apache/fop/fonts/FontEventAdapter.java b/fop-core/src/main/java/org/apache/fop/fonts/FontEventAdapter.java index e8078a796..b18b98b97 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/FontEventAdapter.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/FontEventAdapter.java @@ -71,4 +71,9 @@ public class FontEventAdapter implements FontEventListener { getEventProducer().svgTextStrokedAsShapes(source, fontFamily); } + /** {@inheritDoc} */ + public void fontFeatureNotSuppprted(Object source, String feature, String onlySupportedIn) { + getEventProducer().fontFeatureNotSuppprted(source, feature, onlySupportedIn); + } + } diff --git a/fop-core/src/main/java/org/apache/fop/fonts/FontEventProducer.java b/fop-core/src/main/java/org/apache/fop/fonts/FontEventProducer.java index 0cfa80425..d34af2f6b 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/FontEventProducer.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/FontEventProducer.java @@ -87,4 +87,13 @@ public interface FontEventProducer extends EventProducer { */ void svgTextStrokedAsShapes(Object source, String fontFamily); + /** + * A method to warn the user that the feature they are trying to use is not supported with either the renderer or + * other setting. + * @param source + * @param feature The feature that has caused the not supported issue + * @param onlySupportedIn The renderer / setting that this feature works with. + * @event.severity ERROR + */ + void fontFeatureNotSuppprted(Object source, String feature, String onlySupportedIn); } diff --git a/fop-core/src/main/java/org/apache/fop/fonts/FontLoader.java b/fop-core/src/main/java/org/apache/fop/fonts/FontLoader.java index 911dc34fb..9c11db2e0 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/FontLoader.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/FontLoader.java @@ -92,7 +92,7 @@ public abstract class FontLoader { public static CustomFont loadFont(FontUris fontUris, String subFontName, boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode, boolean useKerning, boolean useAdvanced, InternalResourceResolver resourceResolver, - boolean embedAsType1) throws IOException { + boolean simulateStyle, boolean embedAsType1) throws IOException { boolean type1 = isType1(fontUris.getEmbed()); FontLoader loader; if (type1) { @@ -104,7 +104,7 @@ public abstract class FontLoader { resourceResolver); } else { loader = new OFFontLoader(fontUris.getEmbed(), subFontName, embedded, embeddingMode, - encodingMode, useKerning, useAdvanced, resourceResolver, embedAsType1); + encodingMode, useKerning, useAdvanced, resourceResolver, simulateStyle, embedAsType1); } return loader.getFont(); } diff --git a/fop-core/src/main/java/org/apache/fop/fonts/LazyFont.java b/fop-core/src/main/java/org/apache/fop/fonts/LazyFont.java index 6e69ca761..2d32eec57 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/LazyFont.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/LazyFont.java @@ -47,6 +47,7 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable, private final boolean useKerning; private final boolean useAdvanced; + private boolean simulateStyle; private boolean embedAsType1; private final EncodingMode encodingMode; private final EmbeddingMode embeddingMode; @@ -73,6 +74,7 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable, } else { this.useAdvanced = fontInfo.getAdvanced(); } + this.simulateStyle = fontInfo.getSimulateStyle(); this.embedAsType1 = fontInfo.getEmbedAsType1(); this.encodingMode = fontInfo.getEncodingMode() != null ? fontInfo.getEncodingMode() : EncodingMode.AUTO; @@ -115,8 +117,8 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable, if (fontUris.getEmbed() == null) { throw new RuntimeException("Cannot load font. No font URIs available."); } - realFont = FontLoader.loadFont(fontUris, subFontName, embedded, - embeddingMode, encodingMode, useKerning, useAdvanced, resourceResolver, embedAsType1); + realFont = FontLoader.loadFont(fontUris, subFontName, embedded, embeddingMode, + encodingMode, useKerning, useAdvanced, resourceResolver, simulateStyle, embedAsType1); } if (realFont instanceof FontDescriptor) { realFontDescriptor = (FontDescriptor) realFont; diff --git a/fop-core/src/main/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java b/fop-core/src/main/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java index 564215911..e14bb0123 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java @@ -223,7 +223,7 @@ public class FontInfoFinder { try { OFFontLoader ttfLoader = new OFFontLoader(fontURI, fontName, true, EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useAdvanced, - resourceResolver, false); + resourceResolver, false, false); customFont = ttfLoader.getFont(); if (this.eventListener != null) { customFont.setEventListener(this.eventListener); @@ -251,7 +251,7 @@ public class FontInfoFinder { try { FontUris fontUris = new FontUris(fontURI, null); customFont = FontLoader.loadFont(fontUris, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO, - useKerning, useAdvanced, resourceResolver, false); + useKerning, useAdvanced, resourceResolver, false, false); if (this.eventListener != null) { customFont.setEventListener(this.eventListener); } diff --git a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OFFontLoader.java b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OFFontLoader.java index f36f00e19..3a4b1d771 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OFFontLoader.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OFFontLoader.java @@ -32,6 +32,7 @@ import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.fonts.CFFToType1Font; import org.apache.fop.fonts.CIDFontType; import org.apache.fop.fonts.CMapSegment; +import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.EmbeddingMode; import org.apache.fop.fonts.EncodingMode; import org.apache.fop.fonts.FontLoader; @@ -52,6 +53,7 @@ public class OFFontLoader extends FontLoader { private final String subFontName; private EncodingMode encodingMode; private EmbeddingMode embeddingMode; + private boolean simulateStyle; private boolean embedAsType1; /** @@ -60,7 +62,8 @@ public class OFFontLoader extends FontLoader { * @param resourceResolver the resource resolver for font URI resolution */ public OFFontLoader(URI fontFileURI, InternalResourceResolver resourceResolver) { - this(fontFileURI, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO, true, true, resourceResolver, false); + this(fontFileURI, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO, true, true, resourceResolver, false, + false); } /** @@ -74,14 +77,16 @@ public class OFFontLoader extends FontLoader { * @param useKerning true to enable loading kerning info if available, false to disable * @param useAdvanced true to enable loading advanced info if available, false to disable * @param resolver the FontResolver for font URI resolution + * @param simulateStyle Determines whether to simulate font styles if a font does not support those by default. */ public OFFontLoader(URI fontFileURI, String subFontName, boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode, boolean useKerning, - boolean useAdvanced, InternalResourceResolver resolver, boolean embedAsType1) { + boolean useAdvanced, InternalResourceResolver resolver, boolean simulateStyle, boolean embedAsType1) { super(fontFileURI, embedded, useKerning, useAdvanced, resolver); this.subFontName = subFontName; this.encodingMode = encodingMode; this.embeddingMode = embeddingMode; + this.simulateStyle = simulateStyle; this.embedAsType1 = embedAsType1; if (this.encodingMode == EncodingMode.AUTO) { this.encodingMode = EncodingMode.CID; //Default to CID mode for TrueType @@ -134,6 +139,7 @@ public class OFFontLoader extends FontLoader { isCid = false; } + CustomFont font; if (isCid) { if (otf instanceof OTFFile && embedAsType1) { multiFont = new CFFToType1Font(resourceResolver, embeddingMode); @@ -143,10 +149,13 @@ public class OFFontLoader extends FontLoader { multiFont.setIsOTFFile(otf instanceof OTFFile); returnFont = multiFont; multiFont.setTTCName(ttcFontName); + font = multiFont; } else { singleFont = new SingleByteFont(resourceResolver, embeddingMode); returnFont = singleFont; + font = singleFont; } + font.setSimulateStyle(simulateStyle); returnFont.setFontURI(fontFileURI); if (!otf.getEmbedFontName().equals("")) { diff --git a/fop-core/src/main/java/org/apache/fop/render/bitmap/BitmapRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/bitmap/BitmapRendererConfig.java index 828f41d34..551827fef 100644 --- a/fop-core/src/main/java/org/apache/fop/render/bitmap/BitmapRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/bitmap/BitmapRendererConfig.java @@ -29,6 +29,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; +import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.render.RendererConfig; import org.apache.fop.render.java2d.Java2DRendererConfig; import org.apache.fop.render.java2d.Java2DRendererConfig.Java2DRendererConfigParser; @@ -139,7 +140,8 @@ public class BitmapRendererConfig implements RendererConfig { public BitmapRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException { BitmapRendererConfig config = new BitmapRendererConfig(new DefaultFontConfigParser() - .parse(cfg, userAgent.validateStrictly())); + .parse(cfg, userAgent.validateStrictly(), + new FontEventAdapter(userAgent.getEventBroadcaster()))); build(config, userAgent, cfg); return config; } diff --git a/fop-core/src/main/java/org/apache/fop/render/bitmap/PNGRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/bitmap/PNGRendererConfig.java index 699faea51..26553bc69 100644 --- a/fop-core/src/main/java/org/apache/fop/render/bitmap/PNGRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/bitmap/PNGRendererConfig.java @@ -25,6 +25,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; +import org.apache.fop.fonts.FontEventAdapter; /** * The PNG renderer configuration data object. @@ -43,7 +44,8 @@ public final class PNGRendererConfig extends BitmapRendererConfig { public PNGRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException { return new PNGRendererConfig(new DefaultFontConfigParser().parse(cfg, - userAgent.validateStrictly())); + userAgent.validateStrictly(), + new FontEventAdapter(userAgent.getEventBroadcaster()))); } /** {@inheritDoc} */ diff --git a/fop-core/src/main/java/org/apache/fop/render/bitmap/TIFFRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/bitmap/TIFFRendererConfig.java index f2535d456..c8d71ba17 100644 --- a/fop-core/src/main/java/org/apache/fop/render/bitmap/TIFFRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/bitmap/TIFFRendererConfig.java @@ -30,6 +30,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; +import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.render.RendererConfigOption; import static org.apache.fop.render.bitmap.TIFFCompressionValue.PACKBITS; @@ -111,7 +112,8 @@ public final class TIFFRendererConfig extends BitmapRendererConfig { /** {@inheritDoc} */ public TIFFRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException { config = new TIFFRendererConfig(new DefaultFontConfigParser() - .parse(cfg, userAgent.validateStrictly())); + .parse(cfg, userAgent.validateStrictly(), + new FontEventAdapter(userAgent.getEventBroadcaster()))); super.build(config, userAgent, cfg); if (cfg != null) { setParam(TIFFRendererOption.COMPRESSION, diff --git a/fop-core/src/main/java/org/apache/fop/render/intermediate/IFRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/intermediate/IFRendererConfig.java index 753d9ff30..7fc7be063 100644 --- a/fop-core/src/main/java/org/apache/fop/render/intermediate/IFRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/intermediate/IFRendererConfig.java @@ -26,6 +26,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; import org.apache.fop.fonts.FontConfig; +import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.render.RendererConfig; /** @@ -52,7 +53,8 @@ public final class IFRendererConfig implements RendererConfig { public RendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException { return new IFRendererConfig(new DefaultFontConfigParser().parse(cfg, - userAgent.validateStrictly())); + userAgent.validateStrictly(), + new FontEventAdapter(userAgent.getEventBroadcaster()))); } /** {@inheritDoc} */ diff --git a/fop-core/src/main/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java b/fop-core/src/main/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java index dfa7e01de..4ad2044cb 100644 --- a/fop-core/src/main/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java +++ b/fop-core/src/main/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java @@ -87,7 +87,7 @@ public class ConfiguredFontCollection implements FontCollection { configFontInfo.getSubFontName(), true, configFontInfo.getEmbeddingMode(), configFontInfo.getEncodingMode(), configFontInfo.getKerning(), configFontInfo.getAdvanced(), resourceResolver, - configFontInfo.getEmbedAsType1()); + configFontInfo.getSimulateStyle(), configFontInfo.getEmbedAsType1()); font = new CustomFontMetricsMapper(fontMetrics); } diff --git a/fop-core/src/main/java/org/apache/fop/render/java2d/Java2DRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/java2d/Java2DRendererConfig.java index 1ed0aec96..141b61bf9 100644 --- a/fop-core/src/main/java/org/apache/fop/render/java2d/Java2DRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/java2d/Java2DRendererConfig.java @@ -27,6 +27,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; +import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.render.RendererConfig; import static org.apache.fop.render.java2d.Java2DRendererOption.JAVA2D_TRANSPARENT_PAGE_BACKGROUND; @@ -68,7 +69,8 @@ public final class Java2DRendererConfig implements RendererConfig { public Java2DRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException { Java2DRendererConfig config = new Java2DRendererConfig(new DefaultFontConfigParser() - .parse(cfg, userAgent.validateStrictly())); + .parse(cfg, userAgent.validateStrictly(), + new FontEventAdapter(userAgent.getEventBroadcaster()))); boolean value = cfg.getChild( JAVA2D_TRANSPARENT_PAGE_BACKGROUND.getName(), true).getValueAsBoolean(false); config.params.put(JAVA2D_TRANSPARENT_PAGE_BACKGROUND, value); diff --git a/fop-core/src/main/java/org/apache/fop/render/pcl/PCLRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/pcl/PCLRendererConfig.java index 05e72b00e..30429a7c5 100644 --- a/fop-core/src/main/java/org/apache/fop/render/pcl/PCLRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/pcl/PCLRendererConfig.java @@ -29,6 +29,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; +import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.render.RendererConfig; import static org.apache.fop.render.pcl.Java2DRendererOption.DISABLE_PJL; @@ -88,7 +89,8 @@ public final class PCLRendererConfig implements RendererConfig { /** {@inheritDoc} */ public PCLRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException { PCLRendererConfig config = new PCLRendererConfig(new DefaultFontConfigParser() - .parse(cfg, userAgent.validateStrictly())); + .parse(cfg, userAgent.validateStrictly(), + new FontEventAdapter(userAgent.getEventBroadcaster()))); configure(cfg, config); return config; } diff --git a/fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java b/fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java index 6bbb2fff5..c7b2879f1 100644 --- a/fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java +++ b/fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java @@ -39,6 +39,7 @@ import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.fop.ResourceEventProducer; +import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.fonts.LazyFont; @@ -458,9 +459,21 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> { PDFTextUtil textutil = generator.getTextUtil(); textutil.updateTf(fontKey, fontSize, tf.isMultiByte()); + double shear = 0; + boolean simulateStyle = tf instanceof CustomFont && ((CustomFont) tf).getSimulateStyle(); + if (simulateStyle) { + if (triplet.getWeight() == 700) { + generator.add("q\n"); + generator.add("2 Tr 0.31543 w\n"); + } + if (triplet.getStyle().equals("italic")) { + shear = 0.3333; + } + } + generator.updateCharacterSpacing(letterSpacing / 1000f); - textutil.writeTextMatrix(new AffineTransform(1, 0, 0, -1, x / 1000f, y / 1000f)); + textutil.writeTextMatrix(new AffineTransform(1, 0, shear, -1, x / 1000f, y / 1000f)); int l = text.length(); int dxl = (dx != null ? dx.length : 0); @@ -504,6 +517,9 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> { } textutil.writeTJ(); + if (simulateStyle && triplet.getWeight() == 700) { + generator.add("Q\n"); + } } private static int[] paZero = new int[4]; diff --git a/fop-core/src/main/java/org/apache/fop/render/pdf/PDFRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/pdf/PDFRendererConfig.java index 5e7447888..84ac45f40 100644 --- a/fop-core/src/main/java/org/apache/fop/render/pdf/PDFRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/pdf/PDFRendererConfig.java @@ -27,6 +27,7 @@ import java.util.Map; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,6 +36,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; +import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.pdf.PDFEncryptionParams; import org.apache.fop.pdf.PDFFilterList; import org.apache.fop.render.RendererConfig; @@ -117,8 +119,14 @@ public final class PDFRendererConfig implements RendererConfig { if (cfg != null) { configure(cfg, userAgent, strict); } - pdfConfig = new PDFRendererConfig(new DefaultFontConfigParser().parse(cfg, strict), - new PDFRendererOptionsConfig(configOptions, encryptionConfig)); + if (userAgent == null) { + pdfConfig = new PDFRendererConfig(new DefaultFontConfigParser().parse(cfg, strict), + new PDFRendererOptionsConfig(configOptions, encryptionConfig)); + } else { + pdfConfig = new PDFRendererConfig(new DefaultFontConfigParser().parse(cfg, strict, + new FontEventAdapter(userAgent.getEventBroadcaster())), + new PDFRendererOptionsConfig(configOptions, encryptionConfig)); + } } private void parseAndPut(PDFRendererOption option, Configuration cfg) { diff --git a/fop-core/src/main/java/org/apache/fop/render/ps/PSRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/ps/PSRendererConfig.java index e26be11d0..eb2b7ce42 100644 --- a/fop-core/src/main/java/org/apache/fop/render/ps/PSRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/ps/PSRendererConfig.java @@ -32,6 +32,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; +import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.render.RendererConfig; import org.apache.fop.util.LogUtil; @@ -113,7 +114,8 @@ public final class PSRendererConfig implements RendererConfig { private ParserHelper(Configuration cfg, FOUserAgent userAgent) throws ConfigurationException, FOPException { config = new PSRendererConfig(new DefaultFontConfigParser().parse(cfg, - userAgent.validateStrictly())); + userAgent.validateStrictly(), + new FontEventAdapter(userAgent.getEventBroadcaster()))); if (cfg != null) { setBoolConfigParam(cfg, AUTO_ROTATE_LANDSCAPE); setConfigParameter(LANGUAGE_LEVEL, diff --git a/fop-core/src/main/java/org/apache/fop/render/txt/TxtRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/txt/TxtRendererConfig.java index f597ee518..bd6f07c4a 100644 --- a/fop-core/src/main/java/org/apache/fop/render/txt/TxtRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/txt/TxtRendererConfig.java @@ -28,6 +28,7 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; import org.apache.fop.fonts.DefaultFontConfig; import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; +import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.render.RendererConfig; import org.apache.fop.render.RendererConfigOption; @@ -81,7 +82,7 @@ public final class TxtRendererConfig implements RendererConfig { /** {@inheritDoc} */ public TxtRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException { TxtRendererConfig config = new TxtRendererConfig(new DefaultFontConfigParser().parse(cfg, - userAgent.validateStrictly())); + userAgent.validateStrictly(), new FontEventAdapter(userAgent.getEventBroadcaster()))); if (cfg != null) { TxtRendererOption option = TxtRendererOption.ENCODING; String value = cfg.getChild(option.getName(), true).getValue(null); diff --git a/fop-core/src/main/resources/org/apache/fop/fonts/FontEventProducer.xml b/fop-core/src/main/resources/org/apache/fop/fonts/FontEventProducer.xml index d7ce27e7a..e95d94972 100644 --- a/fop-core/src/main/resources/org/apache/fop/fonts/FontEventProducer.xml +++ b/fop-core/src/main/resources/org/apache/fop/fonts/FontEventProducer.xml @@ -22,4 +22,5 @@ <message key="glyphNotAvailable">Glyph "{ch}" (0x{ch,hex}[, {ch,glyph-name}]) not available in font "{fontName}".</message> <message key="fontDirectoryNotFound">The font directory {dir} could not be found.</message> <message key="svgTextStrokedAsShapes">The SVG text for font {fontFamily} will be stroked as shapes.</message> + <message key="fontFeatureNotSuppprted">The {feature} property is only supported in {onlySupportedIn}.</message> </catalogue> diff --git a/fop-core/src/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java b/fop-core/src/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java index eb6ffa653..f692a56b4 100644 --- a/fop-core/src/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java @@ -49,7 +49,7 @@ public class DejaVuLGCSerifTestCase { File file = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); FontUris fontUris = new FontUris(file.toURI(), null); font = FontLoader.loadFont(fontUris, "", true, EmbeddingMode.AUTO, EncodingMode.AUTO, - false, false, resolver, false); + false, false, resolver, false, false); } /** diff --git a/fop-core/src/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java b/fop-core/src/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java index 9c9a0a3c5..9e0a7f1b0 100644 --- a/fop-core/src/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java @@ -53,7 +53,8 @@ public class EmbedFontInfoTestCase { List<FontTriplet> triplets = new ArrayList<FontTriplet>(); triplets.add(triplet); FontUris fontUris = new FontUris(embedURI, metricsURI); - sut = new EmbedFontInfo(fontUris, kerning, useAdvanced, triplets, subFontName, encMode, embedMode, false); + sut = new EmbedFontInfo(fontUris, kerning, useAdvanced, triplets, subFontName, encMode, + embedMode, false, false); } @Test diff --git a/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java b/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java index 52cef1820..c0a5ed721 100644 --- a/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java +++ b/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java @@ -51,7 +51,7 @@ public class OTFToType1TestCase { InternalResourceResolver rr = ResourceResolverFactory.createDefaultInternalResourceResolver( new File(".").toURI()); CustomFont realFont = FontLoader.loadFont(new FontUris(new File(s).toURI(), null), null, true, - EmbeddingMode.SUBSET, EncodingMode.AUTO, true, true, rr, true); + EmbeddingMode.SUBSET, EncodingMode.AUTO, true, true, rr, false, true); realFont.mapChar('d'); InputStream is = ((CFFToType1Font)realFont).getInputStreams().get(0); return Type1Font.createWithPFB(is); diff --git a/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java b/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java index 49002bbce..5201edba1 100644 --- a/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java @@ -50,12 +50,13 @@ public class TTFFontLoaderTestCase { boolean useKerning = true; OFFontLoader fontLoader = new OFFontLoader(absoluteFilePath, fontName, embedded, - EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resourceResolver, false); + EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useComplexScriptFeatures, + resourceResolver, false, false); assertTrue(fontLoader.getFont().hasKerningInfo()); useKerning = false; fontLoader = new OFFontLoader(absoluteFilePath, fontName, embedded, EmbeddingMode.AUTO, - EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resourceResolver, false); + EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resourceResolver, false, false); assertFalse(fontLoader.getFont().hasKerningInfo()); } } diff --git a/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java b/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java index d70c00f9e..b5c7263be 100644 --- a/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java @@ -38,9 +38,13 @@ import static org.mockito.Mockito.when; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import org.apache.fop.fo.Constants; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.fonts.MultiByteFont; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFProfile; import org.apache.fop.pdf.PDFStructElem; +import org.apache.fop.pdf.PDFTextUtil; import org.apache.fop.render.RenderingContext; import org.apache.fop.render.intermediate.IFContext; import org.apache.fop.render.intermediate.IFException; @@ -51,7 +55,7 @@ import junit.framework.Assert; public class PDFPainterTestCase { private FOUserAgent foUserAgent; - private PDFContentGenerator pdfContentGenerator; + private PDFContentGenerator pdfContentGenerator; private PDFDocumentHandler pdfDocumentHandler; private PDFPainter pdfPainter; private PDFStructElem elem = new PDFStructElem(); @@ -73,17 +77,17 @@ public class PDFPainterTestCase { verify(pdfContentGenerator, times(16)).add(endsWith(" c ")); } - private void createPDFPainter(boolean value) { - mockFOUserAgent(value); + private void createPDFPainter(boolean accessibility) { + mockFOUserAgent(accessibility); mockPDFContentGenerator(); mockPDFDocumentHandler(); PDFLogicalStructureHandler handler = mock(PDFLogicalStructureHandler.class); pdfPainter = new PDFPainter(pdfDocumentHandler, handler); } - private void mockFOUserAgent(boolean value) { + private void mockFOUserAgent(boolean accessibility) { foUserAgent = mock(FOUserAgent.class); - when(foUserAgent.isAccessibilityEnabled()).thenReturn(value); + when(foUserAgent.isAccessibilityEnabled()).thenReturn(accessibility); } private void mockPDFContentGenerator() { @@ -132,4 +136,46 @@ public class PDFPainterTestCase { return renderingContext; } } + + @Test + public void testSimulateStyle() throws IFException { + FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); + foUserAgent = fopFactory.newFOUserAgent(); + mockPDFContentGenerator(); + final StringBuilder sb = new StringBuilder(); + PDFTextUtil pdfTextUtil = new PDFTextUtil() { + protected void write(String code) { + sb.append(code); + } + protected void write(StringBuffer code) { + sb.append(code); + } + }; + pdfTextUtil.beginTextObject(); + + when(pdfContentGenerator.getTextUtil()).thenReturn(pdfTextUtil); + PDFDocumentHandler pdfDocumentHandler = new PDFDocumentHandler(new IFContext(foUserAgent)) { + PDFContentGenerator getGenerator() { + return pdfContentGenerator; + } + }; + + pdfDocumentHandler.setResult(new StreamResult(new ByteArrayOutputStream())); + pdfDocumentHandler.startDocument(); + pdfDocumentHandler.startPage(0, "", "", new Dimension()); + FontInfo fi = new FontInfo(); + fi.addFontProperties("f1", new FontTriplet("a", "italic", 700)); + MultiByteFont font = new MultiByteFont(null, null); + font.setSimulateStyle(true); + fi.addMetrics("f1", font); + pdfDocumentHandler.setFontInfo(fi); + MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, null); + pdfPainter.setFont("a", "italic", 700, null, 12, null); + pdfPainter.drawText(0, 0, 0, 0, null, "test"); + + Assert.assertEquals(sb.toString(), "BT\n/f1 0.012 Tf\n1 0 0.3333 -1 0 0 Tm [<0000000000000000>] TJ\n"); + verify(pdfContentGenerator).add("q\n"); + verify(pdfContentGenerator).add("2 Tr 0.31543 w\n"); + verify(pdfContentGenerator).add("Q\n"); + } } diff --git a/fop-core/src/test/java/org/apache/fop/svg/font/FontInfoBuilder.java b/fop-core/src/test/java/org/apache/fop/svg/font/FontInfoBuilder.java index 583d7653a..255bc19ed 100644 --- a/fop-core/src/test/java/org/apache/fop/svg/font/FontInfoBuilder.java +++ b/fop-core/src/test/java/org/apache/fop/svg/font/FontInfoBuilder.java @@ -83,7 +83,7 @@ class FontInfoBuilder { URI baseURI = new File("test/resources/fonts/ttf").toURI(); InternalResourceResolver resolver = ResourceResolverFactory.createDefaultInternalResourceResolver(baseURI); OFFontLoader fontLoader = new OFFontLoader(new URI(filename), null, true, - EmbeddingMode.AUTO, EncodingMode.AUTO, true, useAdvanced, resolver, false); + EmbeddingMode.AUTO, EncodingMode.AUTO, true, useAdvanced, resolver, false, false); FontMetrics font = fontLoader.getFont(); registerFont(font, "F" + fontKey++, fontName); return this; |