/*
 * 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: PDFCIDFont.java 1758773 2016-09-01 13:02:29Z ssteiner $ */

package org.apache.fop.pdf;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Set;

import org.apache.fop.fonts.CIDFontType;

// based on work by Takayuki Takeuchi

Class representing a "character identifier" font (p 210 and onwards).
/** * Class representing a "character identifier" font (p 210 and onwards). */
public class PDFCIDFont extends PDFObject { private String basefont; private CIDFontType cidtype; private Integer dw; private PDFWArray w; private int[] dw2; private PDFWArray w2; private PDFCIDSystemInfo systemInfo; private PDFCIDFontDescriptor descriptor; private PDFCMap cmap;
/CIDToGIDMap (only for CIDFontType2, see p 212) can be either "Identity" (default) or a PDFStream
/** * /CIDToGIDMap (only for CIDFontType2, see p 212) * can be either "Identity" (default) or a PDFStream */
private PDFStream cidMap;
Create the /Font object
Params:
  • basefont – Name of the basefont
  • cidtype – CID type
  • dw – default width
  • w – array of character widths
  • registry – name of the issuer
  • ordering – Unique name of the font
  • supplement – Supplement number
  • descriptor – CID font descriptor
/** * Create the /Font object * @param basefont Name of the basefont * @param cidtype CID type * @param dw default width * @param w array of character widths * @param registry name of the issuer * @param ordering Unique name of the font * @param supplement Supplement number * @param descriptor CID font descriptor */
public PDFCIDFont(String basefont, CIDFontType cidtype, int dw, int[] w, String registry, String ordering, int supplement, PDFCIDFontDescriptor descriptor) { this(basefont, cidtype, dw, new PDFWArray(w), new PDFCIDSystemInfo(registry, ordering, supplement), descriptor); }
Create the /Font object
Params:
  • basefont – Name of the basefont
  • cidtype – CID type
  • dw – default width
  • w – array of character widths
  • systemInfo – CID system info
  • descriptor – CID font descriptor
/** * Create the /Font object * @param basefont Name of the basefont * @param cidtype CID type * @param dw default width * @param w array of character widths * @param systemInfo CID system info * @param descriptor CID font descriptor */
public PDFCIDFont(String basefont, CIDFontType cidtype, int dw, int[] w, PDFCIDSystemInfo systemInfo, PDFCIDFontDescriptor descriptor) { this(basefont, cidtype, dw, new PDFWArray(w), systemInfo, descriptor); }
Create the /Font object
Params:
  • basefont – Name of the basefont
  • cidtype – CID type
  • dw – default width
  • w – array of character widths
  • systemInfo – CID system info
  • descriptor – CID font descriptor
/** * Create the /Font object * @param basefont Name of the basefont * @param cidtype CID type * @param dw default width * @param w array of character widths * @param systemInfo CID system info * @param descriptor CID font descriptor */
public PDFCIDFont(String basefont, CIDFontType cidtype, int dw, PDFWArray w, PDFCIDSystemInfo systemInfo, PDFCIDFontDescriptor descriptor) { super(); this.basefont = basefont; this.cidtype = cidtype; this.dw = dw; this.w = w; this.dw2 = null; this.w2 = null; systemInfo.setParent(this); this.systemInfo = systemInfo; this.descriptor = descriptor; this.cidMap = null; this.cmap = null; }
Set the /DW attribute
Params:
  • dw – the default width
/** * Set the /DW attribute * @param dw the default width */
public void setDW(int dw) { this.dw = dw; }
Set the /W array
Params:
  • w – the width array
/** * Set the /W array * @param w the width array */
public void setW(PDFWArray w) { this.w = w; }
Set the (two elements) /DW2 array
Params:
  • dw2 – the default metrics for vertical writing
/** * Set the (two elements) /DW2 array * @param dw2 the default metrics for vertical writing */
public void setDW2(int[] dw2) { this.dw2 = dw2; }
Set the two elements of the /DW2 array
Params:
  • posY – position vector
  • displacementY – displacement vector
/** * Set the two elements of the /DW2 array * @param posY position vector * @param displacementY displacement vector */
public void setDW2(int posY, int displacementY) { this.dw2 = new int[] { posY, displacementY }; }
Set the CMap used as /ToUnicode cmap
Params:
  • cmap – character map
/** * Set the CMap used as /ToUnicode cmap * @param cmap character map */
public void setCMAP(PDFCMap cmap) { this.cmap = cmap; }
Set the /W2 array
Params:
  • w2 – array of metrics for vertical writing
/** * Set the /W2 array * @param w2 array of metrics for vertical writing */
public void setW2(PDFWArray w2) { this.w2 = w2; }
Set the /CIDToGIDMap (to be used only for CIDFontType2)
Params:
  • map – mapping information
/** * Set the /CIDToGIDMap (to be used only for CIDFontType2) * @param map mapping information */
public void setCIDMap(PDFStream map) { this.cidMap = map; }
Set the /CIDToGIDMap (to be used only for CIDFontType2) to "Identity"
/** * Set the /CIDToGIDMap (to be used only for CIDFontType2) to "Identity" */
public void setCIDMapIdentity() { this.cidMap = null; // not an error here, simply use the default }
Returns the PDF name for a certain CID font type.
Params:
  • cidFontType – CID font type
Returns:corresponding PDF name
/** * Returns the PDF name for a certain CID font type. * @param cidFontType CID font type * @return corresponding PDF name */
protected String getPDFNameForCIDFontType(CIDFontType cidFontType) { if (cidFontType == CIDFontType.CIDTYPE0) { return cidFontType.getName(); } else if (cidFontType == CIDFontType.CIDTYPE2) { return cidFontType.getName(); } else { throw new IllegalArgumentException("Unsupported CID font type: " + cidFontType.getName()); } }
{@inheritDoc}
/** * {@inheritDoc} */
public String toPDFString() { StringBuffer p = new StringBuffer(128); p.append("<< /Type /Font"); p.append("\n/BaseFont /"); p.append(this.basefont); p.append(" \n/CIDToGIDMap "); if (cidMap != null) { p.append(cidMap.referencePDF()); } else { p.append("/Identity"); //This is the default. We still write it because PDF/A requires it. } p.append(" \n/Subtype /"); p.append(getPDFNameForCIDFontType(this.cidtype)); p.append("\n"); p.append(systemInfo.toPDFString()); p.append("\n/FontDescriptor "); p.append(this.descriptor.referencePDF()); if (cmap != null) { p.append("\n/ToUnicode "); p.append(cmap.referencePDF()); } if (dw != null) { p.append("\n/DW "); p.append(this.dw); } if (w != null) { p.append("\n/W "); p.append(w.toPDFString()); } if (dw2 != null) { p.append("\n/DW2 ["); // always two values, see p 211 p.append(this.dw2[0]); p.append(this.dw2[1]); p.append("]"); } if (w2 != null) { p.append("\n/W2 "); p.append(w2.toPDFString()); } p.append("\n>>"); return p.toString(); }
{@inheritDoc}
/** * {@inheritDoc} */
public byte[] toPDF() { ByteArrayOutputStream bout = new ByteArrayOutputStream(128); try { bout.write(encode("<< /Type /Font\n")); bout.write(encode("/BaseFont /")); bout.write(encode(this.basefont)); bout.write(encode(" \n")); bout.write(encode("/CIDToGIDMap ")); bout.write(encode(cidMap != null ? cidMap.referencePDF() : "/Identity")); bout.write(encode(" \n")); bout.write(encode("/Subtype /")); bout.write(encode(getPDFNameForCIDFontType(this.cidtype))); bout.write(encode("\n")); bout.write(encode("/CIDSystemInfo ")); bout.write(systemInfo.toPDF()); bout.write(encode("\n")); bout.write(encode("/FontDescriptor ")); bout.write(encode(this.descriptor.referencePDF())); bout.write(encode("\n")); if (cmap != null) { bout.write(encode("/ToUnicode ")); bout.write(encode(cmap.referencePDF())); bout.write(encode("\n")); } if (dw != null) { bout.write(encode("/DW ")); bout.write(encode(this.dw.toString())); bout.write(encode("\n")); } if (w != null) { bout.write(encode("/W ")); bout.write(encode(w.toPDFString())); bout.write(encode("\n")); } if (dw2 != null) { bout.write(encode("/DW2 [")); // always two values, see p 211 bout.write(encode(Integer.toString(this.dw2[0]))); bout.write(encode(Integer.toString(this.dw2[1]))); bout.write(encode("]\n")); } if (w2 != null) { bout.write(encode("/W2 ")); bout.write(encode(w2.toPDFString())); bout.write(encode("\n")); } bout.write(encode(">>")); } catch (IOException ioe) { log.error("Ignored I/O exception", ioe); } return bout.toByteArray(); } @Override public void getChildren(Set<PDFObject> children) { super.getChildren(children); if (cidMap != null) { children.add(cidMap); cidMap.getChildren(children); } children.add(descriptor); descriptor.getChildren(children); if (cmap != null) { children.add(cmap); cmap.getChildren(children); } } }