All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.fonts.tt.TTGlyphs Maven / Gradle / Ivy

There is a newer version: 20151002
Show newest version
/*
 * ===========================================
 * 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-2015 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 - 2024 Weber Informatics LLC | Privacy Policy