mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Code to list fonts in a PDF file
This commit is contained in:
parent
e575be49e3
commit
c4e3fda682
@ -116,7 +116,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "podofo",
|
"name": "podofo",
|
||||||
"sources": "calibre/utils/podofo/utils.cpp calibre/utils/podofo/output.cpp calibre/utils/podofo/doc.cpp calibre/utils/podofo/outline.cpp calibre/utils/podofo/podofo.cpp",
|
"sources": "calibre/utils/podofo/utils.cpp calibre/utils/podofo/output.cpp calibre/utils/podofo/doc.cpp calibre/utils/podofo/outline.cpp calibre/utils/podofo/fonts.cpp calibre/utils/podofo/podofo.cpp",
|
||||||
"headers": "calibre/utils/podofo/global.h",
|
"headers": "calibre/utils/podofo/global.h",
|
||||||
"libraries": "podofo",
|
"libraries": "podofo",
|
||||||
"lib_dirs": "!podofo_lib",
|
"lib_dirs": "!podofo_lib",
|
||||||
|
@ -142,21 +142,14 @@ def get_image_count(path):
|
|||||||
return p.image_count()
|
return p.image_count()
|
||||||
|
|
||||||
|
|
||||||
def test_outline(src):
|
def test_list_fonts(src):
|
||||||
podofo = get_podofo()
|
podofo = get_podofo()
|
||||||
p = podofo.PDFDoc()
|
p = podofo.PDFDoc()
|
||||||
with open(src, 'rb') as f:
|
with open(src, 'rb') as f:
|
||||||
raw = f.read()
|
raw = f.read()
|
||||||
p.load(raw)
|
p.load(raw)
|
||||||
total = p.page_count()
|
import pprint
|
||||||
root = p.create_outline('Table of Contents')
|
pprint.pprint(p.list_fonts())
|
||||||
for i in range(0, total):
|
|
||||||
root.create('Page %d'%i, i, True)
|
|
||||||
raw = p.write()
|
|
||||||
out = '/tmp/outlined.pdf'
|
|
||||||
with open(out, 'wb') as f:
|
|
||||||
f.write(raw)
|
|
||||||
print('Outlined PDF:', out)
|
|
||||||
|
|
||||||
|
|
||||||
def test_save_to(src, dest):
|
def test_save_to(src, dest):
|
||||||
|
@ -429,15 +429,6 @@ PDFDoc_extract_anchors(PDFDoc *self, PyObject *args) {
|
|||||||
|
|
||||||
// alter_links() {{{
|
// alter_links() {{{
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static inline bool
|
|
||||||
dictionary_has_key_name(PdfDictionary &d, T key, const char *name) {
|
|
||||||
const PdfObject *val = d.GetKey(key);
|
|
||||||
if (val && val->IsName() && val->GetName().GetName() == name) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
PDFDoc_alter_links(PDFDoc *self, PyObject *args) {
|
PDFDoc_alter_links(PDFDoc *self, PyObject *args) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -724,6 +715,9 @@ static PyMethodDef PDFDoc_methods[] = {
|
|||||||
{"alter_links", (PyCFunction)PDFDoc_alter_links, METH_VARARGS,
|
{"alter_links", (PyCFunction)PDFDoc_alter_links, METH_VARARGS,
|
||||||
"alter_links() -> Change links in the document."
|
"alter_links() -> Change links in the document."
|
||||||
},
|
},
|
||||||
|
{"list_fonts", (PyCFunction)list_fonts, METH_VARARGS,
|
||||||
|
"list_fonts() -> Get list of fonts in document"
|
||||||
|
},
|
||||||
{"delete_page", (PyCFunction)PDFDoc_delete_page, METH_VARARGS,
|
{"delete_page", (PyCFunction)PDFDoc_delete_page, METH_VARARGS,
|
||||||
"delete_page(page_num) -> Delete the specified page from the pdf (0 is the first page)."
|
"delete_page(page_num) -> Delete the specified page from the pdf (0 is the first page)."
|
||||||
},
|
},
|
||||||
|
55
src/calibre/utils/podofo/fonts.cpp
Normal file
55
src/calibre/utils/podofo/fonts.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* fonts.cpp
|
||||||
|
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the GPL3 license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace pdf;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
PyObject*
|
||||||
|
list_fonts(PDFDoc *self, PyObject *args) {
|
||||||
|
pyunique_ptr ans(PyList_New(0));
|
||||||
|
if (!ans) return NULL;
|
||||||
|
try {
|
||||||
|
const PdfVecObjects &objects = self->doc->GetObjects();
|
||||||
|
for (TCIVecObjects it = objects.begin(); it != objects.end(); it++) {
|
||||||
|
if ((*it)->IsDictionary()) {
|
||||||
|
const PdfDictionary &dict = (*it)->GetDictionary();
|
||||||
|
if (dictionary_has_key_name(dict, PdfName::KeyType, "Font") && dict.HasKey("BaseFont")) {
|
||||||
|
const string &name = dict.GetKey("BaseFont")->GetName().GetName();
|
||||||
|
const string &subtype = dict.GetKey(PdfName::KeySubtype)->GetName().GetName();
|
||||||
|
const PdfReference &ref = (*it)->Reference();
|
||||||
|
unsigned long num = ref.ObjectNumber(), generation = ref.GenerationNumber();
|
||||||
|
const PdfObject *descriptor = (*it)->GetIndirectKey("FontDescriptor");
|
||||||
|
long long stream_len = 0;
|
||||||
|
if (descriptor) {
|
||||||
|
const PdfObject *ff = descriptor->GetIndirectKey("FontFile");
|
||||||
|
if (!ff) ff = descriptor->GetIndirectKey("FontFile2");
|
||||||
|
if (!ff) ff = descriptor->GetIndirectKey("FontFile3");
|
||||||
|
const PdfStream *stream = ff->GetStream();
|
||||||
|
if (stream) stream_len = stream->GetLength();
|
||||||
|
}
|
||||||
|
pyunique_ptr d(Py_BuildValue(
|
||||||
|
"{sssss(kk)sL}",
|
||||||
|
"BaseFont", name.c_str(),
|
||||||
|
"Subtype", subtype.c_str(),
|
||||||
|
"Reference", num, generation,
|
||||||
|
"Length", stream_len));
|
||||||
|
if (!d) { return NULL; }
|
||||||
|
if (PyList_Append(ans.get(), d.get()) != 0) return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (const PdfError &err) {
|
||||||
|
podofo_set_exception(err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ans.release();
|
||||||
|
}
|
||||||
|
}
|
@ -41,4 +41,24 @@ void podofo_set_exception(const PdfError &err);
|
|||||||
PyObject * podofo_convert_pdfstring(const PdfString &s);
|
PyObject * podofo_convert_pdfstring(const PdfString &s);
|
||||||
const PdfString podofo_convert_pystring(PyObject *py);
|
const PdfString podofo_convert_pystring(PyObject *py);
|
||||||
PyObject* write_doc(PdfMemDocument *doc, PyObject *f);
|
PyObject* write_doc(PdfMemDocument *doc, PyObject *f);
|
||||||
|
|
||||||
|
struct PyObjectDeleter {
|
||||||
|
void operator()(PyObject *obj) {
|
||||||
|
Py_XDECREF(obj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// unique_ptr that uses Py_XDECREF as the destructor function.
|
||||||
|
typedef std::unique_ptr<PyObject, PyObjectDeleter> pyunique_ptr;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline bool
|
||||||
|
dictionary_has_key_name(const PdfDictionary &d, T key, const char *name) {
|
||||||
|
const PdfObject *val = d.GetKey(key);
|
||||||
|
if (val && val->IsName() && val->GetName().GetName() == name) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
PyObject* list_fonts(PDFDoc*, PyObject*);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user