⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfffontsubset.java

📁 源码包含生成 PDF 和 HTML 的类库
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * $Id: CFFFontSubset.java 3573 2008-07-21 15:08:04Z blowagie $ * * Copyright 2004 Oren Manor and Ygal Blum * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above.  If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */package com.lowagie.text.pdf;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;/** * This Class subsets a CFF Type Font. The subset is preformed for CID fonts and NON CID fonts. * The Charstring is subsetted for both types. For CID fonts only the FDArray which are used are embedded.  * The Lsubroutines of the FDArrays used are subsetted as well. The Subroutine subset supports both Type1 and Type2 * formatting although only tested on Type2 Format. * For Non CID the Lsubroutines are subsetted. On both types the Gsubroutines is subsetted.  * A font which was not of CID type is transformed into CID as a part of the subset process.  * The CID synthetic creation was written by Sivan Toledo (sivan@math.tau.ac.il)  * @author Oren Manor (manorore@post.tau.ac.il) and Ygal Blum (blumygal@post.tau.ac.il) */public class CFFFontSubset extends CFFFont {		/**	 *  The Strings in this array represent Type1/Type2 operator names	 */	static final String SubrsFunctions[] = {			"RESERVED_0","hstem","RESERVED_2","vstem","vmoveto","rlineto","hlineto","vlineto",			"rrcurveto","RESERVED_9","callsubr","return","escape","RESERVED_13",			"endchar","RESERVED_15","RESERVED_16","RESERVED_17","hstemhm","hintmask",			"cntrmask","rmoveto","hmoveto","vstemhm","rcurveline","rlinecurve","vvcurveto",			"hhcurveto","shortint","callgsubr","vhcurveto","hvcurveto"			};	/**	 * The Strings in this array represent Type1/Type2 escape operator names	 */	static final String SubrsEscapeFuncs[] = {			"RESERVED_0","RESERVED_1","RESERVED_2","and","or","not","RESERVED_6",			"RESERVED_7","RESERVED_8","abs","add","sub","div","RESERVED_13","neg",			"eq","RESERVED_16","RESERVED_17","drop","RESERVED_19","put","get","ifelse",			"random","mul","RESERVED_25","sqrt","dup","exch","index","roll","RESERVED_31",			"RESERVED_32","RESERVED_33","hflex","flex","hflex1","flex1","RESERVED_REST"	};		/**	*  Operator codes for unused  CharStrings and unused local and global Subrs	*/	static final byte ENDCHAR_OP = 14;	static final byte RETURN_OP = 11;		/**	 * A HashMap containing the glyphs used in the text after being converted	 * to glyph number by the CMap 	 */	HashMap GlyphsUsed;	/**	 * The GlyphsUsed keys as an ArrayList	 */	ArrayList glyphsInList;	/**	 * A HashMap for keeping the FDArrays being used by the font	 */	HashMap FDArrayUsed = new HashMap();	/**	 * A HashMaps array for keeping the subroutines used in each FontDict	 */	HashMap[] hSubrsUsed;	/**	 * The SubroutinesUsed HashMaps as ArrayLists	 */	ArrayList[] lSubrsUsed;	/**	 * A HashMap for keeping the Global subroutines used in the font	 */	HashMap hGSubrsUsed  = new HashMap();	/**	 * The Global SubroutinesUsed HashMaps as ArrayLists	 */	ArrayList lGSubrsUsed = new ArrayList();	/**	 * A HashMap for keeping the subroutines used in a non-cid font	 */	HashMap hSubrsUsedNonCID  = new HashMap();	/**	 * The SubroutinesUsed HashMap as ArrayList	 */	ArrayList lSubrsUsedNonCID = new ArrayList();	/**	 * An array of the new Indexes for the local Subr. One index for each FontDict	 */	byte[][] NewLSubrsIndex;	/**	 * The new subroutines index for a non-cid font	 */	byte[] NewSubrsIndexNonCID;	/**	 * The new global subroutines index of the font	 */	byte[] NewGSubrsIndex;	/**	 * The new CharString of the font	 */	byte[] NewCharStringsIndex;		/**	 * The bias for the global subroutines	 */	int GBias = 0;		/**	 * The linked list for generating the new font stream	 */	LinkedList OutputList;		/**	 * Number of arguments to the stem operators in a subroutine calculated recursively	 */	int NumOfHints=0;		/**	 	 * C'tor for CFFFontSubset	 * @param rf - The font file	 * @param GlyphsUsed - a HashMap that contains the glyph used in the subset 	 */    public CFFFontSubset(RandomAccessFileOrArray rf,HashMap GlyphsUsed){		// Use CFFFont c'tor in order to parse the font file.    	super(rf);		this.GlyphsUsed = GlyphsUsed;		//Put the glyphs into a list		glyphsInList = new ArrayList(GlyphsUsed.keySet());						for (int i=0;i<fonts.length;++i)		{			// Read the number of glyphs in the font			seek(fonts[i].charstringsOffset);	        fonts[i].nglyphs = getCard16();	        	    	// Jump to the count field of the String Index	        seek(stringIndexOffset);	        fonts[i].nstrings = getCard16()+standardStrings.length;	        	        // For each font save the offset array of the charstring			fonts[i].charstringsOffsets = getIndex(fonts[i].charstringsOffset);						// Process the FDSelect if exist 			if (fonts[i].fdselectOffset>=0)			{				// Process the FDSelect	            readFDSelect(i);	            // Build the FDArrayUsed hashmap            	BuildFDArrayUsed(i);			}			if (fonts[i].isCID)				// Build the FD Array used Hash Map				ReadFDArray(i);			// compute the charset length 			fonts[i].CharsetLength = CountCharset(fonts[i].charsetOffset,fonts[i].nglyphs);		}	}    /**     * Calculates the length of the charset according to its format     * @param Offset The Charset Offset     * @param NumofGlyphs Number of glyphs in the font     * @return the length of the Charset     */    int CountCharset(int Offset,int NumofGlyphs){    	int format;    	int Length=0;    	seek(Offset);    	// Read the format    	format = getCard8();    	// Calc according to format    	switch (format){    		case 0:    			Length = 1+2*NumofGlyphs;    			break;    		case 1:    			Length = 1+3*CountRange(NumofGlyphs,1);    			break;    		case 2:    			Length = 1+4*CountRange(NumofGlyphs,2);    			break;    		default:    			break;    	}    	return Length;    }        /**     * Function calculates the number of ranges in the Charset     * @param NumofGlyphs The number of glyphs in the font     * @param Type The format of the Charset     * @return The number of ranges in the Charset data structure     */    int CountRange(int NumofGlyphs,int Type){    	int num=0;    	char Sid;    	int i=1,nLeft;    	while (i<NumofGlyphs){    		num++;    		Sid = getCard16();    		if (Type==1)    			nLeft = getCard8();    		else    			nLeft = getCard16();    		i += nLeft+1;    	}    	return num;    }	/**	 * Read the FDSelect of the font and compute the array and its length	 * @param Font The index of the font being processed	 */	protected void readFDSelect(int Font)	{		// Restore the number of glyphs		int NumOfGlyphs = fonts[Font].nglyphs;		int[] FDSelect = new int[NumOfGlyphs];		// Go to the beginning of the FDSelect		seek(fonts[Font].fdselectOffset);		// Read the FDSelect's format		fonts[Font].FDSelectFormat = getCard8();				switch(fonts[Font].FDSelectFormat){			// Format==0 means each glyph has an entry that indicated			// its FD.			case 0:				for (int i=0;i<NumOfGlyphs;i++)				{					FDSelect[i] = getCard8();				}				// The FDSelect's Length is one for each glyph + the format				// for later use				fonts[Font].FDSelectLength = fonts[Font].nglyphs+1;				break;			case 3:				// Format==3 means the ranges version				// The number of ranges				int nRanges = getCard16();				int l=0;				// Read the first in the first range				int first = getCard16();				for (int i=0;i<nRanges;i++)				{					// Read the FD index					int fd = getCard8();					// Read the first of the next range					int last = getCard16();					// Calc the steps and write to the array					int steps = last-first;					for (int k=0;k<steps;k++)					{						FDSelect[l] = fd;						l++;					}					// The last from this iteration is the first of the next					first = last;				}				// Store the length for later use				fonts[Font].FDSelectLength = 1+2+nRanges*3+2;				break;			default:				break;		}		// Save the FDSelect of the font 		fonts[Font].FDSelect = FDSelect; 	}		/**	 * Function reads the FDSelect and builds the FDArrayUsed HashMap According to the glyphs used	 * @param Font the Number of font being processed	 */	protected void BuildFDArrayUsed(int Font)	{		int[] FDSelect = fonts[Font].FDSelect;		// For each glyph used		for (int i=0;i<glyphsInList.size();i++)		{			// Pop the glyphs index			int glyph = ((Integer)glyphsInList.get(i)).intValue();			// Pop the glyph's FD			int FD = FDSelect[glyph];			// Put the FD index into the FDArrayUsed HashMap			FDArrayUsed.put(new Integer(FD),null);		}	}	/**	 * Read the FDArray count, offsize and Offset array	 * @param Font	 */	protected void ReadFDArray(int Font)	{		seek(fonts[Font].fdarrayOffset);		fonts[Font].FDArrayCount = getCard16();		fonts[Font].FDArrayOffsize = getCard8();		// Since we will change values inside the FDArray objects		// We increase its offsize to prevent errors 		if (fonts[Font].FDArrayOffsize < 4)			fonts[Font].FDArrayOffsize++;		fonts[Font].FDArrayOffsets = getIndex(fonts[Font].fdarrayOffset);	}    	/**	 * The Process function extracts one font out of the CFF file and returns a	 * subset version of the original.	 * @param fontName - The name of the font to be taken out of the CFF	 * @return The new font stream	 * @throws IOException	 */	public byte[] Process(String fontName)throws IOException{		try		{				// Verify that the file is open			buf.reOpen();			// Find the Font that we will be dealing with			int j;	        for (j=0; j<fonts.length; j++)	            if (fontName.equals(fonts[j].name)) break;	        if (j==fonts.length) return null;	        			// Calc the bias for the global subrs			if (gsubrIndexOffset >= 0)				GBias = CalcBias(gsubrIndexOffset,j);	        // Prepare the new CharStrings Index			BuildNewCharString(j);			 // Prepare the new Global and Local Subrs Indices			BuildNewLGSubrs(j);			// Build the new file 			byte[] Ret = BuildNewFile(j);			return Ret;		}		finally {            try {                buf.close();            }            catch (Exception e) {                // empty on purpose            }		}	}	/**	 * Function calcs bias according to the CharString type and the count	 * of the subrs	 * @param Offset The offset to the relevant subrs index	 * @param Font the font	 * @return The calculated Bias	 */	protected int CalcBias(int Offset,int Font)	{		seek(Offset);		int nSubrs = getCard16();		// If type==1 -> bias=0 		if (fonts[Font].CharstringType == 1)			return 0;		// else calc according to the count		else if (nSubrs < 1240)			return 107;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -