30#include <osl/file.hxx>
34#include <com/sun/star/beans/XPropertySet.hpp>
35#include <com/sun/star/embed/ElementModes.hpp>
36#include <com/sun/star/embed/XTransactedObject.hpp>
37#include <com/sun/star/embed/XStorage.hpp>
38#include <com/sun/star/frame/XModel.hpp>
39#include <com/sun/star/ucb/SimpleFileAccess.hpp>
40#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
41#include <com/sun/star/style/XStyle.hpp>
42#include <com/sun/star/container/XNameAccess.hpp>
54class XMLFontAutoStylePoolEntry_Impl
61 rtl_TextEncoding eEnc;
65 inline XMLFontAutoStylePoolEntry_Impl(
71 rtl_TextEncoding eEnc );
73 inline XMLFontAutoStylePoolEntry_Impl(
78 rtl_TextEncoding eEnc );
81 const OUString& GetFamilyName()
const {
return sFamilyName; }
82 const OUString& GetStyleName()
const {
return sStyleName; }
83 FontFamily GetFamily()
const {
return nFamily; }
84 FontPitch GetPitch()
const {
return nPitch; }
85 rtl_TextEncoding GetEncoding()
const {
return eEnc; }
90inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
96 rtl_TextEncoding eE ) :
98 sFamilyName(
std::move( aFamilyName )),
99 sStyleName(
std::move( aStyleName )),
106inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
107 OUString rFamilyName,
111 rtl_TextEncoding eE ) :
112 sFamilyName(
std::move( rFamilyName )),
113 sStyleName(
std::move( rStyleName )),
122struct XMLFontAutoStylePoolEntryCmp_Impl {
124 std::unique_ptr<XMLFontAutoStylePoolEntry_Impl>
const& r1,
125 std::unique_ptr<XMLFontAutoStylePoolEntry_Impl>
const& r2 )
const
127 bool bEnc1(r1->GetEncoding() != RTL_TEXTENCODING_SYMBOL);
128 bool bEnc2(r2->GetEncoding() != RTL_TEXTENCODING_SYMBOL);
130 return bEnc1 < bEnc2;
131 else if( r1->GetPitch() != r2->GetPitch() )
132 return r1->GetPitch() < r2->GetPitch();
133 else if( r1->GetFamily() != r2->GetFamily() )
134 return r1->GetFamily() < r2->GetFamily();
137 sal_Int32 nCmp = r1->GetFamilyName().compareTo( r2->GetFamilyName() );
139 return r1->GetStyleName().compareTo( r2->GetStyleName() ) < 0;
155 m_bTryToEmbedFonts( bTryToEmbedFonts ),
156 m_bEmbedUsedOnly(false),
157 m_bEmbedLatinScript(true),
158 m_bEmbedAsianScript(true),
159 m_bEmbedComplexScript(true)
168 const OUString& rFamilyName,
169 const OUString& rStyleName,
172 rtl_TextEncoding eEnc )
175 XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
180 sPoolName = (*it)->GetName();
185 sal_Int32 nLen = rFamilyName.indexOf(
';' );
192 sName = rFamilyName.copy( 0, nLen );
196 if(
sName.isEmpty() )
210 std::unique_ptr<XMLFontAutoStylePoolEntry_Impl> pEntry(
211 new XMLFontAutoStylePoolEntry_Impl(
sName, rFamilyName, rStyleName,
212 nFamily, nPitch, eEnc ));
221 const OUString& rFamilyName,
222 const OUString& rStyleName,
225 rtl_TextEncoding eEnc )
const
228 XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
233 sName = (*it)->GetName();
242OUString lcl_checkFontFile(
const OUString &fileUrl )
244 osl::DirectoryItem aDirItem;
245 if( osl::DirectoryItem::get( fileUrl, aDirItem ) == osl::File::E_None )
247 osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
248 if( aDirItem.getFileStatus( aStatus ) == osl::File::E_None )
250 if( !aStatus.isDirectory() )
258struct EmbeddedFontInfo
266OUString FontWeightToString(
FontWeight eWeight)
284OUString FontItalicToString(
FontItalic eWeight)
305 std::unordered_set<OUString> aReturnSet;
307 uno::Reference<style::XStyleFamiliesSupplier> xFamiliesSupp(
GetExport().GetModel(), UNO_QUERY);
308 if (!xFamiliesSupp.is())
312 uno::Reference<container::XNameAccess> xFamilies(xFamiliesSupp->getStyleFamilies());
315 const uno::Sequence<OUString> aFamilyNames = xFamilies->getElementNames();
316 for (OUString
const & sFamilyName : aFamilyNames)
318 uno::Reference<container::XNameAccess> xStyleContainer;
319 xFamilies->getByName(sFamilyName) >>= xStyleContainer;
321 if (xStyleContainer.is())
323 const uno::Sequence<OUString> aStyleNames = xStyleContainer->getElementNames();
324 for (OUString
const & rName : aStyleNames)
326 uno::Reference<style::XStyle> xStyle;
327 xStyleContainer->getByName(rName) >>= xStyle;
328 if (xStyle->isInUse())
330 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, UNO_QUERY);
331 uno::Reference<beans::XPropertySetInfo> xInfo(xPropertySet ? xPropertySet->getPropertySetInfo() :
nullptr);
336 OUString sCharFontName;
337 Any aFontAny = xPropertySet->getPropertyValue(
"CharFontName");
338 aFontAny >>= sCharFontName;
339 if (!sCharFontName.isEmpty())
340 aReturnSet.insert(sCharFontName);
344 OUString sCharFontNameAsian;
345 Any aFontAny = xPropertySet->getPropertyValue(
"CharFontNameAsian");
346 aFontAny >>= sCharFontNameAsian;
347 if (!sCharFontNameAsian.isEmpty())
348 aReturnSet.insert(sCharFontNameAsian);
352 OUString sCharFontNameComplex;
353 Any aFontAny = xPropertySet->getPropertyValue(
"CharFontNameComplex");
354 aFontAny >>= sCharFontNameComplex;
355 if (!sCharFontNameComplex.isEmpty())
356 aReturnSet.insert(sCharFontNameComplex);
370 for (
auto const & rAutoStyleEntry : aAutoStyleEntries)
372 for (
auto const & rPair : rAutoStyleEntry.m_aXmlProperties)
374 if (rPair.first ==
"font-name" ||
375 rPair.first ==
"font-weight-asian" ||
376 rPair.first ==
"font-weight-complex")
378 if (rPair.second.has<OUString>())
380 OUString sFontName = rPair.second.get<OUString>();
381 if (!sFontName.isEmpty())
382 aReturnSet.insert(sFontName);
404 std::map<OUString, OUString> fontFilesMap;
406 std::unordered_set<OUString> aUsedFontNames;
411 std::vector<XMLFontAutoStylePoolEntry_Impl*> aFontAutoStyles;
414 aFontAutoStyles.push_back(pEntry.get());
417 aFontAutoStyles.begin(), aFontAutoStyles.end(),
418 [](
const XMLFontAutoStylePoolEntry_Impl* pA, XMLFontAutoStylePoolEntry_Impl* pB) ->
bool {
419 return pA->GetName() < pB->GetName();
422 for (
const auto& pEntry : aFontAutoStyles)
426 aAny <<= pEntry->GetFamilyName();
427 if (aFamilyNameHdl.
exportXML(sTmp, aAny, rUnitConv))
431 const OUString& rStyleName = pEntry->GetStyleName();
432 if (!rStyleName.isEmpty())
437 aAny <<= static_cast<sal_Int16>(pEntry->GetFamily());
438 if (aFamilyHdl.
exportXML(sTmp, aAny, rUnitConv))
443 aAny <<= static_cast<sal_Int16>(pEntry->GetPitch());
444 if (aPitchHdl.
exportXML(sTmp, aAny, rUnitConv))
450 aAny <<= static_cast<sal_Int16>(pEntry->GetEncoding());
451 if (aEncHdl.
exportXML( sTmp, aAny, rUnitConv))
463 std::vector<EmbeddedFontInfo> aEmbeddedFonts;
464 static const std::vector<std::pair<FontWeight, FontItalic>> aCombinations =
472 for (
auto const & aCombinationPair : aCombinations)
477 pEntry->GetFamilyName(), pEntry->GetFamily(),
478 aCombinationPair.second, aCombinationPair.first, pEntry->GetPitch(),
480 if (sFileUrl.isEmpty())
485 aUsedFontNames.find(pEntry->GetFamilyName()) != aUsedFontNames.end())
487 if (!fontFilesMap.count(sFileUrl))
489 const OUString docUrl = bExportFlat ?
490 lcl_checkFontFile(sFileUrl) :
embedFontFile(sFileUrl, pEntry->GetFamilyName());
491 if (!docUrl.isEmpty())
492 fontFilesMap[sFileUrl] = docUrl;
496 EmbeddedFontInfo aEmbeddedFont;
497 aEmbeddedFont.aURL = sFileUrl;
498 aEmbeddedFont.eWeight = aCombinationPair.first;
499 aEmbeddedFont.eItalic = aCombinationPair.second;
500 aEmbeddedFonts.push_back(aEmbeddedFont);
503 if (!aEmbeddedFonts.empty())
506 for (EmbeddedFontInfo
const & rEmbeddedFont : aEmbeddedFonts)
508 if (fontFilesMap.count(rEmbeddedFont.aURL))
513 fontFilesMap[rEmbeddedFont.aURL]);
520 FontItalicToString(rEmbeddedFont.eItalic));
522 FontWeightToString(rEmbeddedFont.eWeight));
529 const uno::Reference<ucb::XSimpleFileAccess> xFileAccess(
533 const uno::Reference<io::XInputStream> xInput(xFileAccess->openFileRead(fontFilesMap[rEmbeddedFont.aURL]));
537 catch (
const uno::Exception &)
553static OUString
getFreeFontName(uno::Reference<embed::XStorage>
const & rxStorage, OUString
const & rFamilyName)
560 rFamilyName.replaceAll(
" ",
"_") +
"_" +
561 OUString::number(
nIndex) +
".ttf";
563 }
while (rxStorage->hasByName(
sName));
570 std::stringstream aStringStream;
571 for (
auto const & rByte : rHash)
573 aStringStream << std::setw(2) << std::setfill(
'0') << std::hex <<
int(rByte);
576 return OString(aStringStream.str());
582 osl::File aFile(rFileUrl);
583 if (aFile.open(osl_File_OpenFlag_Read) != osl::File::E_None)
590 sal_uInt64 nReadSize;
592 if (aFile.isEndOfFile(&bEof) != osl::File::E_None)
594 SAL_WARN(
"xmloff",
"Error reading font file " << rFileUrl);
599 if (aFile.read(
aBuffer, 4096, nReadSize) != osl::File::E_None)
601 SAL_WARN(
"xmloff",
"Error reading font file " << rFileUrl);
606 aHashEngine.
update(
reinterpret_cast<unsigned char*
>(
aBuffer), nReadSize);
619 osl::File file( fileUrl );
620 if( file.open( osl_File_OpenFlag_Read ) != osl::File::E_None )
623 if ( !
GetExport().GetTargetStorage().is() )
626 uno::Reference< embed::XStorage > storage;
627 storage.set(
GetExport().GetTargetStorage()->openStorageElement(
"Fonts",
628 ::embed::ElementModes::WRITE ), uno::UNO_SET_THROW );
632 uno::Reference< io::XOutputStream > outputStream;
633 outputStream.set( storage->openStreamElement(
name, ::embed::ElementModes::WRITE ), UNO_QUERY_THROW );
634 uno::Reference < beans::XPropertySet > propertySet( outputStream, uno::UNO_QUERY );
635 assert( propertySet.is());
636 propertySet->setPropertyValue(
"MediaType",
uno::Any( OUString(
"application/x-font-ttf" )));
642 if( file.isEndOfFile( &eof ) != osl::File::E_None )
644 SAL_WARN(
"xmloff",
"Error reading font file " << fileUrl );
645 outputStream->closeOutput();
650 if( file.read( buffer, 4096, readSize ) != osl::File::E_None )
652 SAL_WARN(
"xmloff",
"Error reading font file " << fileUrl );
653 outputStream->closeOutput();
659 outputStream->writeBytes(uno::Sequence<sal_Int8>(buffer, readSize));
661 outputStream->closeOutput();
664 Reference< embed::XTransactedObject > transaction( storage, UNO_QUERY );
665 if( transaction.is())
667 transaction->commit();
668 OUString sInternalName =
"Fonts/" +
name;
670 return sInternalName;
static OUString getFreeFontName(uno::Reference< embed::XStorage > const &rxStorage, OUString const &rFamilyName)
static OString convertToHashString(std::vector< unsigned char > const &rHash)
static OString getFileHash(OUString const &rFileUrl)
static OUString fontFileUrl(std::u16string_view familyName, FontFamily family, FontItalic italic, FontWeight weight, FontPitch pitch, FontRights rights)
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
rtl::Reference< SvXMLAutoStylePoolP > const & GetAutoStylePool()
virtual void collectAutoStyles()
const SvXMLUnitConverter & GetMM100UnitConverter() const
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
bool exportOfficeBinaryDataElement(const css::uno::Reference< css::io::XInputStream > &rIn)
std::unique_ptr< XMLFontAutoStylePool_Impl > m_pFontAutoStylePool
OUString embedFontFile(OUString const &rFileUrl, OUString const &rFamilyName)
OUString Find(const OUString &rFamilyName, const OUString &rStyleName, FontFamily nFamily, FontPitch nPitch, rtl_TextEncoding eEnc) const
std::set< OUString > m_aNames
std::unordered_map< OString, OUString > m_aEmbeddedFontFiles
bool m_bEmbedComplexScript
SvXMLExport & GetExport()
virtual ~XMLFontAutoStylePool() override
XMLFontAutoStylePool(SvXMLExport &rExport, bool tryToEmbedFonts=false)
OUString Add(const OUString &rFamilyName, const OUString &rStyleName, FontFamily nFamily, FontPitch nPitch, rtl_TextEncoding eEnc)
std::unordered_set< OUString > getUsedFontList()
PropertyHandler for the XML-data-type:
virtual bool exportXML(OUString &rStrExpValue, const css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Exports the given value according to the XML-data-type corresponding to the derived class.
PropertyHandler for the XML-data-type:
virtual bool exportXML(OUString &rStrExpValue, const css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Exports the given value according to the XML-data-type corresponding to the derived class.
PropertyHandler for the XML-data-type:
virtual bool exportXML(OUString &rStrExpValue, const css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Exports the given value according to the XML-data-type corresponding to the derived class.
PropertyHandler for the XML-data-type:
virtual bool exportXML(OUString &rStrExpValue, const css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Exports the given value according to the XML-data-type corresponding to the derived class.
std::vector< unsigned char > finalize()
void update(const unsigned char *pInput, size_t length)
std::vector< Value >::const_iterator const_iterator
#define TOOLS_WARN_EXCEPTION(area, stream)
virtual OUString GetName() const override
#define SAL_WARN(area, stream)
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
Handling of tokens in XML:
@ XML_FONT_FAMILY_GENERIC
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
std::unique_ptr< char[]> aBuffer
constexpr sal_uInt16 XML_NAMESPACE_XLINK
constexpr sal_uInt16 XML_NAMESPACE_SVG
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
constexpr sal_uInt16 XML_NAMESPACE_STYLE