tdf#162002 DOCX import, font embed: only discard subset fonts with few glyphs
Commit a9f3c11375525a7708378dd3648febc40db1ad20 (tdf#162002 DOCX import: ignore subsetted embedded fonts for editing, 2024-07-12) decided to ignore all subsetted fonts for editing, improve this a little so we only ignore subsetted fonts when they can't even provide an English alphabet in any form (lowercase, uppercase). This avoids the possible problem that a font is marked as subsetted but it's good enough in practice and we would still throw it away for editing. Change-Id: I0bc0e14ffc0c039f029220991bd16d9e3254f059 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170570 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
This commit is contained in:
parent
828b26bdc2
commit
09da7fd9ce
@ -66,7 +66,8 @@ public:
|
||||
*/
|
||||
bool addEmbeddedFont( const css::uno::Reference< css::io::XInputStream >& stream,
|
||||
const OUString& fontName, std::u16string_view extra,
|
||||
std::vector< unsigned char > const & key, bool eot = false);
|
||||
std::vector< unsigned char > const & key, bool eot = false,
|
||||
bool bSubsetted = false);
|
||||
|
||||
/**
|
||||
Returns a URL for a file where to store contents of a given temporary font.
|
||||
|
@ -39,6 +39,24 @@ CPPUNIT_TEST_FIXTURE(Test, testSubsettedEmbeddedFont)
|
||||
// during editing may be missing from the subsetted font:
|
||||
CPPUNIT_ASSERT(aUrl.isEmpty());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testSubsettedFullEmbeddedFont)
|
||||
{
|
||||
#if !defined(MACOSX) // FIXME fails on macOS
|
||||
// Given a document with an embedded font (marked as subsetted, but otherwise full in practice),
|
||||
// loaded for editing:
|
||||
loadFromFile(u"subsetted-full-embedded-font.docx");
|
||||
|
||||
// When checking if the font is available:
|
||||
OUString aUrl = EmbeddedFontsHelper::fontFileUrl(
|
||||
u"IBM Plex Serif Light", FAMILY_ROMAN, ITALIC_NONE, WEIGHT_NORMAL, PITCH_VARIABLE,
|
||||
EmbeddedFontsHelper::FontRights::ViewingAllowed);
|
||||
|
||||
// Then make sure the subsetted font is available, given that it has the reasonable amount of
|
||||
// glyphs:
|
||||
CPPUNIT_ASSERT(!aUrl.isEmpty());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
Binary file not shown.
@ -236,11 +236,13 @@ bool FontTable::IsReadOnly() const
|
||||
|
||||
void FontTable::addEmbeddedFont(const css::uno::Reference<css::io::XInputStream>& stream,
|
||||
const OUString& fontName, std::u16string_view extra,
|
||||
std::vector<unsigned char> const & key)
|
||||
std::vector<unsigned char> const & key,
|
||||
bool bSubsetted)
|
||||
{
|
||||
if (!m_pImpl->xEmbeddedFontHelper)
|
||||
m_pImpl->xEmbeddedFontHelper.reset(new EmbeddedFontsHelper);
|
||||
m_pImpl->xEmbeddedFontHelper->addEmbeddedFont(stream, fontName, extra, key);
|
||||
m_pImpl->xEmbeddedFontHelper->addEmbeddedFont(stream, fontName, extra, key,
|
||||
/*eot=*/false, bSubsetted);
|
||||
}
|
||||
|
||||
EmbeddedFontHandler::EmbeddedFontHandler(FontTable& rFontTable, OUString _fontName, std::u16string_view style )
|
||||
@ -256,11 +258,6 @@ EmbeddedFontHandler::~EmbeddedFontHandler()
|
||||
if( !m_inputStream.is())
|
||||
return;
|
||||
|
||||
if (m_bSubsetted && !m_fontTable.IsReadOnly())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector< unsigned char > key( 32 );
|
||||
if( !m_fontKey.isEmpty())
|
||||
{ // key for unobfuscating
|
||||
@ -280,7 +277,9 @@ EmbeddedFontHandler::~EmbeddedFontHandler()
|
||||
key[ i + 16 ] = val;
|
||||
}
|
||||
}
|
||||
m_fontTable.addEmbeddedFont( m_inputStream, m_fontName, m_style, key );
|
||||
// Ignore the "subsetted" flag if we're not editing anyway.
|
||||
bool bSubsetted = m_bSubsetted && !m_fontTable.IsReadOnly();
|
||||
m_fontTable.addEmbeddedFont( m_inputStream, m_fontName, m_style, key, bSubsetted );
|
||||
m_inputStream->closeInput();
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,8 @@ class FontTable : public LoggedProperties, public LoggedTable
|
||||
|
||||
void addEmbeddedFont(const css::uno::Reference<css::io::XInputStream>& stream,
|
||||
const OUString& fontName, std::u16string_view extra,
|
||||
std::vector<unsigned char> const & key);
|
||||
std::vector<unsigned char> const & key,
|
||||
bool bSubsetted);
|
||||
bool IsReadOnly() const;
|
||||
|
||||
private:
|
||||
|
@ -66,7 +66,8 @@ void EmbeddedFontsHelper::clearTemporaryFontFiles()
|
||||
}
|
||||
|
||||
bool EmbeddedFontsHelper::addEmbeddedFont( const uno::Reference< io::XInputStream >& stream, const OUString& fontName,
|
||||
std::u16string_view extra, std::vector< unsigned char > const & key, bool eot )
|
||||
std::u16string_view extra, std::vector< unsigned char > const & key, bool eot,
|
||||
bool bSubsetted )
|
||||
{
|
||||
OUString fileUrl = EmbeddedFontsHelper::fileUrlForTemporaryFont( fontName, extra );
|
||||
osl::File file( fileUrl );
|
||||
@ -159,6 +160,37 @@ bool EmbeddedFontsHelper::addEmbeddedFont( const uno::Reference< io::XInputStrea
|
||||
osl::File::remove( fileUrl );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bSubsetted)
|
||||
{
|
||||
TrueTypeFont* font;
|
||||
sal_uInt32 nGlyphs = 0;
|
||||
if (OpenTTFontBuffer(fontData.data(), fontData.size(), 0, &font) == SFErrCodes::Ok)
|
||||
{
|
||||
sal_uInt32 nGlyphCount = font->glyphCount();
|
||||
for (sal_uInt32 i = 0; i < nGlyphCount; ++i)
|
||||
{
|
||||
sal_uInt32 nOffset = font->glyphOffset(i);
|
||||
sal_uInt32 nNextOffset = font->glyphOffset(i + 1);
|
||||
if (nOffset == nNextOffset)
|
||||
{
|
||||
// GetTTGlyphComponents() says this is an empty glyph, ignore it.
|
||||
continue;
|
||||
}
|
||||
++nGlyphs;
|
||||
}
|
||||
CloseTTFont(font);
|
||||
}
|
||||
// Check if it has reasonable amount of glyphs, set the limit to the number of glyphs in the
|
||||
// English alphabet (not differentiating lowercase and uppercase).
|
||||
if (nGlyphs < 26)
|
||||
{
|
||||
SAL_INFO("vcl.fonts", "Ignoring embedded font that only provides " << nGlyphs << " non-empty glyphs");
|
||||
osl::File::remove(fileUrl);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_aAccumulatedFonts.emplace_back(std::make_pair(fontName, fileUrl));
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user