mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
sfntly: Do not segfault for fonts that dont have loca tables. Also nicer error messages for such fonts.
This commit is contained in:
parent
18805c4c68
commit
062dbe2bbe
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
static PyObject *Error = NULL;
|
static PyObject *Error = NULL;
|
||||||
static PyObject *NoGlyphs = NULL;
|
static PyObject *NoGlyphs = NULL;
|
||||||
|
static PyObject *UnsupportedFont = NULL;
|
||||||
|
|
||||||
// Predicates {{{
|
// Predicates {{{
|
||||||
CompositePredicate::CompositePredicate(IntegerSet &chars, IntegerList &ranges) :
|
CompositePredicate::CompositePredicate(IntegerSet &chars, IntegerList &ranges) :
|
||||||
@ -112,11 +113,15 @@ FontSourcedInfoBuilder::FontSourcedInfoBuilder(Font* font,
|
|||||||
FontSourcedInfoBuilder::~FontSourcedInfoBuilder() { }
|
FontSourcedInfoBuilder::~FontSourcedInfoBuilder() { }
|
||||||
|
|
||||||
CALLER_ATTACH FontInfo* FontSourcedInfoBuilder::GetFontInfo() {
|
CALLER_ATTACH FontInfo* FontSourcedInfoBuilder::GetFontInfo() {
|
||||||
|
if (!cmap_) {
|
||||||
|
PyErr_SetString(Error, "This font has no cmap table!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
CharacterMap* chars_to_glyph_ids = new CharacterMap;
|
CharacterMap* chars_to_glyph_ids = new CharacterMap;
|
||||||
bool success = GetCharacterMap(chars_to_glyph_ids);
|
bool success = GetCharacterMap(chars_to_glyph_ids);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
delete chars_to_glyph_ids;
|
delete chars_to_glyph_ids;
|
||||||
PyErr_SetString(Error, "Error creating character map.\n");
|
if (!PyErr_Occurred()) PyErr_SetString(Error, "Error creating character map.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
GlyphIdSet* resolved_glyph_ids = new GlyphIdSet;
|
GlyphIdSet* resolved_glyph_ids = new GlyphIdSet;
|
||||||
@ -124,7 +129,7 @@ CALLER_ATTACH FontInfo* FontSourcedInfoBuilder::GetFontInfo() {
|
|||||||
if (!success) {
|
if (!success) {
|
||||||
delete chars_to_glyph_ids;
|
delete chars_to_glyph_ids;
|
||||||
delete resolved_glyph_ids;
|
delete resolved_glyph_ids;
|
||||||
PyErr_SetString(Error, "Error resolving composite glyphs.\n");
|
if (!PyErr_Occurred()) PyErr_SetString(Error, "Error resolving composite glyphs.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Ptr<FontInfo> font_info = new FontInfo;
|
Ptr<FontInfo> font_info = new FontInfo;
|
||||||
@ -178,6 +183,10 @@ bool FontSourcedInfoBuilder::ResolveCompositeGlyphs(CharacterMap* chars_to_glyph
|
|||||||
// As long as there are unresolved glyph ids.
|
// As long as there are unresolved glyph ids.
|
||||||
while (!unresolved_glyph_ids->empty()) {
|
while (!unresolved_glyph_ids->empty()) {
|
||||||
// Get the corresponding glyph.
|
// Get the corresponding glyph.
|
||||||
|
if (!loca_table_) {
|
||||||
|
PyErr_SetString(UnsupportedFont, "This font does not have a loca table. Subsetting is not supported for fonts without loca tables (usually OTF fonts with PostScript (CFF) outlines).");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
int32_t glyph_id = *(unresolved_glyph_ids->begin());
|
int32_t glyph_id = *(unresolved_glyph_ids->begin());
|
||||||
unresolved_glyph_ids->erase(unresolved_glyph_ids->begin());
|
unresolved_glyph_ids->erase(unresolved_glyph_ids->begin());
|
||||||
if (glyph_id < 0 || glyph_id > loca_table_->num_glyphs()) {
|
if (glyph_id < 0 || glyph_id > loca_table_->num_glyphs()) {
|
||||||
@ -189,6 +198,10 @@ bool FontSourcedInfoBuilder::ResolveCompositeGlyphs(CharacterMap* chars_to_glyph
|
|||||||
}
|
}
|
||||||
int32_t offset = loca_table_->GlyphOffset(glyph_id);
|
int32_t offset = loca_table_->GlyphOffset(glyph_id);
|
||||||
GlyphPtr glyph;
|
GlyphPtr glyph;
|
||||||
|
if (!glyph_table_) {
|
||||||
|
PyErr_SetString(UnsupportedFont, "This font does not have a glyf table. Subsetting is not supported for fonts without glyf tables (usually OTF fonts with PostScript (CFF) outlines).");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
glyph.Attach(glyph_table_->GetGlyph(offset, length));
|
glyph.Attach(glyph_table_->GetGlyph(offset, length));
|
||||||
if (glyph == NULL) {
|
if (glyph == NULL) {
|
||||||
continue;
|
continue;
|
||||||
@ -449,7 +462,7 @@ CALLER_ATTACH Font* PredicateSubsetter::Subset() {
|
|||||||
Ptr<FontInfo> font_info;
|
Ptr<FontInfo> font_info;
|
||||||
font_info.Attach(info_builder->GetFontInfo());
|
font_info.Attach(info_builder->GetFontInfo());
|
||||||
if (!font_info) {
|
if (!font_info) {
|
||||||
PyErr_SetString(Error, "Could not create font info");
|
if (!PyErr_Occurred()) PyErr_SetString(Error, "Could not create font info");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,6 +613,10 @@ initsfntly(void) {
|
|||||||
NoGlyphs = PyErr_NewException((char*)"sfntly.NoGlyphs", NULL, NULL);
|
NoGlyphs = PyErr_NewException((char*)"sfntly.NoGlyphs", NULL, NULL);
|
||||||
if (NoGlyphs == NULL) return;
|
if (NoGlyphs == NULL) return;
|
||||||
PyModule_AddObject(m, "NoGlyphs", NoGlyphs);
|
PyModule_AddObject(m, "NoGlyphs", NoGlyphs);
|
||||||
|
|
||||||
|
UnsupportedFont = PyErr_NewException((char*)"sfntly.UnsupportedFont", NULL, NULL);
|
||||||
|
if (UnsupportedFont == NULL) return;
|
||||||
|
PyModule_AddObject(m, "UnsupportedFont", UnsupportedFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user