
org.jpedal.fonts.tt.TTGlyphs Maven / Gradle / Ivy
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/support/
*
* (C) Copyright 1997-2016 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---------------
* TTGlyphs.java
* ---------------
*/
package org.jpedal.fonts.tt;
import java.util.Map;
import org.jpedal.fonts.glyph.GlyphFactory;
import org.jpedal.fonts.glyph.MarkerGlyph;
import org.jpedal.fonts.glyph.PdfGlyph;
import org.jpedal.fonts.glyph.PdfJavaGlyphs;
import org.jpedal.fonts.FontMappings;
import org.jpedal.fonts.StandardFonts;
import org.jpedal.fonts.objects.FontData;
import org.jpedal.PdfDecoderInt;
import org.jpedal.utils.LogWriter;
import org.jpedal.fonts.tt.hinting.TTVM;
public class TTGlyphs extends PdfJavaGlyphs {
protected int[] CIDToGIDMap;
float[] FontBBox= {0f,0f,1000f,1000f};
boolean isCorrupted;
private CMAP currentCMAP;
private Post currentPost;
private Glyf currentGlyf;
private Hmtx currentHmtx;
private Hhea currentHhea;
private Head currentHead;
private FontFile2 fontTable;
//private Head currentHead;
//private Name currentName;
//private Maxp currentMapx;
private Loca currentLoca;
private TTVM vm;
//private Hhea currentHhea;
private CFF currentCFF;
//int glyphCount=0;
//assume TT and set to OTF further down
int type= StandardFonts.TRUETYPE;
private int unitsPerEm;
private boolean hasCFF;
private boolean isCID;
/**
* used by non type3 font
*/
@Override
public PdfGlyph getEmbeddedGlyph(final GlyphFactory factory, final String glyph, final float[][]Trm, int rawInt,
final String displayValue, final float currentWidth, final String key) {
final int id=rawInt;
if(hasGIDtoCID && isIdentity()){
rawInt=CIDToGIDMap[rawInt];
}
/**flush cache if needed*/
if(Trm!=null && (lastTrm[0][0]!=Trm[0][0])|(lastTrm[1][0]!=Trm[1][0])|
(lastTrm[0][1]!=Trm[0][1])|(lastTrm[1][1]!=Trm[1][1])){
lastTrm=Trm;
flush();
}
//either calculate the glyph to draw or reuse if alreasy drawn
PdfGlyph transformedGlyph2 = getEmbeddedCachedShape(id);
if (transformedGlyph2 == null) {
//use CMAP to get actual glyph ID
int idx=rawInt;
if((!isCID || !isIdentity()) && currentCMAP!=null) {
idx = currentCMAP.convertIndexToCharacterCode(glyph, rawInt);
}
//if no value use post to lookup
if(idx<1){
idx = currentPost.convertGlyphToCharacterCode(glyph);
}
//shape to draw onto
try{
if(hasCFF){
transformedGlyph2=currentCFF.getCFFGlyph(factory,glyph,Trm,idx, displayValue,currentWidth,key);
//set raw width to use for scaling
if(transformedGlyph2!=null) {
transformedGlyph2.setWidth(getUnscaledWidth(glyph, rawInt, false));
}
}else {
transformedGlyph2 = getTTGlyph(idx, glyph, rawInt, displayValue, factory);
}
}catch(final Exception e){
//noinspection UnusedAssignment
transformedGlyph2=null;
LogWriter.writeLog("Exception: " + e.getMessage());
}
//save so we can reuse if it occurs again in this TJ command
setEmbeddedCachedShape(id, transformedGlyph2);
}
return transformedGlyph2;
}
/*
* creates glyph from truetype font commands
*/
private PdfGlyph getTTGlyph(int idx, final String glyph, final int rawInt, final String displayValue, final GlyphFactory factory) {
if(isCorrupted) {
idx = rawInt;
}
PdfGlyph currentGlyph=null;
try{
//final boolean debug=(rawInt==2465);
BaseTTGlyph.debug=false;
if(idx!=-1){
//move the pointer to the commands
final int p=currentGlyf.getCharString(idx);
if(p!=-1){
if(factory.useFX()){
currentGlyph=factory.getGlyph(currentGlyf, fontTable, currentHmtx, idx, (unitsPerEm / 1000f), vm,baseFontName);
}else if (TTGlyph.useHinting) {
currentGlyph = new TTGlyph(currentGlyf, fontTable, currentHmtx, idx, (unitsPerEm / 1000f), vm);
} else {
currentGlyph = new TTGlyph(currentGlyf, fontTable, currentHmtx, idx, (unitsPerEm / 1000f), baseFontName);
}
if(BaseTTGlyph.debug) {
System.out.println(">>" + p + ' ' + rawInt + ' ' + displayValue + ' ' + baseFontName);
}
} else if (!factory.useFX() && (" ".equals(glyph) || " ".equals(displayValue))) {
//Add a marker glyph in to record the number of the space glyph
currentGlyph = new MarkerGlyph(0,0,0,0,baseFontName);
currentGlyph.setGlyphNumber(idx+1);
}
}
}catch(final Exception ee){
LogWriter.writeLog("Exception "+ee);
}
//if(glyph.equals("fl"))
return currentGlyph;
}
@Override
public void setEncodingToUse(final boolean hasEncoding, final int fontEncoding, final boolean isCIDFont) {
if(currentCMAP!=null){
if(isCorrupted) {
currentCMAP.setEncodingToUse(hasEncoding, fontEncoding, isCIDFont);
} else {
currentCMAP.setEncodingToUse(hasEncoding, fontEncoding, isCIDFont);
}
}
}
@Override
public int getConvertedGlyph(final int idx){
if(currentCMAP==null) {
return idx;
} else {
return currentCMAP.convertIndexToCharacterCode(null, idx);
}
}
/**
* Return charstrings and subrs - used by PS to OTF converter
* @return
*/
@Override
public Map getCharStrings() {
if(currentCMAP!=null){
return currentCMAP.buildCharStringTable();
}else{
return currentGlyf.buildCharStringTable();
}
}
/*
* creates glyph from truetype font commands
*/
@Override
public float getTTWidth(final String glyph, final int rawInt, final String displayValue, final boolean TTstreamisCID) {
//use CMAP if not CID
int idx=rawInt;
float width=0;
try{
if((!TTstreamisCID)) {
idx = currentCMAP.convertIndexToCharacterCode(glyph, rawInt);
}
//if no value use post to lookup
if(idx<1) {
idx = currentPost.convertGlyphToCharacterCode(glyph);
}
//if(idx!=-1)
width=currentHmtx.getWidth(idx);
}catch(final Exception e){
LogWriter.writeLog("Attempting to read width " + e);
}
return width;
}
/*
* creates glyph from truetype font commands
*/
private float getUnscaledWidth(final String glyph, final int rawInt, final boolean TTstreamisCID) {
//use CMAP if not CID
int idx=rawInt;
float width=0;
try{
if((!TTstreamisCID)) {
idx = currentCMAP.convertIndexToCharacterCode(glyph, rawInt);
}
//if no value use post to lookup
if(idx<1) {
idx = currentPost.convertGlyphToCharacterCode(glyph);
}
//if(idx!=-1)
width=currentHmtx.getUnscaledWidth(idx);
}catch(final Exception e){
LogWriter.writeLog("Attempting to read width " + e);
}
return width;
}
@Override
public void setGIDtoCID(final int[] cidToGIDMap) {
hasGIDtoCID=true;
this.CIDToGIDMap=cidToGIDMap;
}
/**
* return name of font or all fonts if TTC
* NAME will be LOWERCASE to avoid issues of capitalisation
* when used for lookup - if no name, will default to null
*
* Mode is PdfDecoder.SUBSTITUTE_* CONSTANT. RuntimeException will be thrown on invalid value
*/
public static String[] readFontNames(final FontData fontData, final int mode) {
/**setup read the table locations*/
final FontFile2 currentFontFile=new FontFile2(fontData);
//get type
//int fontType=currentFontFile.getType();
final int fontCount=currentFontFile.getFontCount();
final String[] fontNames=new String[fontCount];
/**read tables for names*/
for(int i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy