Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* ===========================================
* 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.PdfDecoderInt;
import org.jpedal.fonts.FontMappings;
import org.jpedal.fonts.StandardFonts;
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.objects.FontData;
import org.jpedal.fonts.tt.hinting.TTVM;
import org.jpedal.utils.LogWriter;
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;
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){
width=1000;
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 fontDetails) {
/* setup read the table locations*/
final FontFile2 currentFontFile=new FontFile2(fontData);
//get type
//int fontType=currentFontFile.getType();
final int fontCount=currentFontFile.getFontCount();
/* read tables for names*/
for(int i=0;i stringValues= currentName.getStrings();
if(stringValues!=null){
for (final Integer o : stringValues.keySet()) {
final Integer currentKey = o;
final int keyInt = currentKey;
if (keyInt < Name.stringNames.length) {
fontDetails.put(Name.stringNames[currentKey], stringValues.get(currentKey));
}
}
}
}
if(fontData!=null) {
fontData.close();
}
}
@Override
public int readEmbeddedFont(final boolean TTstreamisCID, final byte[] fontDataAsArray, final FontData fontData) {
final FontFile2 currentFontFile;
isCID=TTstreamisCID;
/* setup read the table locations*/
if(fontDataAsArray!=null) {
currentFontFile = new FontFile2(fontDataAsArray);
} else {
currentFontFile = new FontFile2(fontData);
}
//select font if TTC
//does nothing if TT
if(FontMappings.fontSubstitutionFontID==null){
currentFontFile.setPointer(0);
}else{
final Integer fontID= FontMappings.fontSubstitutionFontID.get(fontName.toLowerCase());
if(fontID!=null) {
currentFontFile.setPointer(fontID);
} else {
currentFontFile.setPointer(0);
}
}
currentHead=new Head(currentFontFile);
currentPost=new Post(currentFontFile);
//currentName=new Name(currentFontFile);
final Maxp currentMaxp =new Maxp(currentFontFile);
glyphCount= currentMaxp.getGlyphCount();
currentLoca=new Loca(currentFontFile,glyphCount,currentHead.getIndexToLocFormat());
isCorrupted=currentLoca.isCorrupted();
currentGlyf=new Glyf(currentFontFile,glyphCount,currentLoca.getIndices());
currentCFF=new CFF(currentFontFile,isCID);
hasCFF=currentCFF.hasCFFData();
if(hasCFF) {
type = StandardFonts.OPENTYPE;
}
//currentCvt=new Cvt(currentFontFile);
if(TTGlyph.useHinting){
//Classes in hinting package which we will delete in lgpl
vm=new TTVM(currentFontFile, currentMaxp);
}
currentHhea=new Hhea(currentFontFile);
FontBBox=currentHead.getFontBBox();
currentHmtx=new Hmtx(currentFontFile,glyphCount,currentHhea.getNumberOfHMetrics(),(int)FontBBox[3]);
//not all files have CMAPs
//if(!TTstreamisCID){
final int startPointer=currentFontFile.selectTable(FontFile2.CMAP);
if(startPointer!=0) {
currentCMAP = new CMAP(currentFontFile, startPointer);
}
//}
unitsPerEm=currentHead.getUnitsPerEm();
fontTable=new FontFile2(currentGlyf.getTableData(),true);
if(fontData!=null) {
fontData.close();
}
return type;
}
@Override
public float[] getFontBoundingBox() {
return FontBBox;
}
@Override
public int getType() {
return type;
}
//flag if Loca broken so we need to try and Substitute
@Override
public boolean isCorrupted() {
return isCorrupted;
}
@Override
public void setCorrupted(final boolean corrupt) {
isCorrupted=corrupt;
}
@Override
public Table getTable(final int type){
final Table table;
switch(type){
case FontFile2.LOCA:
table=currentLoca;
break;
case FontFile2.CMAP:
table=currentCMAP;
break;
case FontFile2.HHEA:
table=currentHhea;
break;
case FontFile2.HMTX:
table=currentHmtx;
break;
case FontFile2.HEAD:
table=currentHead;
break;
default:
throw new RuntimeException("table not yet added to getTable)");
}
return table;
}
}