mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Detect font usage inside XObjects as well
This commit is contained in:
parent
c842a82a0f
commit
bf602f48ed
@ -78,14 +78,17 @@ replace_font_references(PDFDoc *self, const std::unordered_map<uint64_t, uint64_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
used_fonts_in_page(PdfPage *page, unordered_reference_set &ans) {
|
used_fonts_in_canvas(PdfCanvas *canvas, unordered_reference_set &ans) {
|
||||||
PdfContentsTokenizer tokenizer(page);
|
PdfContentsTokenizer tokenizer(canvas);
|
||||||
bool in_text_block = false;
|
bool in_text_block = false;
|
||||||
const char* token = NULL;
|
const char* token = NULL;
|
||||||
EPdfContentsType contents_type;
|
EPdfContentsType contents_type;
|
||||||
PdfVariant var;
|
PdfVariant var;
|
||||||
std::stack<PdfVariant> stack;
|
std::stack<PdfVariant> stack;
|
||||||
|
const PdfDictionary &resources = canvas->GetResources()->GetDictionary();
|
||||||
|
if (!resources.HasKey("Font")) return;
|
||||||
|
const PdfDictionary &fonts_dict = resources.GetKey("Font")->GetDictionary();
|
||||||
|
|
||||||
while (tokenizer.ReadNext(contents_type, token, var)) {
|
while (tokenizer.ReadNext(contents_type, token, var)) {
|
||||||
if (contents_type == ePdfContentsType_Variant) stack.push(var);
|
if (contents_type == ePdfContentsType_Variant) stack.push(var);
|
||||||
@ -102,12 +105,13 @@ used_fonts_in_page(PdfPage *page, unordered_reference_set &ans) {
|
|||||||
stack.pop();
|
stack.pop();
|
||||||
if (stack.size() > 0 && stack.top().IsName()) {
|
if (stack.size() > 0 && stack.top().IsName()) {
|
||||||
const PdfName &reference_name = stack.top().GetName();
|
const PdfName &reference_name = stack.top().GetName();
|
||||||
PdfObject* font = page->GetFromResources("Font", reference_name);
|
if (fonts_dict.HasKey(reference_name)) {
|
||||||
if (font) ans.insert(font->Reference());
|
ans.insert(fonts_dict.GetKey(reference_name)->GetReference());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
@ -238,24 +242,35 @@ static PyObject*
|
|||||||
remove_unused_fonts(PDFDoc *self, PyObject *args) {
|
remove_unused_fonts(PDFDoc *self, PyObject *args) {
|
||||||
unsigned long count = 0;
|
unsigned long count = 0;
|
||||||
unordered_reference_set used_fonts;
|
unordered_reference_set used_fonts;
|
||||||
|
// Look in Pages
|
||||||
for (int i = 0; i < self->doc->GetPageCount(); i++) {
|
for (int i = 0; i < self->doc->GetPageCount(); i++) {
|
||||||
PdfPage *page = self->doc->GetPage(i);
|
PdfPage *page = self->doc->GetPage(i);
|
||||||
if (page) used_fonts_in_page(page, used_fonts);
|
if (page) used_fonts_in_canvas(page, used_fonts);
|
||||||
|
}
|
||||||
|
// Look in XObjects
|
||||||
|
PdfVecObjects &objects = self->doc->GetObjects();
|
||||||
|
for (auto &k : objects) {
|
||||||
|
if (k->IsDictionary()) {
|
||||||
|
const PdfDictionary &dict = k->GetDictionary();
|
||||||
|
if (dictionary_has_key_name(dict, PdfName::KeyType, "XObject") && dictionary_has_key_name(dict, PdfName::KeySubtype, "Form")) {
|
||||||
|
PdfXObject xo(k);
|
||||||
|
used_fonts_in_canvas(&xo, used_fonts);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unordered_reference_set all_fonts;
|
unordered_reference_set all_fonts;
|
||||||
unordered_reference_set type3_fonts;
|
unordered_reference_set type3_fonts;
|
||||||
charprocs_usage_map charprocs_usage;
|
charprocs_usage_map charprocs_usage;
|
||||||
PdfVecObjects &objects = self->doc->GetObjects();
|
for (auto &k : objects) {
|
||||||
for (TCIVecObjects it = objects.begin(); it != objects.end(); it++) {
|
if (k->IsDictionary()) {
|
||||||
if ((*it)->IsDictionary()) {
|
const PdfDictionary &dict = k->GetDictionary();
|
||||||
const PdfDictionary &dict = (*it)->GetDictionary();
|
|
||||||
if (dictionary_has_key_name(dict, PdfName::KeyType, "Font")) {
|
if (dictionary_has_key_name(dict, PdfName::KeyType, "Font")) {
|
||||||
const std::string &font_type = dict.GetKey(PdfName::KeySubtype)->GetName().GetName();
|
const std::string &font_type = dict.GetKey(PdfName::KeySubtype)->GetName().GetName();
|
||||||
if (font_type == "Type0") {
|
if (font_type == "Type0") {
|
||||||
all_fonts.insert((*it)->Reference());
|
all_fonts.insert(k->Reference());
|
||||||
} else if (font_type == "Type3") {
|
} else if (font_type == "Type3") {
|
||||||
all_fonts.insert((*it)->Reference());
|
all_fonts.insert(k->Reference());
|
||||||
type3_fonts.insert((*it)->Reference());
|
type3_fonts.insert(k->Reference());
|
||||||
for (auto &x : dict.GetKey("CharProcs")->GetDictionary().GetKeys()) {
|
for (auto &x : dict.GetKey("CharProcs")->GetDictionary().GetKeys()) {
|
||||||
const PdfReference &ref = x.second->GetReference();
|
const PdfReference &ref = x.second->GetReference();
|
||||||
if (charprocs_usage.find(ref) == charprocs_usage.end()) charprocs_usage[ref] = 1;
|
if (charprocs_usage.find(ref) == charprocs_usage.end()) charprocs_usage[ref] = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user