29 #include <osl/file.hxx>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/embed/ElementModes.hpp>
35 #include <com/sun/star/embed/XTransactedObject.hpp>
36 #include <com/sun/star/embed/XStorage.hpp>
37 #include <com/sun/star/frame/XModel.hpp>
38 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
39 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
40 #include <com/sun/star/style/XStyle.hpp>
41 #include <com/sun/star/container/XNameAccess.hpp>
53 class XMLFontAutoStylePoolEntry_Impl
60 rtl_TextEncoding eEnc;
64 inline XMLFontAutoStylePoolEntry_Impl(
65 const OUString& rName,
66 const OUString& rFamilyName,
67 const OUString& rStyleName,
70 rtl_TextEncoding eEnc );
72 inline XMLFontAutoStylePoolEntry_Impl(
73 const OUString& rFamilyName,
74 const OUString& rStyleName,
77 rtl_TextEncoding eEnc );
79 const OUString&
GetName()
const {
return sName; }
80 const OUString& GetFamilyName()
const {
return sFamilyName; }
81 const OUString& GetStyleName()
const {
return sStyleName; }
82 FontFamily GetFamily()
const {
return nFamily; }
83 FontPitch GetPitch()
const {
return nPitch; }
84 rtl_TextEncoding GetEncoding()
const {
return eEnc; }
89 inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
90 const OUString& rName,
91 const OUString& rFamilyName,
92 const OUString& rStyleName,
95 rtl_TextEncoding eE ) :
97 sFamilyName( rFamilyName ),
98 sStyleName( rStyleName ),
105 inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
106 const OUString& rFamilyName,
107 const OUString& rStyleName,
110 rtl_TextEncoding eE ) :
111 sFamilyName( rFamilyName ),
112 sStyleName( rStyleName ),
121 struct XMLFontAutoStylePoolEntryCmp_Impl {
123 std::unique_ptr<XMLFontAutoStylePoolEntry_Impl>
const& r1,
124 std::unique_ptr<XMLFontAutoStylePoolEntry_Impl>
const& r2 )
const
126 bool bEnc1(r1->GetEncoding() != RTL_TEXTENCODING_SYMBOL);
127 bool bEnc2(r2->GetEncoding() != RTL_TEXTENCODING_SYMBOL);
129 return bEnc1 < bEnc2;
130 else if( r1->GetPitch() != r2->GetPitch() )
131 return r1->GetPitch() < r2->GetPitch();
132 else if( r1->GetFamily() != r2->GetFamily() )
133 return r1->GetFamily() < r2->GetFamily();
136 sal_Int32 nCmp = r1->GetFamilyName().compareTo( r2->GetFamilyName() );
138 return r1->GetStyleName().compareTo( r2->GetStyleName() ) < 0;
154 m_bTryToEmbedFonts( bTryToEmbedFonts ),
155 m_bEmbedUsedOnly(
false),
156 m_bEmbedLatinScript(true),
157 m_bEmbedAsianScript(true),
158 m_bEmbedComplexScript(true)
167 const OUString& rFamilyName,
168 const OUString& rStyleName,
171 rtl_TextEncoding eEnc )
174 XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
179 sPoolName = (*it)->GetName();
184 sal_Int32 nLen = rFamilyName.indexOf(
';' );
191 sName = rFamilyName.copy( 0, nLen );
192 sName = sName.trim();
195 if( sName.isEmpty() )
202 sName = sPrefix + OUString::number( nCount );
205 sName = sPrefix + OUString::number( ++nCount );
209 std::unique_ptr<XMLFontAutoStylePoolEntry_Impl> pEntry(
210 new XMLFontAutoStylePoolEntry_Impl( sName, rFamilyName, rStyleName,
211 nFamily, nPitch, eEnc ));
220 const OUString& rFamilyName,
221 const OUString& rStyleName,
224 rtl_TextEncoding eEnc )
const
227 XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
232 sName = (*it)->GetName();
241 OUString lcl_checkFontFile(
const OUString &fileUrl )
243 osl::DirectoryItem aDirItem;
244 if( osl::DirectoryItem::get( fileUrl, aDirItem ) == osl::File::E_None )
246 osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
247 if( aDirItem.getFileStatus( aStatus ) == osl::File::E_None )
249 if( !aStatus.isDirectory() )
257 struct EmbeddedFontInfo
265 OUString FontWeightToString(
FontWeight eWeight)
283 OUString FontItalicToString(
FontItalic eWeight)
304 std::unordered_set<OUString> aReturnSet;
306 uno::Reference<style::XStyleFamiliesSupplier> xFamiliesSupp(
GetExport().GetModel(), UNO_QUERY);
307 if (!xFamiliesSupp.is())
311 uno::Reference<container::XNameAccess> xFamilies(xFamiliesSupp->getStyleFamilies());
314 const uno::Sequence<OUString> aFamilyNames = xFamilies->getElementNames();
315 for (OUString
const & sFamilyName : aFamilyNames)
317 uno::Reference<container::XNameAccess> xStyleContainer;
318 xFamilies->getByName(sFamilyName) >>= xStyleContainer;
320 if (xStyleContainer.is())
322 const uno::Sequence<OUString> aStyleNames = xStyleContainer->getElementNames();
323 for (OUString
const & rName : aStyleNames)
325 uno::Reference<style::XStyle> xStyle;
326 xStyleContainer->getByName(rName) >>= xStyle;
327 if (xStyle->isInUse())
329 uno::Reference<beans::XPropertySet> xPropertySet(xStyle, UNO_QUERY);
330 if (xPropertySet.is())
332 uno::Reference<beans::XPropertySetInfo> xInfo(xPropertySet->getPropertySetInfo());
335 OUString sCharFontName;
336 Any aFontAny = xPropertySet->getPropertyValue(
"CharFontName");
337 aFontAny >>= sCharFontName;
338 if (!sCharFontName.isEmpty())
339 aReturnSet.insert(sCharFontName);
343 OUString sCharFontNameAsian;
344 Any aFontAny = xPropertySet->getPropertyValue(
"CharFontNameAsian");
345 aFontAny >>= sCharFontNameAsian;
346 if (!sCharFontNameAsian.isEmpty())
347 aReturnSet.insert(sCharFontNameAsian);
351 OUString sCharFontNameComplex;
352 Any aFontAny = xPropertySet->getPropertyValue(
"CharFontNameComplex");
353 aFontAny >>= sCharFontNameComplex;
354 if (!sCharFontNameComplex.isEmpty())
355 aReturnSet.insert(sCharFontNameComplex);
369 for (
auto const & rAutoStyleEntry : aAutoStyleEntries)
371 for (
auto const & rPair : rAutoStyleEntry.m_aXmlProperties)
373 if (rPair.first ==
"font-name" ||
374 rPair.first ==
"font-weight-asian" ||
375 rPair.first ==
"font-weight-complex")
377 if (rPair.second.has<OUString>())
379 OUString sFontName = rPair.second.get<OUString>();
380 if (!sFontName.isEmpty())
381 aReturnSet.insert(sFontName);
403 std::map<OUString, OUString> fontFilesMap;
405 std::unordered_set<OUString> aUsedFontNames;
410 std::vector<XMLFontAutoStylePoolEntry_Impl*> aFontAutoStyles;
413 aFontAutoStyles.push_back(pEntry.get());
416 aFontAutoStyles.begin(), aFontAutoStyles.end(),
417 [](
const XMLFontAutoStylePoolEntry_Impl* pA, XMLFontAutoStylePoolEntry_Impl* pB) ->
bool {
418 return pA->GetName() < pB->GetName();
421 for (
const auto& pEntry : aFontAutoStyles)
425 aAny <<= pEntry->GetFamilyName();
426 if (aFamilyNameHdl.
exportXML(sTmp, aAny, rUnitConv))
430 const OUString& rStyleName = pEntry->GetStyleName();
431 if (!rStyleName.isEmpty())
436 aAny <<= static_cast<sal_Int16>(pEntry->GetFamily());
437 if (aFamilyHdl.
exportXML(sTmp, aAny, rUnitConv))
442 aAny <<= static_cast<sal_Int16>(pEntry->GetPitch());
443 if (aPitchHdl.
exportXML(sTmp, aAny, rUnitConv))
449 aAny <<= static_cast<sal_Int16>(pEntry->GetEncoding());
450 if (aEncHdl.
exportXML( sTmp, aAny, rUnitConv))
462 std::vector<EmbeddedFontInfo> aEmbeddedFonts;
463 static const std::vector<std::pair<FontWeight, FontItalic>> aCombinations =
471 for (
auto const & aCombinationPair : aCombinations)
476 pEntry->GetFamilyName(), pEntry->GetFamily(),
477 aCombinationPair.second, aCombinationPair.first, pEntry->GetPitch(),
479 if (sFileUrl.isEmpty())
484 aUsedFontNames.find(pEntry->GetFamilyName()) != aUsedFontNames.end())
486 if (!fontFilesMap.count(sFileUrl))
488 const OUString docUrl = bExportFlat ?
489 lcl_checkFontFile(sFileUrl) :
embedFontFile(sFileUrl, pEntry->GetFamilyName());
490 if (!docUrl.isEmpty())
491 fontFilesMap[sFileUrl] = docUrl;
495 EmbeddedFontInfo aEmbeddedFont;
496 aEmbeddedFont.aURL = sFileUrl;
497 aEmbeddedFont.eWeight = aCombinationPair.first;
498 aEmbeddedFont.eItalic = aCombinationPair.second;
499 aEmbeddedFonts.push_back(aEmbeddedFont);
502 if (!aEmbeddedFonts.empty())
505 for (EmbeddedFontInfo
const & rEmbeddedFont : aEmbeddedFonts)
507 if (fontFilesMap.count(rEmbeddedFont.aURL))
512 fontFilesMap[rEmbeddedFont.aURL]);
519 FontItalicToString(rEmbeddedFont.eItalic));
521 FontWeightToString(rEmbeddedFont.eWeight));
528 const uno::Reference<ucb::XSimpleFileAccess> xFileAccess(
532 const uno::Reference<io::XInputStream> xInput(xFileAccess->openFileRead(fontFilesMap[rEmbeddedFont.aURL]));
534 aBase64Exp.exportOfficeBinaryDataElement(xInput);
536 catch (
const uno::Exception &)
552 static OUString
getFreeFontName(uno::Reference<embed::XStorage>
const & rxStorage, OUString
const & rFamilyName)
559 rFamilyName.replaceAll(
" ",
"_") +
"_" +
560 OUString::number(nIndex) +
".ttf";
562 }
while (rxStorage->hasByName(sName));
569 std::stringstream aStringStream;
570 for (
auto const & rByte : rHash)
572 aStringStream << std::setw(2) << std::setfill(
'0') << std::hex <<
int(rByte);
575 return aStringStream.str().c_str();
581 osl::File aFile(rFileUrl);
582 if (aFile.open(osl_File_OpenFlag_Read) != osl::File::E_None)
589 sal_uInt64 nReadSize;
591 if (aFile.isEndOfFile(&bEof) != osl::File::E_None)
593 SAL_WARN(
"xmloff",
"Error reading font file " << rFileUrl);
598 if (aFile.read(aBuffer, 4096, nReadSize) != osl::File::E_None)
600 SAL_WARN(
"xmloff",
"Error reading font file " << rFileUrl);
605 aHashEngine.
update(reinterpret_cast<unsigned char*>(aBuffer), nReadSize);
618 osl::File file( fileUrl );
619 if( file.open( osl_File_OpenFlag_Read ) != osl::File::E_None )
625 uno::Reference< embed::XStorage > storage;
626 storage.set(
GetExport().GetTargetStorage()->openStorageElement(
"Fonts",
627 ::embed::ElementModes::WRITE ), uno::UNO_SET_THROW );
631 uno::Reference< io::XOutputStream > outputStream;
632 outputStream.set( storage->openStreamElement( name, ::embed::ElementModes::WRITE ), UNO_QUERY_THROW );
633 uno::Reference < beans::XPropertySet > propertySet( outputStream, uno::UNO_QUERY );
634 assert( propertySet.is());
635 propertySet->setPropertyValue(
"MediaType",
uno::Any( OUString(
"application/x-font-ttf" )));
641 if( file.isEndOfFile( &eof ) != osl::File::E_None )
643 SAL_WARN(
"xmloff",
"Error reading font file " << fileUrl );
644 outputStream->closeOutput();
649 if( file.read( buffer, 4096, readSize ) != osl::File::E_None )
651 SAL_WARN(
"xmloff",
"Error reading font file " << fileUrl );
652 outputStream->closeOutput();
658 outputStream->writeBytes(uno::Sequence<sal_Int8>(buffer, readSize));
660 outputStream->closeOutput();
663 Reference< embed::XTransactedObject > transaction( storage, UNO_QUERY );
664 if( transaction.is())
666 transaction->commit();
667 OUString sInternalName =
"Fonts/" + name;
669 return sInternalName;
css::uno::Reference< css::embed::XStorage > const & GetTargetStorage() const
std::unordered_set< OUString > getUsedFontList()
static OString convertToHashString(std::vector< unsigned char > const &rHash)
OUString Add(const OUString &rFamilyName, const OUString &rStyleName, FontFamily nFamily, FontPitch nPitch, rtl_TextEncoding eEnc)
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
PropertyHandler for the XML-data-type:
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
OUString embedFontFile(OUString const &rFileUrl, OUString const &rFamilyName)
const SvXMLUnitConverter & GetMM100UnitConverter() const
virtual ~XMLFontAutoStylePool() override
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
static OString getFileHash(OUString const &rFileUrl)
constexpr sal_uInt16 XML_NAMESPACE_XLINK
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
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...
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
SvXMLExport & GetExport()
virtual OUString GetName() const override
PropertyHandler for the XML-data-type:
static OUString getFreeFontName(uno::Reference< embed::XStorage > const &rxStorage, OUString const &rFamilyName)
constexpr sal_uInt16 XML_NAMESPACE_SVG
PropertyHandler for the XML-data-type:
#define TOOLS_WARN_EXCEPTION(area, stream)
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...
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::unique_ptr< XMLFontAutoStylePool_Impl > m_pFontAutoStylePool
static OUString fontFileUrl(std::u16string_view familyName, FontFamily family, FontItalic italic, FontWeight weight, FontPitch pitch, FontRights rights)
XMLFontAutoStylePool(SvXMLExport &rExport, bool tryToEmbedFonts=false)
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
std::unique_ptr< char[]> aBuffer
void update(const unsigned char *pInput, size_t length)
rtl::Reference< SvXMLAutoStylePoolP > const & GetAutoStylePool()
Handling of tokens in XML:
std::set< OUString > m_aNames
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...
#define SAL_WARN(area, stream)
OUString Find(const OUString &rFamilyName, const OUString &rStyleName, FontFamily nFamily, FontPitch nPitch, rtl_TextEncoding eEnc) const
PropertyHandler for the XML-data-type:
bool m_bEmbedComplexScript
std::vector< unsigned char > finalize()
constexpr sal_uInt16 XML_NAMESPACE_STYLE
std::unordered_map< OString, OUString > m_aEmbeddedFontFiles
std::vector< std::unique_ptr< XMLFontAutoStylePoolEntry_Impl > >::const_iterator const_iterator
bool m_bDetectedRangeSegmentation false
virtual void collectAutoStyles()