blob: b22b92e2f81450de8ddf68f7e57a363551ed7212 [file] [log] [blame]
/*
* 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.fonts;
//Java
import java.text.DecimalFormat;
import java.util.Map;
/**
* Generic MultiByte (CID) font
*/
public class MultiByteFont extends CIDFont {
private static int uniqueCounter = -1;
private String ttcName = null;
private String encoding = "Identity-H";
private int defaultWidth = 0;
private CIDFontType cidType = CIDFontType.CIDTYPE2;
private String namePrefix = null; // Quasi unique prefix
private CIDSubset subset = new CIDSubset();
/** A map from Unicode indices to glyph indices */
private BFEntry[] bfentries = null;
/**
* Default constructor
*/
public MultiByteFont() {
// Make sure that the 3 first glyphs are included
subset.setupFirstThreeGlyphs();
// Create a quasiunique prefix for fontname
synchronized (this.getClass()) {
uniqueCounter++;
if (uniqueCounter > 99999 || uniqueCounter < 0) {
uniqueCounter = 0; //We need maximum 5 character then we start again
}
}
DecimalFormat counterFormat = new DecimalFormat("00000");
String cntString = counterFormat.format(uniqueCounter);
//Subset prefix as described in chapter 5.5.3 of PDF 1.4
StringBuffer sb = new StringBuffer("E");
for (int i = 0, c = cntString.length(); i < c; i++) {
//translate numbers to uppercase characters
sb.append((char)(cntString.charAt(i) + (65 - 48)));
}
sb.append("+");
namePrefix = sb.toString();
setFontType(FontType.TYPE0);
}
/** {@inheritDoc} */
public int getDefaultWidth() {
return defaultWidth;
}
/** {@inheritDoc} */
public String getRegistry() {
return "Adobe";
}
/** {@inheritDoc} */
public String getOrdering() {
return "UCS";
}
/** {@inheritDoc} */
public int getSupplement() {
return 0;
}
/** {@inheritDoc} */
public CIDFontType getCIDType() {
return cidType;
}
/**
* Sets the CIDType.
* @param cidType The cidType to set
*/
public void setCIDType(CIDFontType cidType) {
this.cidType = cidType;
}
private String getPrefixedFontName() {
return namePrefix + FontUtil.stripWhiteSpace(super.getFontName());
}
/** {@inheritDoc} */
public String getEmbedFontName() {
if (isEmbeddable()) {
return getPrefixedFontName();
} else {
return super.getFontName();
}
}
/** {@inheritDoc} */
public boolean isEmbeddable() {
return !(getEmbedFileName() == null && getEmbedResourceName() == null);
}
/** {@inheritDoc} */
public CIDSubset getCIDSubset() {
return this.subset;
}
/** {@inheritDoc} */
public String getEncodingName() {
return encoding;
}
/** {@inheritDoc} */
public int getWidth(int i, int size) {
if (isEmbeddable()) {
int glyphIndex = subset.getGlyphIndexForSubsetIndex(i);
return size * width[glyphIndex];
} else {
return size * width[i];
}
}
/** {@inheritDoc} */
public int[] getWidths() {
int[] arr = new int[width.length];
System.arraycopy(width, 0, arr, 0, width.length - 1);
return arr;
}
/**
* Returns the glyph index for a Unicode character. The method returns 0 if there's no
* such glyph in the character map.
* @param c the Unicode character index
* @return the glyph index (or 0 if the glyph is not available)
*/
private int findGlyphIndex(char c) {
int idx = (int)c;
int retIdx = SingleByteEncoding.NOT_FOUND_CODE_POINT;
for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) {
if (bfentries[i].getUnicodeStart() <= idx
&& bfentries[i].getUnicodeEnd() >= idx) {
retIdx = bfentries[i].getGlyphStartIndex()
+ idx
- bfentries[i].getUnicodeStart();
}
}
return retIdx;
}
/** {@inheritDoc} */
public char mapChar(char c) {
notifyMapOperation();
int glyphIndex = findGlyphIndex(c);
if (glyphIndex == SingleByteEncoding.NOT_FOUND_CODE_POINT) {
warnMissingGlyph(c);
glyphIndex = findGlyphIndex(Typeface.NOT_FOUND);
}
if (isEmbeddable()) {
glyphIndex = subset.mapSubsetChar(glyphIndex, c);
}
return (char)glyphIndex;
}
/** {@inheritDoc} */
public boolean hasChar(char c) {
return (findGlyphIndex(c) != SingleByteEncoding.NOT_FOUND_CODE_POINT);
}
/**
* Sets the array of BFEntry instances which constitutes the Unicode to glyph index map for
* a font. ("BF" means "base font")
* @param entries the Unicode to glyph index map
*/
public void setBFEntries(BFEntry[] entries) {
this.bfentries = entries;
}
/**
* Sets the defaultWidth.
* @param defaultWidth The defaultWidth to set
*/
public void setDefaultWidth(int defaultWidth) {
this.defaultWidth = defaultWidth;
}
/**
* Returns the TrueType Collection Name.
* @return the TrueType Collection Name
*/
public String getTTCName() {
return ttcName;
}
/**
* Sets the the TrueType Collection Name.
* @param ttcName the TrueType Collection Name
*/
public void setTTCName(String ttcName) {
this.ttcName = ttcName;
}
/**
* Sets the width array.
* @param wds array of widths.
*/
public void setWidthArray(int[] wds) {
this.width = wds;
}
/**
* Returns a Map of used Glyphs.
* @return Map Map of used Glyphs
*/
public Map getUsedGlyphs() {
return subset.getSubsetGlyphs();
}
/** {@inheritDoc} */
public char[] getCharsUsed() {
if (!isEmbeddable()) {
return null;
}
return subset.getSubsetChars();
}
}