tdf#162002 DOCX import: ignore subsetted embedded fonts for editing
Open the bugdoc, some characters use a fallback font, some not, while the same font is used in Word for all characters. It turns out that the bugdoc has a subsetted embedded font, and the font only has 8 glyphs, which explains the inconsistent rendering. Fix the problem by ignoring subsetted fonts for the editing case: if a font is subsetted then only use the embedded font for viewing. First also had to fix up the tokenizer, as it had the wrong type for the subsetted attribute, so we couldn't get its boolean value (OOXMLStringValue doesn't override getInt(), so OOXMLValue::getInt() returns 0 unconditionally). Note that in theory we can have embedded fonts which are nominally subsetted but in practice they have a "reasonable" amount of glyphs in them, those are currently discarded, but should be probably still kept in a follow-up change. Change-Id: I3e6dfbb246d464fede64f183a3f244edc70e7b8a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170397 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This commit is contained in:
parent
f5685bdfff
commit
a9f3c11375
8 changed files with 73 additions and 8 deletions
|
@ -22,6 +22,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,sw_writerfilter_dmapper, \
|
|||
sw/qa/writerfilter/dmapper/DomainMapperTableManager \
|
||||
sw/qa/writerfilter/dmapper/DomainMapper \
|
||||
sw/qa/writerfilter/dmapper/DomainMapper_Impl \
|
||||
sw/qa/writerfilter/dmapper/FontTable \
|
||||
sw/qa/writerfilter/dmapper/GraphicImport \
|
||||
sw/qa/writerfilter/dmapper/NumberingManager \
|
||||
sw/qa/writerfilter/dmapper/TableManager \
|
||||
|
|
44
sw/qa/writerfilter/dmapper/FontTable.cxx
Normal file
44
sw/qa/writerfilter/dmapper/FontTable.cxx
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <test/unoapi_test.hxx>
|
||||
|
||||
#include <vcl/embeddedfontshelper.hxx>
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
||||
namespace
|
||||
{
|
||||
/// Tests for sw/source/writerfilter/dmapper/FontTable.cxx.
|
||||
class Test : public UnoApiTest
|
||||
{
|
||||
public:
|
||||
Test()
|
||||
: UnoApiTest(u"/sw/qa/writerfilter/dmapper/data/"_ustr)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testSubsettedEmbeddedFont)
|
||||
{
|
||||
// Given a document with a subsetted embedded font, loaded for editing:
|
||||
loadFromFile(u"subsetted-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 not available, given that the newly inserted characters
|
||||
// during editing may be missing from the subsetted font:
|
||||
CPPUNIT_ASSERT(aUrl.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
BIN
sw/qa/writerfilter/dmapper/data/subsetted-embedded-font.docx
Normal file
BIN
sw/qa/writerfilter/dmapper/data/subsetted-embedded-font.docx
Normal file
Binary file not shown.
|
@ -382,6 +382,7 @@ DomainMapper_Impl::DomainMapper_Impl(
|
|||
m_xAltChunkStartingRange(rMediaDesc.getUnpackedValueOrDefault(u"AltChunkStartingRange"_ustr, uno::Reference<text::XTextRange>())),
|
||||
m_bIsNewDoc(!rMediaDesc.getUnpackedValueOrDefault(u"InsertMode"_ustr, false)),
|
||||
m_bIsAltChunk(rMediaDesc.getUnpackedValueOrDefault(u"AltChunkMode"_ustr, false)),
|
||||
m_bReadOnly(rMediaDesc.getUnpackedValueOrDefault(u"ReadOnly"_ustr, false)),
|
||||
m_bIsReadGlossaries(rMediaDesc.getUnpackedValueOrDefault(u"ReadGlossaries"_ustr, false)),
|
||||
m_bHasFtnSep(false),
|
||||
m_bIsSplitPara(false),
|
||||
|
|
|
@ -697,6 +697,8 @@ public:
|
|||
private:
|
||||
bool m_bIsNewDoc;
|
||||
bool m_bIsAltChunk = false;
|
||||
/// Document is loaded for viewing, not editing.
|
||||
bool m_bReadOnly = false;
|
||||
bool m_bIsReadGlossaries;
|
||||
|
||||
public:
|
||||
|
@ -861,7 +863,7 @@ public:
|
|||
FontTablePtr const & GetFontTable()
|
||||
{
|
||||
if(!m_pFontTable)
|
||||
m_pFontTable = new FontTable();
|
||||
m_pFontTable = new FontTable(m_bReadOnly);
|
||||
return m_pFontTable;
|
||||
}
|
||||
StyleSheetTablePtr const & GetStyleSheetTable()
|
||||
|
|
|
@ -37,14 +37,18 @@ struct FontTable_Impl
|
|||
std::unique_ptr<EmbeddedFontsHelper, o3tl::default_delete<EmbeddedFontsHelper>> xEmbeddedFontHelper;
|
||||
std::vector< FontEntry::Pointer_t > aFontEntries;
|
||||
FontEntry::Pointer_t pCurrentEntry;
|
||||
FontTable_Impl() {}
|
||||
bool m_bReadOnly;
|
||||
FontTable_Impl(bool bReadOnly)
|
||||
: m_bReadOnly(bReadOnly)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
FontTable::FontTable()
|
||||
FontTable::FontTable(bool bReadOnly)
|
||||
: LoggedProperties("FontTable")
|
||||
, LoggedTable("FontTable")
|
||||
, LoggedStream("FontTable")
|
||||
, m_pImpl( new FontTable_Impl )
|
||||
, m_pImpl( new FontTable_Impl(bReadOnly) )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -225,6 +229,11 @@ sal_uInt32 FontTable::size()
|
|||
return m_pImpl->aFontEntries.size();
|
||||
}
|
||||
|
||||
bool FontTable::IsReadOnly() const
|
||||
{
|
||||
return m_pImpl->m_bReadOnly;
|
||||
}
|
||||
|
||||
void FontTable::addEmbeddedFont(const css::uno::Reference<css::io::XInputStream>& stream,
|
||||
const OUString& fontName, std::u16string_view extra,
|
||||
std::vector<unsigned char> const & key)
|
||||
|
@ -246,6 +255,12 @@ 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
|
||||
|
@ -279,8 +294,8 @@ void EmbeddedFontHandler::lcl_attribute( Id name, Value& val )
|
|||
case NS_ooxml::LN_CT_Rel_id:
|
||||
break;
|
||||
case NS_ooxml::LN_CT_FontRel_subsetted:
|
||||
break; // TODO? Let's just ignore this for now and hope
|
||||
// it doesn't break anything.
|
||||
m_bSubsetted = static_cast<bool>(val.getInt());
|
||||
break;
|
||||
case NS_ooxml::LN_inputstream: // the actual font data as stream
|
||||
val.getAny() >>= m_inputStream;
|
||||
break;
|
||||
|
|
|
@ -45,7 +45,7 @@ class FontTable : public LoggedProperties, public LoggedTable
|
|||
std::unique_ptr<FontTable_Impl> m_pImpl;
|
||||
|
||||
public:
|
||||
FontTable();
|
||||
FontTable(bool bReadOnly);
|
||||
virtual ~FontTable() override;
|
||||
|
||||
sal_uInt32 size();
|
||||
|
@ -54,6 +54,7 @@ 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);
|
||||
bool IsReadOnly() const;
|
||||
|
||||
private:
|
||||
// Properties
|
||||
|
@ -98,6 +99,7 @@ private:
|
|||
std::u16string_view m_style;
|
||||
OUString m_fontKey;
|
||||
css::uno::Reference<css::io::XInputStream> m_inputStream;
|
||||
bool m_bSubsetted = false;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -16386,7 +16386,7 @@
|
|||
<data type="string"/>
|
||||
</attribute>
|
||||
<attribute name="subsetted">
|
||||
<data type="string"/>
|
||||
<ref name="ST_OnOff"/>
|
||||
</attribute>
|
||||
</define>
|
||||
<define name="CT_Font">
|
||||
|
|
Loading…
Reference in a new issue