mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Optionally get font data when listing fonts
This commit is contained in:
parent
0705abf946
commit
929f65ecf2
@ -75,6 +75,8 @@ used_fonts_in_page(PdfPage *page, int page_num, PyObject *ans) {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
PyObject*
|
PyObject*
|
||||||
list_fonts(PDFDoc *self, PyObject *args) {
|
list_fonts(PDFDoc *self, PyObject *args) {
|
||||||
|
int get_font_data = 0;
|
||||||
|
if (!PyArg_ParseTuple(args, "|i", &get_font_data)) return NULL;
|
||||||
pyunique_ptr ans(PyList_New(0));
|
pyunique_ptr ans(PyList_New(0));
|
||||||
if (!ans) return NULL;
|
if (!ans) return NULL;
|
||||||
try {
|
try {
|
||||||
@ -88,15 +90,20 @@ list_fonts(PDFDoc *self, PyObject *args) {
|
|||||||
const PdfReference &ref = (*it)->Reference();
|
const PdfReference &ref = (*it)->Reference();
|
||||||
unsigned long num = ref.ObjectNumber(), generation = ref.GenerationNumber();
|
unsigned long num = ref.ObjectNumber(), generation = ref.GenerationNumber();
|
||||||
const PdfObject *descriptor = (*it)->GetIndirectKey("FontDescriptor");
|
const PdfObject *descriptor = (*it)->GetIndirectKey("FontDescriptor");
|
||||||
long long stream_len = 0;
|
pyunique_ptr descendant_font, stream_ref, encoding;
|
||||||
pyunique_ptr descendant_font, stream_ref;
|
PyBytesOutputStream stream_data;
|
||||||
|
if (dict.HasKey("Encoding") && dict.GetKey("Encoding")->IsName()) {
|
||||||
|
encoding.reset(PyUnicode_FromString(dict.GetKey("Encoding")->GetName().GetName().c_str()));
|
||||||
|
}
|
||||||
if (descriptor) {
|
if (descriptor) {
|
||||||
const PdfObject *ff = get_font_file(descriptor);
|
const PdfObject *ff = get_font_file(descriptor);
|
||||||
if (ff) {
|
if (ff) {
|
||||||
stream_ref.reset(ref_as_tuple(ff->Reference()));
|
stream_ref.reset(ref_as_tuple(ff->Reference()));
|
||||||
if (!stream_ref) return NULL;
|
if (!stream_ref) return NULL;
|
||||||
const PdfStream *stream = ff->GetStream();
|
const PdfStream *stream = ff->GetStream();
|
||||||
if (stream) stream_len = stream->GetLength();
|
if (stream && get_font_data) {
|
||||||
|
stream->GetCopy(&stream_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (dict.HasKey("DescendantFonts")) {
|
} else if (dict.HasKey("DescendantFonts")) {
|
||||||
const PdfArray &df = dict.GetKey("DescendantFonts")->GetArray();
|
const PdfArray &df = dict.GetKey("DescendantFonts")->GetArray();
|
||||||
@ -105,13 +112,14 @@ list_fonts(PDFDoc *self, PyObject *args) {
|
|||||||
}
|
}
|
||||||
#define V(x) (x ? x.get() : Py_None)
|
#define V(x) (x ? x.get() : Py_None)
|
||||||
pyunique_ptr d(Py_BuildValue(
|
pyunique_ptr d(Py_BuildValue(
|
||||||
"{ss ss s(kk) sL sO sO}",
|
"{ss ss s(kk) sO sO sO sO}",
|
||||||
"BaseFont", name.c_str(),
|
"BaseFont", name.c_str(),
|
||||||
"Subtype", subtype.c_str(),
|
"Subtype", subtype.c_str(),
|
||||||
"Reference", num, generation,
|
"Reference", num, generation,
|
||||||
"Length", stream_len,
|
"Data", V(stream_data),
|
||||||
"DescendantFont", V(descendant_font),
|
"DescendantFont", V(descendant_font),
|
||||||
"StreamRef", V(stream_ref)
|
"StreamRef", V(stream_ref),
|
||||||
|
"Encoding", V(encoding)
|
||||||
));
|
));
|
||||||
#undef V
|
#undef V
|
||||||
if (!d) { return NULL; }
|
if (!d) { return NULL; }
|
||||||
|
@ -50,6 +50,32 @@ struct PyObjectDeleter {
|
|||||||
// unique_ptr that uses Py_XDECREF as the destructor function.
|
// unique_ptr that uses Py_XDECREF as the destructor function.
|
||||||
typedef std::unique_ptr<PyObject, PyObjectDeleter> pyunique_ptr;
|
typedef std::unique_ptr<PyObject, PyObjectDeleter> pyunique_ptr;
|
||||||
|
|
||||||
|
class PyBytesOutputStream : public PdfOutputStream {
|
||||||
|
private:
|
||||||
|
pyunique_ptr bytes;
|
||||||
|
PyBytesOutputStream( const PyBytesOutputStream & ) ;
|
||||||
|
PyBytesOutputStream & operator=( const PyBytesOutputStream & ) ;
|
||||||
|
public:
|
||||||
|
PyBytesOutputStream() : bytes() {}
|
||||||
|
void Close() {}
|
||||||
|
operator bool() const { return bool(bytes); }
|
||||||
|
PyObject* get() const { return bytes.get(); }
|
||||||
|
pdf_long Write(const char *buf, const pdf_long sz){
|
||||||
|
if (!bytes) {
|
||||||
|
bytes.reset(PyBytes_FromStringAndSize(buf, sz));
|
||||||
|
if (!bytes) throw PdfError(ePdfError_OutOfMemory, __FILE__, __LINE__, NULL);
|
||||||
|
} else {
|
||||||
|
size_t old_sz = PyBytes_GET_SIZE(bytes.get());
|
||||||
|
PyObject *old = bytes.release();
|
||||||
|
if (_PyBytes_Resize(&old, old_sz + sz) != 0) throw PdfError(ePdfError_OutOfMemory, __FILE__, __LINE__, NULL);
|
||||||
|
memcpy(PyBytes_AS_STRING(old) + old_sz, buf, sz);
|
||||||
|
bytes.reset(old);
|
||||||
|
}
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static inline bool
|
static inline bool
|
||||||
dictionary_has_key_name(const PdfDictionary &d, T key, const char *name) {
|
dictionary_has_key_name(const PdfDictionary &d, T key, const char *name) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user