1//========================================================================
2//
3// pdffonts.cc
4//
5// Copyright 2001-2007 Glyph & Cog, LLC
6//
7//========================================================================
8
9//========================================================================
10//
11// Modified under the Poppler project - http://poppler.freedesktop.org
12//
13// All changes made under the Poppler project to this file are licensed
14// under GPL version 2 or later
15//
16// Copyright (C) 2006 Dominic Lachowicz <cinamod@hotmail.com>
17// Copyright (C) 2007-2008, 2010, 2018, 2022 Albert Astals Cid <aacid@kde.org>
18// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
19// Copyright (C) 2012, 2017 Adrian Johnson <ajohnson@redneon.com>
20// Copyright (C) 2013 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
21// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
22// Copyright (C) 2019, 2021 Oliver Sander <oliver.sander@tu-dresden.de>
23//
24// To see a description of the changes please see the Changelog file that
25// came with your tarball or type make ChangeLog if you are building from git
26//
27//========================================================================
28
29#include "config.h"
30#include <poppler-config.h>
31#include <cstdio>
32#include <cstdlib>
33#include <cstddef>
34#include <cmath>
35#include <memory>
36#include <string>
37#include "parseargs.h"
38#include "goo/GooString.h"
39#include "goo/gmem.h"
40#include "GlobalParams.h"
41#include "Object.h"
42#include "PDFDoc.h"
43#include "PDFDocFactory.h"
44#include "FontInfo.h"
45#include "Win32Console.h"
46
47static const char *fontTypeNames[] = { "unknown", "Type 1", "Type 1C", "Type 1C (OT)", "Type 3", "TrueType", "TrueType (OT)", "CID Type 0", "CID Type 0C", "CID Type 0C (OT)", "CID TrueType", "CID TrueType (OT)" };
48
49static int firstPage = 1;
50static int lastPage = 0;
51static bool showSubst = false;
52static char ownerPassword[33] = "\001";
53static char userPassword[33] = "\001";
54static bool printVersion = false;
55static bool printHelp = false;
56
57static const ArgDesc argDesc[] = { { .arg: "-f", .kind: argInt, .val: &firstPage, .size: 0, .usage: "first page to examine" },
58 { .arg: "-l", .kind: argInt, .val: &lastPage, .size: 0, .usage: "last page to examine" },
59 { .arg: "-subst", .kind: argFlag, .val: &showSubst, .size: 0, .usage: "show font substitutions" },
60 { .arg: "-opw", .kind: argString, .val: ownerPassword, .size: sizeof(ownerPassword), .usage: "owner password (for encrypted files)" },
61 { .arg: "-upw", .kind: argString, .val: userPassword, .size: sizeof(userPassword), .usage: "user password (for encrypted files)" },
62 { .arg: "-v", .kind: argFlag, .val: &printVersion, .size: 0, .usage: "print copyright and version info" },
63 { .arg: "-h", .kind: argFlag, .val: &printHelp, .size: 0, .usage: "print usage information" },
64 { .arg: "-help", .kind: argFlag, .val: &printHelp, .size: 0, .usage: "print usage information" },
65 { .arg: "--help", .kind: argFlag, .val: &printHelp, .size: 0, .usage: "print usage information" },
66 { .arg: "-?", .kind: argFlag, .val: &printHelp, .size: 0, .usage: "print usage information" },
67 {} };
68
69int main(int argc, char *argv[])
70{
71 std::optional<GooString> ownerPW, userPW;
72 bool ok;
73
74 Win32Console win32Console(&argc, &argv);
75
76 // parse args
77 ok = parseArgs(args: argDesc, argc: &argc, argv);
78 if (!ok || argc != 2 || printVersion || printHelp) {
79 fprintf(stderr, format: "pdffonts version %s\n", PACKAGE_VERSION);
80 fprintf(stderr, format: "%s\n", popplerCopyright);
81 fprintf(stderr, format: "%s\n", xpdfCopyright);
82 if (!printVersion) {
83 printUsage(program: "pdffonts", otherArgs: "<PDF-file>", args: argDesc);
84 }
85 if (printVersion || printHelp) {
86 return 0;
87 }
88 return 99;
89 }
90
91 std::string fileName(argv[1]);
92 if (fileName == "-") {
93 fileName = "fd://0";
94 }
95
96 // read config file
97 globalParams = std::make_unique<GlobalParams>();
98
99 // open PDF file
100 if (ownerPassword[0] != '\001') {
101 ownerPW = GooString(ownerPassword);
102 }
103 if (userPassword[0] != '\001') {
104 userPW = GooString(userPassword);
105 }
106
107 auto doc = std::unique_ptr<PDFDoc>(PDFDocFactory().createPDFDoc(uri: GooString(fileName), ownerPassword: ownerPW, userPassword: userPW));
108
109 if (!doc->isOk()) {
110 return 1;
111 }
112
113 // get page range
114 if (firstPage < 1) {
115 firstPage = 1;
116 }
117 if (lastPage < 1 || lastPage > doc->getNumPages()) {
118 lastPage = doc->getNumPages();
119 }
120 if (lastPage < firstPage) {
121 fprintf(stderr, format: "Wrong page range given: the first page (%d) can not be after the last page (%d).\n", firstPage, lastPage);
122 return 99;
123 }
124
125 // get the fonts
126 {
127 FontInfoScanner scanner(doc.get(), firstPage - 1);
128 const std::vector<FontInfo *> fonts = scanner.scan(nPages: lastPage - firstPage + 1);
129
130 if (showSubst) {
131 // print the font substitutions
132 printf(format: "name object ID substitute font substitute font file\n");
133 printf(format: "------------------------------------ --------- ------------------------------------ ------------------------------------\n");
134 for (const FontInfo *font : fonts) {
135 if (font->getFile()) {
136 printf(format: "%-36s", font->getName() ? font->getName()->c_str() : "[none]");
137 const Ref fontRef = font->getRef();
138 if (fontRef.gen >= 100000) {
139 printf(format: " [none]");
140 } else {
141 printf(format: " %6d %2d", fontRef.num, fontRef.gen);
142 }
143 printf(format: " %-36s %s\n", font->getSubstituteName() ? font->getSubstituteName()->c_str() : "[none]", font->getFile()->c_str());
144 }
145 delete font;
146 }
147 } else {
148 // print the font info
149 printf(format: "name type encoding emb sub uni object ID\n");
150 printf(format: "------------------------------------ ----------------- ---------------- --- --- --- ---------\n");
151 for (const FontInfo *font : fonts) {
152 printf(format: "%-36s %-17s %-16s %-3s %-3s %-3s", font->getName() ? font->getName()->c_str() : "[none]", fontTypeNames[font->getType()], font->getEncoding().c_str(), font->getEmbedded() ? "yes" : "no",
153 font->getSubset() ? "yes" : "no", font->getToUnicode() ? "yes" : "no");
154 const Ref fontRef = font->getRef();
155 if (fontRef.gen >= 100000) {
156 printf(format: " [none]\n");
157 } else {
158 printf(format: " %6d %2d\n", fontRef.num, fontRef.gen);
159 }
160 delete font;
161 }
162 }
163 }
164
165 return 0;
166}
167

source code of poppler/utils/pdffonts.cc