From 13d6dc3a6a5e8bd3c17997351a0e6f087eb301a2 Mon Sep 17 00:00:00 2001 From: tknall Date: Tue, 25 Nov 2008 12:04:30 +0000 Subject: Removing itext from source. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@302 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../java/com/lowagie/text/pdf/CFFFontSubset.java | 1633 -------------------- 1 file changed, 1633 deletions(-) delete mode 100644 src/main/java/com/lowagie/text/pdf/CFFFontSubset.java (limited to 'src/main/java/com/lowagie/text/pdf/CFFFontSubset.java') diff --git a/src/main/java/com/lowagie/text/pdf/CFFFontSubset.java b/src/main/java/com/lowagie/text/pdf/CFFFontSubset.java deleted file mode 100644 index 111f899..0000000 --- a/src/main/java/com/lowagie/text/pdf/CFFFontSubset.java +++ /dev/null @@ -1,1633 +0,0 @@ -/* - * $Id: CFFFontSubset.java,v 1.3 2005/02/17 09:20:54 blowagie Exp $ - * $Name: $ - * - * 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.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.ArrayList; -import java.io.*; - -/** - * This Class subsets a CFF Type Font. The subset is preformed for CID fonts and NON CID fonts. - * The Charstring is subseted 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 altough 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 - * @author Oren Manor & Ygal Blum - */ -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" - }; - - /** - * 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 Indexs 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 recursivly - */ - 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=0) - { - // Proces 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,Places; - while (i= 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 relevent 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; - 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); - } - - /** - * 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 hasmap-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=0) - { - //Scans the Charsting data storing the used Local and Global subroutines - // by the glyphs. Scans the Subrs recursivley. - 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]); - } - } - } - // 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 Charsting data storing the used Local and Global subroutines - // by the glyphs. Scans the Subrs recursivley. - BuildSubrUsed(Font,-1,fonts[Font].privateSubrs,fonts[Font].SubrsOffsets,hSubrsUsedNonCID,lSubrsUsedNonCID); - } - // For all fonts susbset the Global Subroutines - // Scan the Global Subr Hashmap recursivly on the Gsubrs - BuildGSubrsUsed(Font); - if (fonts[Font].privateSubrs>=0) - // Builds the New Local Subrs index - NewSubrsIndexNonCID = BuildNewIndex(fonts[Font].SubrsOffsets,hSubrsUsedNonCID); - //Builds the New Global Subrs index - NewGSubrsIndex = BuildNewIndex(gsubrOffsets,hGSubrsUsed); - } - - /** - * 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 begining 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 lsub 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 lsub only) is then scaned recursivly 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= 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 recusrivly for Lsubr & Gsubr used - for (int i=0;i=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=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=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 begining 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 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; i0) - { - 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 constetute a short int - { - int w = getCard8(); - args[arg_count] = new Integer((b0-247)*256 + w + 108); - arg_count++; - continue; - } - if (b0 >= 251 && b0 <= 254)// Same as above except negative - { - int w = getCard8(); - args[arg_count] = new Integer(-(b0-251)*256 - w - 108); - arg_count++; - continue; - } - if (b0 == 255)// The next for bytes represent a double. - { - int first = getCard8(); - int second = getCard8(); - int third = getCard8(); - int fourth = getCard8(); - args[arg_count] = new Integer(first<<24 | second<<16 | third<<8 | fourth); - arg_count++; - continue; - } - if (b0<=31 && b0 != 28) // An operator was found.. Set Key. - { - gotKey=true; - // 12 is an escape command therefor the next byte is a part - // of this command - if (b0 == 12) - { - int b1 = getCard8(); - if (b1>SubrsEscapeFuncs.length-1) - b1 = SubrsEscapeFuncs.length-1; - key = SubrsEscapeFuncs[b1]; - } - else - key = SubrsFunctions[b0]; - continue; - } - } - } - - /** - * The function reads the subroutine and returns the number of the hint in it. - * If a call to another subroutine is found the function calls recursively. - * @param begin the start point of the subr - * @param end the end point of the subr - * @param LBias the bias of the Local Subrs - * @param GBias the bias of the Global Subrs - * @param LSubrsOffsets The Offsets array of the subroutines - * @return The number of hints in the subroutine read. - */ - protected int CalcHints(int begin,int end,int LBias,int GBias,int[] LSubrsOffsets) - { - // Goto begining 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") - { - if (NumOfArgs>0) - { - int Subr = ((Integer)TopElement).intValue() + LBias; - CalcHints(LSubrsOffsets[Subr],LSubrsOffsets[Subr+1],LBias,GBias,LSubrsOffsets); - seek(pos); - } - } - // a call to a Gsubr - else if (key=="callgsubr") - { - if (NumOfArgs>0) - { - int Subr = ((Integer)TopElement).intValue() + GBias; - 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>> 8) & 0xff); - NewIndex[Place++] = (byte) ((Count >>> 0) & 0xff); - // Write the offsize field - NewIndex[Place++] = Offsize; - // Write the offset array according to the offsize - for (int i=0;i>> 24) & 0xff); - case 3: - NewIndex[Place++] = (byte) ((Num >>> 16) & 0xff); - case 2: - NewIndex[Place++] = (byte) ((Num >>> 8) & 0xff); - case 1: - NewIndex[Place++] = (byte) ((Num >>> 0) & 0xff); - } - } - // Write the new object array one by one - for (int i=0;i=0) - OutputList.addLast(new RangeItem(buf,fonts[Font].fdselectOffset,fonts[Font].FDSelectLength)); - // Else create a new one - else - CreateFDSelect(fdselectRef,fonts[Font].nglyphs); - - // Copy the Charset - // Mark the beginning and copy entirly - OutputList.addLast(new MarkerItem(charsetRef)); - OutputList.addLast(new RangeItem(buf,fonts[Font].charsetOffset,fonts[Font].CharsetLength)); - - // Copy the FDArray - // If an FDArray exists - if (fonts[Font].fdarrayOffset>=0) - { - // Mark the beginning - OutputList.addLast(new MarkerItem(fdarrayRef)); - // Build a new FDArray with its private dicts and their LSubrs - Reconstruct(Font); - } - else - // Else create a new one - CreateFDArray(fdarrayRef,privateRef,Font); - - } - // If the font is not CID - else - { - // create FDSelect - CreateFDSelect(fdselectRef,fonts[Font].nglyphs); - // recreate a new charset - CreateCharset(charsetRef,fonts[Font].nglyphs); - // create a font dict index (fdarray) - CreateFDArray(fdarrayRef,privateRef,Font); - } - - // if a private dict exists insert its subsetted version - if (fonts[Font].privateOffset>=0) - { - // Mark the beginning of the private dict - IndexBaseItem PrivateBase = new IndexBaseItem(); - OutputList.addLast(PrivateBase); - OutputList.addLast(new MarkerItem(privateRef)); - - OffsetItem Subr = new DictOffsetItem(); - // Build and copy the new private dict - CreateNonCIDPrivate(Font,Subr); - // Copy the new LSubrs index - CreateNonCIDSubrs(Font,PrivateBase,Subr); - } - - // copy the charstring index - OutputList.addLast(new MarkerItem(charstringsRef)); - - // Add the subsetted charstring - OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewCharStringsIndex),0,NewCharStringsIndex.length)); - - // now create the new CFF font - int[] currentOffset = new int[1]; - currentOffset[0] = 0; - // Count and save the offset for each item - Iterator listIter = OutputList.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.increment(currentOffset); - } - // Compute the Xref for each of the offset items - listIter = OutputList.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.xref(); - } - - int size = currentOffset[0]; - byte[] b = new byte[size]; - - // Emit all the items into the new byte array - listIter = OutputList.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.emit(b); - } - // Return the new stream - return b; - } - - /** - * Function Copies the header from the original fileto the output list - */ - protected void CopyHeader() - { - seek(0); - int major = getCard8(); - int minor = getCard8(); - int hdrSize = getCard8(); - int offSize = getCard8(); - nextIndexOffset = hdrSize; - OutputList.addLast(new RangeItem(buf,0,hdrSize)); - } - - /** - * Function Build the header of an index - * @param Count the count field of the index - * @param Offsize the offsize field of the index - * @param First the first offset of the index - */ - protected void BuildIndexHeader(int Count,int Offsize,int First) - { - // Add the count field - OutputList.addLast(new UInt16Item((char)Count)); // count - // Add the offsize field - OutputList.addLast(new UInt8Item((char)Offsize)); // offSize - // Add the first offset according to the offsize - switch(Offsize){ - case 1: - OutputList.addLast(new UInt8Item((char)First)); // first offset - break; - case 2: - OutputList.addLast(new UInt16Item((char)First)); // first offset - break; - case 3: - OutputList.addLast(new UInt24Item((char)First)); // first offset - break; - case 4: - OutputList.addLast(new UInt32Item((char)First)); // first offset - break; - default: - break; - } - } - - /** - * Function adds the keys into the TopDict - * @param fdarrayRef OffsetItem for the FDArray - * @param fdselectRef OffsetItem for the FDSelect - * @param charsetRef OffsetItem for the CharSet - * @param charstringsRef OffsetItem for the CharString - */ - protected void CreateKeys(OffsetItem fdarrayRef,OffsetItem fdselectRef,OffsetItem charsetRef,OffsetItem charstringsRef) - { - // create an FDArray key - OutputList.addLast(fdarrayRef); - OutputList.addLast(new UInt8Item((char)12)); - OutputList.addLast(new UInt8Item((char)36)); - // create an FDSelect key - OutputList.addLast(fdselectRef); - OutputList.addLast(new UInt8Item((char)12)); - OutputList.addLast(new UInt8Item((char)37)); - // create an charset key - OutputList.addLast(charsetRef); - OutputList.addLast(new UInt8Item((char)15)); - // create a CharStrings key - OutputList.addLast(charstringsRef); - OutputList.addLast(new UInt8Item((char)17)); - } - - /** - * Function takes the original string item and adds the new strings - * to accomodate the CID rules - * @param Font the font - */ - protected void CreateNewStringIndex(int Font) - { - String fdFontName = fonts[Font].name+"-OneRange"; - if (fdFontName.length() > 127) - fdFontName = fdFontName.substring(0,127); - String extraStrings = "Adobe"+"Identity"+fdFontName; - - int origStringsLen = stringOffsets[stringOffsets.length-1] - - stringOffsets[0]; - int stringsBaseOffset = stringOffsets[0]-1; - - byte stringsIndexOffSize; - if (origStringsLen+extraStrings.length() <= 0xff) stringsIndexOffSize = 1; - else if (origStringsLen+extraStrings.length() <= 0xffff) stringsIndexOffSize = 2; - else if (origStringsLen+extraStrings.length() <= 0xffffff) stringsIndexOffSize = 3; - else stringsIndexOffSize = 4; - - OutputList.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); // count - OutputList.addLast(new UInt8Item((char)stringsIndexOffSize)); // offSize - for (int i=0; i= 0) - { - OutputList.addLast(new SubrMarkerItem(fdSubrs[i],fdPrivateBase[i])); - OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewLSubrsIndex[i]),0,NewLSubrsIndex[i].length)); - } - } - } - - /** - * Calculates how many byte it took to write the offset for the subrs in a specific - * private dict. - * @param Offset The Offset for the private dict - * @param Size The size of the private dict - * @return The size of the offset of the subrs in the private dict - */ - int CalcSubrOffsetSize(int Offset,int Size) - { - // Set the size to 0 - int OffsetSize = 0; - // Go to the beginning of the private dict - seek(Offset); - // Go until the end of the private dict - while (getPosition() < Offset+Size) - { - int p1 = getPosition(); - getDictItem(); - int p2 = getPosition(); - // When reached to the subrs offset - if (key=="Subrs") { - // The Offsize (minus the subrs key) - OffsetSize = p2-p1-1; - } - // All other keys are ignored - } - // return the size - return OffsetSize; - } - - /** - * Function computes the size of an index - * @param indexOffset The offset for the computed index - * @return The size of the index - */ - protected int countEntireIndexRange(int indexOffset) - { - // Go to the beginning of the index - seek(indexOffset); - // Read the count field - int count = getCard16(); - // If count==0 -> size=2 - if (count==0) - return 2; - else - { - // Read the offsize field - int indexOffSize = getCard8(); - // Go to the last element of the offset array - seek(indexOffset+2+1+count*indexOffSize); - // The size of the object array is the value of the last element-1 - int size = getOffset(indexOffSize)-1; - // Return the size of the entire index - return 2+1+(count+1)*indexOffSize+size; - } - } - - /** - * The function creates a private dict for a font that was not CID - * All the keys are copied as is except for the subrs key - * @param Font the font - * @param Subr The OffsetItem for the subrs of the private - */ - void CreateNonCIDPrivate(int Font,OffsetItem Subr) - { - // Go to the beginning of the private dict and read untill the end - seek(fonts[Font].privateOffset); - while (getPosition() < fonts[Font].privateOffset+fonts[Font].privateLength) - { - int p1 = getPosition(); - getDictItem(); - int p2 = getPosition(); - // If the dictItem is the "Subrs" then, - // use marker for offset and write operator number - if (key=="Subrs") { - OutputList.addLast(Subr); - OutputList.addLast(new UInt8Item((char)19)); // Subrs - } - // Else copy the entire range - else - OutputList.addLast(new RangeItem(buf,p1,p2-p1)); - } - } - - /** - * the function marks the beginning of the subrs index and adds the subsetted subrs - * index to the output list. - * @param Font the font - * @param PrivateBase IndexBaseItem for the private that's referencing to the subrs - * @param Subrs OffsetItem for the subrs - * @throws IOException - */ - void CreateNonCIDSubrs(int Font,IndexBaseItem PrivateBase,OffsetItem Subrs)throws IOException - { - // Mark the beginning of the Subrs index - OutputList.addLast(new SubrMarkerItem(Subrs,PrivateBase)); - // Put the subsetted new subrs index - OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewSubrsIndexNonCID),0,NewSubrsIndexNonCID.length)); - } -} \ No newline at end of file -- cgit v1.2.3