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

com.itextpdf.io.font.cmap.CMapParser Maven / Gradle / Ivy

There is a newer version: 9.0.0
Show newest version
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    This program is offered under a commercial and under the AGPL license.
    For commercial licensing, contact us at https://itextpdf.com/sales.  For AGPL licensing, see below.

    AGPL licensing:
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see .
 */
package com.itextpdf.io.font.cmap;

import com.itextpdf.io.logs.IoLogMessageConstant;
import com.itextpdf.io.source.PdfTokenizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

public class CMapParser {

    private static final String def = "def";
    private static final String endcidrange = "endcidrange";
    private static final String endcidchar = "endcidchar";
    private static final String endbfrange = "endbfrange";
    private static final String endbfchar = "endbfchar";
    private static final String endcodespacerange = "endcodespacerange";
    private static final String usecmap = "usecmap";

    private static final String Registry = "Registry";
    private static final String Ordering = "Ordering";
    private static final String Supplement = "Supplement";
    private static final String CMapName = "CMapName";

    private static final int MAX_LEVEL = 10;

    public static void parseCid(String cmapName, AbstractCMap cmap, ICMapLocation location) throws java.io.IOException {
        parseCid(cmapName, cmap, location, 0);
    }

    private static void parseCid(String cmapName, AbstractCMap cmap, ICMapLocation location, int level) throws java.io.IOException {
        if (level >= MAX_LEVEL)
            return;
        PdfTokenizer inp = location.getLocation(cmapName);
        try {
            List list = new ArrayList<>();
            CMapContentParser cp = new CMapContentParser(inp);
            int maxExc = 50;
            while (true) {
                try {
                    cp.parse(list);
                } catch (Exception ex) {
                    if (--maxExc < 0)
                        break;
                    continue;
                }
                if (list.size() == 0)
                    break;
                String last = list.get(list.size() - 1).toString();
                if (level == 0 && list.size() == 3 && last.equals(def)) {
                    CMapObject cmapObject = list.get(0);
                    if (Registry.equals(cmapObject.toString())) {
                        cmap.setRegistry(list.get(1).toString());
                    } else if (Ordering.equals(cmapObject.toString())) {
                        cmap.setOrdering(list.get(1).toString());
                    } else if (CMapName.equals(cmapObject.toString())) {
                        cmap.setName(list.get(1).toString());
                    } else if (Supplement.equals(cmapObject.toString())) {
                        try {
                            cmap.setSupplement((int) list.get(1).getValue());
                        } catch (Exception ignored) {
                        }
                    }
                } else if ((last.equals(endcidchar) || last.equals(endbfchar)) && list.size() >= 3) {
                    int lMax = list.size() - 2;
                    for (int k = 0; k < lMax; k += 2) {
                        if (list.get(k).isString()) {
                            cmap.addChar(list.get(k).toString(), list.get(k + 1));
                        }
                    }
                } else if ((last.equals(endcidrange) || last.equals(endbfrange)) && list.size() >= 4) {
                    int lMax = list.size() - 3;
                    for (int k = 0; k < lMax; k += 3) {
                        if (list.get(k).isString() && list.get(k + 1).isString()) {
                            cmap.addRange(list.get(k).toString(), list.get(k + 1).toString(), list.get(k + 2));
                        }
                    }
                } else if (last.equals(usecmap) && list.size() == 2 && list.get(0).isName()) {
                    parseCid(list.get(0).toString(), cmap, location, level + 1);
                } else if (last.equals(endcodespacerange)) {
                    for (int i = 0; i < list.size() + 1; i += 2) {
                        if (list.get(i).isHexString() && list.get(i + 1).isHexString()) {
                            byte[] low = list.get(i).toHexByteArray();
                            byte[] high = list.get(i + 1).toHexByteArray();
                            cmap.addCodeSpaceRange(low, high);
                        }
                    }
                }
            }
        } catch (Exception ex) {
            Logger logger = LoggerFactory.getLogger(CMapParser.class);
            logger.error(IoLogMessageConstant.UNKNOWN_ERROR_WHILE_PROCESSING_CMAP);
        } finally {
            inp.close();
        }
    }

//    private static void encodeSequence(int size, byte[] seqs, char cid, ArrayList planes) {
//        --size;
//        int nextPlane = 0;
//        for (int idx = 0; idx < size; ++idx) {
//            char[] plane = planes.get(nextPlane);
//            int one = seqs[idx] & 0xff;
//            char c = plane[one];
//            if (c != 0 && (c & 0x8000) == 0)
//                throw new PdfRuntimeException("inconsistent.mapping");
//            if (c == 0) {
//                planes.add(new char[256]);
//                c = (char) (planes.size() - 1 | 0x8000);
//                plane[one] = c;
//            }
//            nextPlane = c & 0x7fff;
//        }
//        char[] plane = planes.get(nextPlane);
//        int one = seqs[size] & 0xff;
//        char c = plane[one];
//        if ((c & 0x8000) != 0)
//            throw new PdfRuntimeException("inconsistent.mapping");
//        plane[one] = cid;
//    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy