ソースを参照

Added support for CID-keyed TrueType fonts in PostScript output


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@959012 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-1_1rc1^2
Vincent Hennebert 14年前
コミット
ebbdc63b26

バイナリ
lib/xmlgraphics-commons-1.4svn.jar ファイルの表示


+ 1
- 1
src/java/org/apache/fop/fonts/CIDFontType.java ファイルの表示

@@ -34,7 +34,7 @@ public class CIDFontType extends ValuedEnum {
/**
* CID Font Type 2 (based on TrueType format)
*/
public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 1);
public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 2);


/**

+ 7
- 6
src/java/org/apache/fop/render/ps/FontResourceCache.java ファイルの表示

@@ -42,19 +42,20 @@ class FontResourceCache {
}

/**
* Returns the PSResource for the given font key.
* Returns the PSFontResource for the given font key.
* @param key the font key ("F*")
* @return the matching PSResource
* @return the matching PSFontResource instance
*/
public PSResource getPSResourceForFontKey(String key) {
PSResource res = null;
public PSFontResource getFontResourceForFontKey(String key) {
PSFontResource res = null;
if (this.fontResources != null) {
res = (PSResource)this.fontResources.get(key);
res = (PSFontResource)this.fontResources.get(key);
} else {
this.fontResources = new java.util.HashMap();
}
if (res == null) {
res = new PSResource(PSResource.TYPE_FONT, getPostScriptNameForFontKey(key));
res = PSFontResource.createFontResource(
new PSResource(PSResource.TYPE_FONT, getPostScriptNameForFontKey(key)));
this.fontResources.put(key, res);
}
return res;

+ 57
- 0
src/java/org/apache/fop/render/ps/HexEncoder.java ファイルの表示

@@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.render.ps;

/**
* A helper class to hex-encoded representations of numbers.
*/
final class HexEncoder {

private HexEncoder() { }

/**
* Returns an hex encoding of the given number as a string of the given length,
* left-padded with zeros if necessary.
*
* @param n a number
* @param width required length of the string
* @return an hex-encoded representation of the number
*/
static String encode(int n, int width) {
char[] digits = new char[width];
for (int i = width - 1; i >= 0; i--) {
int digit = n & 0xF;
digits[i] = (char) (digit < 10 ? '0' + digit : 'A' + digit - 10);
n >>= 4;
}
return new String(digits);
}

/**
* Returns an hex encoding of the given character as a four-character string.
*
* @param c a character
* @return an hex-encoded representation of the character
*/
static String encode(char c) {
return encode(c, 4);
}

}

+ 4
- 3
src/java/org/apache/fop/render/ps/PSDocumentHandler.java ファイルの表示

@@ -200,7 +200,8 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
gen.writeDSCComment(DSCConstants.BEGIN_SETUP);
PSRenderingUtil.writeSetupCodeList(gen, setupCodeList, "SetupCode");
if (!psUtil.isOptimizeResources()) {
this.fontResources.addAll(PSFontUtils.writeFontDict(gen, fontInfo));
this.fontResources.addAll(PSFontUtils.writeFontDict(gen, fontInfo,
PSEventProducer.Provider.get(getUserAgent().getEventBroadcaster())));
} else {
gen.commentln("%FOPFontSetup"); //Place-holder, will be replaced in the second pass
}
@@ -538,8 +539,8 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
* @param key the font key ("F*")
* @return the matching PSResource
*/
protected PSResource getPSResourceForFontKey(String key) {
return this.fontResources.getPSResourceForFontKey(key);
protected PSFontResource getPSResourceForFontKey(String key) {
return this.fontResources.getFontResourceForFontKey(key);
}

/**

+ 7
- 0
src/java/org/apache/fop/render/ps/PSEventProducer.java ファイルの表示

@@ -50,4 +50,11 @@ public interface PSEventProducer extends EventProducer {
*/
void postscriptDictionaryParseError(Object source, String content, Exception e);

/**
* PostScript Level 3 features are being used.
*
* @param source the event source
* @event.severity WARN
*/
void postscriptLevel3Used(Object source);
}

+ 1
- 0
src/java/org/apache/fop/render/ps/PSEventProducer.xml ファイルの表示

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalogue xml:lang="en">
<message key="postscriptDictionaryParseError">Failed to parse dictionary string. Reason: {e}, content = "{content}"</message>
<message key="postscriptLevel3Used">PostScript Level 3 features are needed to handle this document. Please make sure that your printer supports PostScript Level 3.</message>
</catalogue>

+ 77
- 0
src/java/org/apache/fop/render/ps/PSFontResource.java ファイルの表示

@@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.render.ps;

import org.apache.xmlgraphics.ps.PSResource;
import org.apache.xmlgraphics.ps.dsc.ResourceTracker;

/**
* A DSC resource corresponding to a font. This class handles the possible other resources
* that a font may depend on. For example, a CID-keyed font depends on a CIDFont resource, a
* CMap resource, and the ProcSet CIDInit resource.
*/
abstract class PSFontResource {

static PSFontResource createFontResource(final PSResource fontResource) {
return new PSFontResource() {

String getName() {
return fontResource.getName();
}

void notifyResourceUsageOnPage(ResourceTracker resourceTracker) {
resourceTracker.notifyResourceUsageOnPage(fontResource);
}
};
}

static PSFontResource createFontResource(final PSResource fontResource,
final PSResource procsetCIDInitResource, final PSResource cmapResource,
final PSResource cidFontResource) {
return new PSFontResource() {

String getName() {
return fontResource.getName();
}

void notifyResourceUsageOnPage(ResourceTracker resourceTracker) {
resourceTracker.notifyResourceUsageOnPage(fontResource);
resourceTracker.notifyResourceUsageOnPage(procsetCIDInitResource);
resourceTracker.notifyResourceUsageOnPage(cmapResource);
resourceTracker.notifyResourceUsageOnPage(cidFontResource);
}
};
}

/**
* Returns the name of the font resource.
*
* @return the name of the font
*/
abstract String getName();

/**
* Notifies the given resource tracker of all the resources needed by this font.
*
* @param resourceTracker
*/
abstract void notifyResourceUsageOnPage(ResourceTracker resourceTracker);

}

+ 144
- 31
src/java/org/apache/fop/render/ps/PSFontUtils.java ファイルの表示

@@ -23,6 +23,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -43,11 +44,13 @@ import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream;

import org.apache.fop.fonts.Base14Font;
import org.apache.fop.fonts.CIDSubset;
import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.fonts.SingleByteEncoding;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
@@ -72,7 +75,12 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
*/
public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo)
throws IOException {
return writeFontDict(gen, fontInfo, fontInfo.getFonts(), true);
return writeFontDict(gen, fontInfo, (PSEventProducer) null);
}

public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo,
PSEventProducer eventProducer) throws IOException {
return writeFontDict(gen, fontInfo, fontInfo.getFonts(), true, eventProducer);
}

/**
@@ -87,7 +95,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
*/
public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map fonts)
throws IOException {
return writeFontDict(gen, fontInfo, fonts, false);
return writeFontDict(gen, fontInfo, fonts, false, null);
}

/**
@@ -101,7 +109,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
* @throws IOException in case of an I/O problem
*/
private static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map fonts,
boolean encodeAllCharacters) throws IOException {
boolean encodeAllCharacters, PSEventProducer eventProducer) throws IOException {
gen.commentln("%FOPBeginFontDict");

Map fontResources = new java.util.HashMap();
@@ -110,8 +118,8 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
String key = (String)iter.next();
Typeface tf = getTypeFace(fontInfo, fonts, key);
PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getFontName());
fontResources.put(key, fontRes);
embedFont(gen, tf, fontRes);
PSFontResource fontResource = embedFont(gen, tf, fontRes, eventProducer);
fontResources.put(key, fontResource);

if (tf instanceof SingleByteFont) {
SingleByteFont sbf = (SingleByteFont)tf;
@@ -191,29 +199,45 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
return tf;
}

/**
* Embeds a font in the PostScript file.
* @param gen the PostScript generator
* @param tf the font
* @param fontRes the PSResource associated with the font
* @throws IOException In case of an I/O error
*/
public static void embedFont(PSGenerator gen, Typeface tf, PSResource fontRes)
throws IOException {
private static PSFontResource embedFont(PSGenerator gen, Typeface tf, PSResource fontRes,
PSEventProducer eventProducer) throws IOException {
boolean embeddedFont = false;
FontType fontType = tf.getFontType();
if (fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE) {
PSFontResource fontResource = null;
if (fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE
|| fontType == FontType.TYPE0) {
if (tf instanceof CustomFont) {
CustomFont cf = (CustomFont)tf;
if (isEmbeddable(cf)) {
InputStream in = getInputStreamOnFont(gen, cf);
if (in != null) {
if (fontType == FontType.TYPE0) {
if (gen.embedIdentityH()) {
/*
* First CID-keyed font to be embedded; add
* %%IncludeResource: comment for ProcSet CIDInit.
*/
gen.includeProcsetCIDInitResource();
if (eventProducer != null) {
eventProducer.postscriptLevel3Used(gen);
}
}
PSResource cidFontResource = embedCIDFont(gen, (MultiByteFont) tf, in);
fontResource = PSFontResource.createFontResource(fontRes,
gen.getProcsetCIDInitResource(),
gen.getIdentityHCMapResource(),
cidFontResource);
}
gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE,
fontRes);
if (fontType == FontType.TYPE1) {
embedType1Font(gen, in);
} else {
fontResource = PSFontResource.createFontResource(fontRes);
} else if (fontType == FontType.TRUETYPE) {
embedTrueTypeFont(gen, (SingleByteFont) tf, in);
fontResource = PSFontResource.createFontResource(fontRes);
} else {
embedType0Font(gen, (MultiByteFont) tf, in);
}
gen.writeDSCComment(DSCConstants.END_RESOURCE);
gen.getResourceTracker().registerSuppliedResource(fontRes);
@@ -229,6 +253,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
if (!embeddedFont) {
gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes);
}
return fontResource;
}

private static void embedTrueTypeFont(PSGenerator gen,
@@ -236,15 +261,25 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
/* See Adobe Technical Note #5012, "The Type 42 Font Format Specification" */
gen.commentln("%!PS-TrueTypeFont-65536-65536-1"); // TODO TrueType & font versions
gen.writeln("11 dict begin");
createType42DictionaryEntries(gen, font, fontStream, font.getCMaps());
gen.writeln("FontName currentdict end definefont pop");
}

private static void createType42DictionaryEntries(PSGenerator gen, CustomFont font,
InputStream fontStream, List cmaps) throws IOException {
gen.write("/FontName /");
gen.write(font.getFontName());
gen.writeln(" def");
gen.writeln("/PaintType 0 def");
gen.writeln("/FontMatrix [1 0 0 1 0 0] def");
writeFontBBox(gen, font);
gen.writeln("/FontType 42 def");
gen.writeln("/Encoding 256 array");
gen.writeln("0 1 255{1 index exch/.notdef put}for");
Set glyphs = new HashSet();
for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) {
gen.write("dup ");
gen.write(Integer.toString(i));
gen.write(i);
gen.write(" /");
String glyphName = Glyphs.charToGlyphName(Glyphs.WINANSI_ENCODING[i]);
if (glyphName.equals("")) {
@@ -256,16 +291,6 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
gen.writeln(" put");
}
gen.writeln("readonly def");
gen.writeln("/PaintType 0 def");
gen.writeln("/FontMatrix [1 0 0 1 0 0] def");
int[] bbox = font.getFontBBox();
gen.write("/FontBBox[");
for (int i = 0; i < 4; i++) {
gen.write(" ");
gen.write(Integer.toString(bbox[i]));
}
gen.writeln(" ] def");
gen.writeln("/FontType 42 def");
gen.write("/sfnts[");
/*
* Store the font file in an array of hex-encoded strings. Strings are limited to
@@ -289,23 +314,21 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
}
gen.writeln("]def");
gen.write("/CharStrings ");
gen.write(Integer.toString(glyphs.size() + 1));
gen.write(glyphs.size() + 1);
gen.writeln(" dict dup begin");
gen.write("/");
gen.write(Glyphs.NOTDEF);
gen.writeln(" 0 def"); // TODO always glyph index 0?
// TODO ugly and temporary, until CID is implemented
List cmaps = font.getCMaps();
for (Iterator iter = glyphs.iterator(); iter.hasNext();) {
String glyphName = (String) iter.next();
gen.write("/");
gen.write(glyphName);
gen.write(" ");
gen.write(Integer.toString(getGlyphIndex(glyphName, cmaps)));
gen.write(getGlyphIndex(glyphName, cmaps));
gen.writeln(" def");
}
gen.writeln("end readonly def");
gen.writeln("FontName currentdict end definefont pop");
}

private static int getGlyphIndex(String glyphName, List cmaps) {
@@ -319,6 +342,96 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
return 0;
}

private static void embedType0Font(PSGenerator gen, MultiByteFont font, InputStream fontStream)
throws IOException {
String psName = font.getFontName();
gen.write("/");
gen.write(psName);
gen.write(" /Identity-H [/");
gen.write(psName);
gen.writeln("] composefont pop");
}

private static PSResource embedCIDFont(PSGenerator gen,
MultiByteFont font, InputStream fontStream) throws IOException {
String psName = font.getFontName();
gen.write("%%BeginResource: CIDFont ");
gen.writeln(psName);

gen.write("%%Title: (");
gen.write(psName);
gen.writeln(" Adobe Identity 0)");

gen.writeln("%%Version: 1"); // TODO use font revision?
gen.writeln("/CIDInit /ProcSet findresource begin");
gen.writeln("20 dict begin");

gen.write("/CIDFontName /");
gen.write(psName);
gen.writeln(" def");

gen.writeln("/CIDFontVersion 1 def"); // TODO same as %%Version above

gen.write("/CIDFontType ");
gen.write(font.getCIDType().getValue());
gen.writeln(" def");

gen.writeln("/CIDSystemInfo 3 dict dup begin");
gen.writeln(" /Registry (Adobe) def");
gen.writeln(" /Ordering (Identity) def");
gen.writeln(" /Supplement 0 def");
gen.writeln("end def");

// TODO UIDBase (and UIDOffset in CMap) necessary if PostScript Level 1 & 2
// interpreters are to be supported
// (Level 1: with composite font extensions; Level 2: those that do not offer
// native mode support for CID-keyed fonts)

// TODO XUID (optional but strongly recommended)

// TODO /FontInfo

gen.write("/CIDCount ");
CIDSubset cidSubset = font.getCIDSubset();
int subsetSize = cidSubset.getSubsetSize();
gen.write(subsetSize);
gen.writeln(" def");
gen.writeln("/GDBytes 2 def"); // TODO always 2?
gen.writeln("/CIDMap [<");
int colCount = 0;
int lineCount = 1;
for (int cid = 0; cid < subsetSize; cid++) {
if (colCount++ == 20) {
gen.newLine();
colCount = 1;
if (lineCount++ == 800) {
gen.writeln("> <");
lineCount = 1;
}
}
String gid = HexEncoder.encode(cidSubset.getGlyphIndexForSubsetIndex(cid), 4);
gen.write(gid);
}
gen.writeln(">] def");
createType42DictionaryEntries(gen, font, fontStream, Collections.EMPTY_LIST);
gen.writeln("CIDFontName currentdict end /CIDFont defineresource pop");
gen.writeln("end");
gen.writeln("%%EndResource");
PSResource cidFontResource = new PSResource(PSResource.TYPE_CIDFONT, psName);
gen.getResourceTracker().registerSuppliedResource(cidFontResource);
return cidFontResource;
}

private static void writeFontBBox(PSGenerator gen, CustomFont font) throws IOException {
int[] bbox = font.getFontBBox();
gen.write("/FontBBox[");
for (int i = 0; i < 4; i++) {
gen.write(" ");
gen.write(bbox[i]);
}
gen.writeln(" ] def");
}

private static boolean isEmbeddable(CustomFont font) {
return font.isEmbeddable();
}

+ 29
- 14
src/java/org/apache/fop/render/ps/PSPainter.java ファイルの表示

@@ -44,6 +44,7 @@ import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.render.RenderingContext;
@@ -379,7 +380,7 @@ public class PSPainter extends AbstractIFPainter {
if (currentEncoding != encoding) {
if (i > 0) {
writeText(text, start, i - start,
letterSpacing, wordSpacing, dx, font, tf);
letterSpacing, wordSpacing, dx, font, tf, false);
}
if (encoding == 0) {
useFont(fontKey, sizeMillipoints);
@@ -391,12 +392,11 @@ public class PSPainter extends AbstractIFPainter {
}
}
writeText(text, start, textLen - start,
letterSpacing, wordSpacing, dx, font, tf);
letterSpacing, wordSpacing, dx, font, tf, false);
} else {
//Simple single-font painting
useFont(fontKey, sizeMillipoints);
writeText(text, 0, textLen,
letterSpacing, wordSpacing, dx, font, tf);
letterSpacing, wordSpacing, dx, font, tf, tf instanceof MultiByteFont);
}
} catch (IOException ioe) {
throw new IFException("I/O error in drawText()", ioe);
@@ -405,7 +405,7 @@ public class PSPainter extends AbstractIFPainter {

private void writeText(String text, int start, int len,
int letterSpacing, int wordSpacing, int[] dx,
Font font, Typeface tf) throws IOException {
Font font, Typeface tf, boolean multiByte) throws IOException {
PSGenerator generator = getGenerator();
int end = start + len;
int initialSize = len;
@@ -414,6 +414,16 @@ public class PSPainter extends AbstractIFPainter {
boolean hasLetterSpacing = (letterSpacing != 0);
boolean needTJ = false;

char strOpen;
char strClose;
if (multiByte) {
strOpen = '<';
strClose = '>';
} else {
strOpen = '(';
strClose = ')';
}

int lineStart = 0;
StringBuffer accText = new StringBuffer(initialSize);
StringBuffer sb = new StringBuffer(initialSize);
@@ -439,8 +449,12 @@ public class PSPainter extends AbstractIFPainter {
if (dx != null && i < dxl - 1) {
glyphAdjust -= dx[i + 1];
}
char codepoint = (char)(ch % 256);
PSGenerator.escapeChar(codepoint, accText); //add character to accumulated text
if (multiByte) {
accText.append(HexEncoder.encode(ch));
} else {
char codepoint = (char)(ch % 256);
PSGenerator.escapeChar(codepoint, accText); //add character to accumulated text
}
if (glyphAdjust != 0) {
needTJ = true;
if (sb.length() == 0) {
@@ -451,9 +465,10 @@ public class PSPainter extends AbstractIFPainter {
sb.append(PSGenerator.LF);
lineStart = sb.length();
}
sb.append('(');
sb.append(strOpen);
sb.append(accText);
sb.append(") ");
sb.append(strClose);
sb.append(' ');
accText.setLength(0); //reset accumulated text
}
sb.append(Integer.toString(glyphAdjust)).append(' ');
@@ -461,9 +476,9 @@ public class PSPainter extends AbstractIFPainter {
}
if (needTJ) {
if (accText.length() > 0) {
sb.append('(');
sb.append(strOpen);
sb.append(accText);
sb.append(')');
sb.append(strClose);
}
if (hasLetterSpacing) {
sb.append("] " + formatMptAsPt(generator, letterSpacing) + " ATJ");
@@ -471,7 +486,7 @@ public class PSPainter extends AbstractIFPainter {
sb.append("] TJ");
}
} else {
sb.append('(').append(accText).append(")");
sb.append(strOpen).append(accText).append(strClose);
if (hasLetterSpacing) {
StringBuffer spb = new StringBuffer();
spb.append(formatMptAsPt(generator, letterSpacing))
@@ -486,10 +501,10 @@ public class PSPainter extends AbstractIFPainter {
}

private void useFont(String key, int size) throws IOException {
PSResource res = this.documentHandler.getPSResourceForFontKey(key);
PSFontResource res = this.documentHandler.getPSResourceForFontKey(key);
PSGenerator generator = getGenerator();
generator.useFont("/" + res.getName(), size / 1000f);
generator.getResourceTracker().notifyResourceUsageOnPage(res);
res.notifyResourceUsageOnPage(generator.getResourceTracker());
}



+ 5
- 5
src/java/org/apache/fop/render/ps/PSTextPainter.java ファイルの表示

@@ -35,13 +35,13 @@ import java.text.AttributedCharacterIterator;
import java.util.Iterator;
import java.util.List;

import org.apache.batik.gvt.TextNode;
import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.text.TextSpanLayout;

import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.xmlgraphics.ps.PSResource;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
@@ -240,9 +240,9 @@ public class PSTextPainter extends NativeTextPainter {
}
}

private PSResource getResourceForFont(Font f, String postfix) {
private PSFontResource getResourceForFont(Font f, String postfix) {
String key = (postfix != null ? f.getFontName() + '_' + postfix : f.getFontName());
return this.fontResources.getPSResourceForFontKey(key);
return this.fontResources.getFontResourceForFontKey(key);
}

private void clip(PSGraphics2D ps, Shape shape) throws IOException {
@@ -299,9 +299,9 @@ public class PSTextPainter extends NativeTextPainter {
public void selectFont(Font f, char mapped) throws IOException {
int encoding = mapped / 256;
String postfix = (encoding == 0 ? null : Integer.toString(encoding));
PSResource res = getResourceForFont(f, postfix);
PSFontResource res = getResourceForFont(f, postfix);
gen.useFont("/" + res.getName(), f.getFontSize() / 1000f);
gen.getResourceTracker().notifyResourceUsageOnPage(res);
res.notifyResourceUsageOnPage(gen.getResourceTracker());
}

public Font getCurrentFont() {

+ 2
- 0
test/java/org/apache/fop/UtilityCodeTestSuite.java ファイルの表示

@@ -24,6 +24,7 @@ import junit.framework.TestSuite;

import org.apache.fop.events.BasicEventTestCase;
import org.apache.fop.pdf.PDFObjectTestCase;
import org.apache.fop.render.ps.HexEncoderTestCase;
import org.apache.fop.traits.BorderPropsTestCase;
import org.apache.fop.util.ColorUtilTestCase;
import org.apache.fop.util.ElementListUtilsTestCase;
@@ -51,6 +52,7 @@ public class UtilityCodeTestSuite {
suite.addTest(new TestSuite(BasicEventTestCase.class));
suite.addTest(new TestSuite(XMLResourceBundleTestCase.class));
suite.addTest(new TestSuite(URIResolutionTestCase.class));
suite.addTest(new TestSuite(HexEncoderTestCase.class));
//$JUnit-END$
return suite;
}

+ 58
- 0
test/java/org/apache/fop/render/ps/HexEncoderTestCase.java ファイルの表示

@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.render.ps;

import junit.framework.TestCase;

/**
* Test case for the conversion of characters into hex-encoded strings.
*/
public class HexEncoderTestCase extends TestCase {

private static char successor(char d) {
if (d == '9') {
return 'A';
} else if (d == 'F') {
return '0';
} else {
return (char) (d + 1);
}
}

private static void increment(char[] digits) {
int d = 4;
do {
d--;
digits[d] = successor(digits[d]);
} while (digits[d] == '0' && d > 0);
}

/**
* Tests that characters are properly encoded into hex strings.
*/
public void testEncodeChar() {
char[] digits = new char[] {'0', '0', '0', '0'};
for (int c = 0; c <= 0xFFFF; c++) {
assertEquals(new String(digits), HexEncoder.encode((char) c));
increment(digits);
}
}

}

読み込み中…
キャンセル
保存