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

📄 cfffontsubset.java

📁 源码包含生成 PDF 和 HTML 的类库
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
		else if (nSubrs < 33900)			return 1131;		else			return 32768;	}	/**	 *Function uses BuildNewIndex to create the new index of the subset charstrings	 * @param FontIndex the font	 * @throws IOException	 */	protected void BuildNewCharString(int FontIndex) throws IOException 	{		NewCharStringsIndex = BuildNewIndex(fonts[FontIndex].charstringsOffsets,GlyphsUsed,ENDCHAR_OP);	}		/**	 * Function builds the new local & global subsrs indices. IF CID then All of 	 * the FD Array lsubrs will be subsetted. 	 * @param Font the font	 * @throws IOException	 */	protected void BuildNewLGSubrs(int Font)throws IOException	{		// If the font is CID then the lsubrs are divided into FontDicts.		// for each FD array the lsubrs will be subsetted.		if(fonts[Font].isCID)		{			// Init the hashmap-array and the arraylist-array to hold the subrs used			// in each private dict.			hSubrsUsed = new HashMap[fonts[Font].fdprivateOffsets.length];			lSubrsUsed = new ArrayList[fonts[Font].fdprivateOffsets.length];			// A [][] which will store the byte array for each new FD Array lsubs index			NewLSubrsIndex = new byte[fonts[Font].fdprivateOffsets.length][];			// An array to hold the offset for each Lsubr index 			fonts[Font].PrivateSubrsOffset = new int[fonts[Font].fdprivateOffsets.length];			// A [][] which will store the offset array for each lsubr index						fonts[Font].PrivateSubrsOffsetsArray = new int[fonts[Font].fdprivateOffsets.length][];						// Put the FDarrayUsed into a list			ArrayList FDInList = new ArrayList(FDArrayUsed.keySet());			// For each FD array which is used subset the lsubr 			for (int j=0;j<FDInList.size();j++)			{				// The FDArray index, Hash Map, Array List to work on				int FD = ((Integer)FDInList.get(j)).intValue();				hSubrsUsed[FD] = new HashMap();				lSubrsUsed[FD] = new ArrayList();				//Reads the private dicts looking for the subr operator and 				// store both the offset for the index and its offset array				BuildFDSubrsOffsets(Font,FD);				// Verify that FDPrivate has a LSubrs index				if(fonts[Font].PrivateSubrsOffset[FD]>=0)				{					//Scans the Charstring data storing the used Local and Global subroutines 					// by the glyphs. Scans the Subrs recursively. 					BuildSubrUsed(Font,FD,fonts[Font].PrivateSubrsOffset[FD],fonts[Font].PrivateSubrsOffsetsArray[FD],hSubrsUsed[FD],lSubrsUsed[FD]);					// Builds the New Local Subrs index					NewLSubrsIndex[FD] = BuildNewIndex(fonts[Font].PrivateSubrsOffsetsArray[FD],hSubrsUsed[FD],RETURN_OP);				}			}		}		// If the font is not CID && the Private Subr exists then subset:		else if (fonts[Font].privateSubrs>=0)		{			// Build the subrs offsets;			fonts[Font].SubrsOffsets = getIndex(fonts[Font].privateSubrs);			//Scans the Charstring data storing the used Local and Global subroutines 			// by the glyphs. Scans the Subrs recursively.			BuildSubrUsed(Font,-1,fonts[Font].privateSubrs,fonts[Font].SubrsOffsets,hSubrsUsedNonCID,lSubrsUsedNonCID);		}		// For all fonts subset the Global Subroutines		// Scan the Global Subr Hashmap recursively on the Gsubrs		BuildGSubrsUsed(Font);		if (fonts[Font].privateSubrs>=0)			// Builds the New Local Subrs index			NewSubrsIndexNonCID = BuildNewIndex(fonts[Font].SubrsOffsets,hSubrsUsedNonCID,RETURN_OP);		//Builds the New Global Subrs index		NewGSubrsIndex = BuildNewIndex(gsubrOffsets,hGSubrsUsed,RETURN_OP);	}	/**	 * The function finds for the FD array processed the local subr offset and its 	 * offset array.  	 * @param Font the font	 * @param FD The FDARRAY processed	 */	protected void BuildFDSubrsOffsets(int Font,int FD)	{		// Initiate to -1 to indicate lsubr operator present		fonts[Font].PrivateSubrsOffset[FD] = -1;		// Goto beginning of objects        seek(fonts[Font].fdprivateOffsets[FD]);        // While in the same object:        while (getPosition() < fonts[Font].fdprivateOffsets[FD]+fonts[Font].fdprivateLengths[FD])        {        	getDictItem();        	// If the dictItem is the "Subrs" then find and store offset,         	if (key=="Subrs")        		fonts[Font].PrivateSubrsOffset[FD] = ((Integer)args[0]).intValue()+fonts[Font].fdprivateOffsets[FD];        }        //Read the lsubr index if the lsubr was found        if (fonts[Font].PrivateSubrsOffset[FD] >= 0)        	fonts[Font].PrivateSubrsOffsetsArray[FD] = getIndex(fonts[Font].PrivateSubrsOffset[FD]); 	}	/**	 * Function uses ReadAsubr on the glyph used to build the LSubr & Gsubr HashMap.	 * The HashMap (of the lsubr only) is then scanned recursively for Lsubr & Gsubrs	 * calls.  	 * @param Font the font	 * @param FD FD array processed. 0 indicates function was called by non CID font	 * @param SubrOffset the offset to the subr index to calc the bias	 * @param SubrsOffsets the offset array of the subr index	 * @param hSubr HashMap of the subrs used	 * @param lSubr ArrayList of the subrs used	 */	protected void BuildSubrUsed(int Font,int FD,int SubrOffset,int[] SubrsOffsets,HashMap hSubr,ArrayList lSubr)	{		// Calc the Bias for the subr index		int LBias = CalcBias(SubrOffset,Font);				// For each glyph used find its GID, start & end pos		for (int i=0;i<glyphsInList.size();i++)		{			int glyph = ((Integer)glyphsInList.get(i)).intValue();			int Start = fonts[Font].charstringsOffsets[glyph];			int End = fonts[Font].charstringsOffsets[glyph+1];						// IF CID:			if (FD >= 0)			{				EmptyStack();				NumOfHints=0;				// Using FDSELECT find the FD Array the glyph belongs to.				int GlyphFD = fonts[Font].FDSelect[glyph];				// If the Glyph is part of the FD being processed 				if (GlyphFD == FD)					// Find the Subrs called by the glyph and insert to hash:					ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets);			}			else				// If the font is not CID 				//Find the Subrs called by the glyph and insert to hash:				ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets);		}		// For all Lsubrs used, check recursively for Lsubr & Gsubr used		for (int i=0;i<lSubr.size();i++)		{			// Pop the subr value from the hash			int Subr = ((Integer)lSubr.get(i)).intValue();			// Ensure the Lsubr call is valid			if (Subr < SubrsOffsets.length-1 && Subr>=0)			{				// Read and process the subr				int Start = SubrsOffsets[Subr];				int End = SubrsOffsets[Subr+1];				ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets);			}		}	}		/**	 * Function scans the Glsubr used ArrayList to find recursive calls 	 * to Gsubrs and adds to Hashmap & ArrayList	 * @param Font the font	 */	protected void BuildGSubrsUsed(int Font)	{		int LBias = 0;		int SizeOfNonCIDSubrsUsed = 0;		if (fonts[Font].privateSubrs>=0)		{			LBias = CalcBias(fonts[Font].privateSubrs,Font);			SizeOfNonCIDSubrsUsed = lSubrsUsedNonCID.size();		}				// For each global subr used 		for (int i=0;i<lGSubrsUsed.size();i++)		{			//Pop the value + check valid 			int Subr = ((Integer)lGSubrsUsed.get(i)).intValue();			if (Subr < gsubrOffsets.length-1 && Subr>=0)			{				// Read the subr and process				int Start = gsubrOffsets[Subr];				int End = gsubrOffsets[Subr+1];								if (fonts[Font].isCID)					ReadASubr(Start,End,GBias,0,hGSubrsUsed,lGSubrsUsed,null);				else				{					ReadASubr(Start,End,GBias,LBias,hSubrsUsedNonCID,lSubrsUsedNonCID,fonts[Font].SubrsOffsets);					if (SizeOfNonCIDSubrsUsed < lSubrsUsedNonCID.size())					{						for (int j=SizeOfNonCIDSubrsUsed;j<lSubrsUsedNonCID.size();j++)						{							//Pop the value + check valid 							int LSubr = ((Integer)lSubrsUsedNonCID.get(j)).intValue();							if (LSubr < fonts[Font].SubrsOffsets.length-1 && LSubr>=0)							{								// Read the subr and process								int LStart = fonts[Font].SubrsOffsets[LSubr];								int LEnd = fonts[Font].SubrsOffsets[LSubr+1];								ReadASubr(LStart,LEnd,GBias,LBias,hSubrsUsedNonCID,lSubrsUsedNonCID,fonts[Font].SubrsOffsets);							}						}						SizeOfNonCIDSubrsUsed = lSubrsUsedNonCID.size();					}				}			}		}	}	/**	 * The function reads a subrs (glyph info) between begin and end.	 * Adds calls to a Lsubr to the hSubr and lSubrs.	 * Adds calls to a Gsubr to the hGSubr and lGSubrs.	 * @param begin the start point of the subr	 * @param end the end point of the subr	 * @param GBias the bias of the Global Subrs	 * @param LBias the bias of the Local Subrs	 * @param hSubr the HashMap for the lSubrs	 * @param lSubr the ArrayList for the lSubrs	 */	protected void ReadASubr(int begin,int end,int GBias,int LBias,HashMap hSubr,ArrayList lSubr,int[] LSubrsOffsets)	{		// Clear the stack for the subrs		EmptyStack();		NumOfHints = 0;		// Goto beginning of the subr        seek(begin);        while (getPosition() < end)        {        	// Read the next command        	ReadCommand();        	int pos = getPosition();        	Object TopElement=null;        	if (arg_count > 0)        		TopElement = args[arg_count-1];        	int NumOfArgs = arg_count;        	// Check the modification needed on the Argument Stack according to key;        	HandelStack();        	// a call to a Lsubr        	if (key=="callsubr")         	{        		// Verify that arguments are passed         		if (NumOfArgs > 0)        		{            		// Calc the index of the Subrs            		int Subr = ((Integer)TopElement).intValue() + LBias;            		// If the subr isn't in the HashMap -> Put in        			if (!hSubr.containsKey(new Integer (Subr)))            		{            			hSubr.put(new Integer(Subr),null);            			lSubr.add(new Integer(Subr));            		}        			CalcHints(LSubrsOffsets[Subr],LSubrsOffsets[Subr+1],LBias,GBias,LSubrsOffsets);        			seek(pos);        		}        		        	}        	// a call to a Gsubr        	else if (key=="callgsubr")        	{        		// Verify that arguments are passed         		if (NumOfArgs > 0)        		{	        		// Calc the index of the Subrs	        		int Subr = ((Integer)TopElement).intValue() + GBias;	        		// If the subr isn't in the HashMap -> Put in	        		if (!hGSubrsUsed.containsKey(new Integer (Subr)))	        		{	        			hGSubrsUsed.put(new Integer(Subr),null);	        			lGSubrsUsed.add(new Integer(Subr));	        		}	        		CalcHints(gsubrOffsets[Subr],gsubrOffsets[Subr+1],LBias,GBias,LSubrsOffsets);	        		seek(pos);        		}        	}        	// A call to "stem"        	else if (key == "hstem" || key == "vstem" || key == "hstemhm" || key == "vstemhm")        		// Increment the NumOfHints by the number couples of of arguments        		NumOfHints += NumOfArgs/2;        	// A call to "mask"        	else if (key == "hintmask" || key == "cntrmask")        	{        		// Compute the size of the mask        		int SizeOfMask = NumOfHints/8;        		if (NumOfHints%8 != 0 || SizeOfMask == 0)        			SizeOfMask++;        		// Continue the pointer in SizeOfMask steps        		for (int i=0;i<SizeOfMask;i++)        			getCard8();        	}        }	}	/**	 * Function Checks how the current operator effects the run time stack after being run 	 * An operator may increase or decrease the stack size	 */	protected void HandelStack()	{    	// Find out what the operator does to the stack    	int StackHandel = StackOpp();    	if (StackHandel < 2)    	{    		// The operators that enlarge the stack by one    		if (StackHandel==1)    			PushStack();    		// The operators that pop the stack    		else    		{    			// Abs value for the for loop    			StackHandel *= -1;    			for (int i=0;i<StackHandel;i++)    				PopStack();    		}    		    	}    	// All other flush the stack    	else    		EmptyStack();			}		/**	 * Function checks the key and return the change to the stack after the operator	 * @return The change in the stack. 2-> flush the stack	 */	protected int StackOpp()	{		if (key == "ifelse")			return -3;		if (key == "roll" || key == "put")			return -2;		if (key == "callsubr" || key == "callgsubr" || key == "add" || key == "sub" ||			key == "div" || key == "mul" || key == "drop" || key == "and" || 			key == "or" || key == "eq")			return -1;		if (key == "abs" || key == "neg" || key == "sqrt" || key == "exch" || 			key == "index" || key == "get" || key == "not" || key == "return")			return 0;		if (key == "random" || key == "dup")			return 1;		return 2;	}		/**	 * Empty the Type2 Stack	 *	 */	protected void EmptyStack()	{		// Null the arguments    	for (int i=0; i<arg_count; i++) args[i]=null;        arg_count = 0;			}		/**	 * Pop one element from the stack 	 *	 */	protected void PopStack()	{		if (arg_count>0)		{			args[arg_count-1]=null;			arg_count--;		}	}		/**	 * Add an item to the stack	 *	 */	protected void PushStack()	{		arg_count++;	}		/**	 * The function reads the next command after the file pointer is set	 */	protected void ReadCommand()	{        key = null;        boolean gotKey = false;        // Until a key is found        while (!gotKey) {        	// Read the first Char            char b0 = getCard8();            // decode according to the type1/type2 format            if (b0 == 28) // the two next bytes represent a short int;            {            	int first = getCard8();            	int second = getCard8();            	args[arg_count] = new Integer(first<<8 | second);            	arg_count++;            	continue;            }            if (b0 >= 32 && b0 <= 246) // The byte read is the byte;            {            	args[arg_count] = new Integer(b0 - 139);            	arg_count++;            	continue;            }            if (b0 >= 247 && b0 <= 250) // The byte read and the next byte constitute a short int            {            	int w = getCard8();            	args[arg_count] = new Integer((b0-247)*256 + w + 108);

⌨️ 快捷键说明

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