diff options
Diffstat (limited to 'sdext/source/pdfimport/tree/style.hxx')
-rw-r--r-- | sdext/source/pdfimport/tree/style.hxx | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/sdext/source/pdfimport/tree/style.hxx b/sdext/source/pdfimport/tree/style.hxx new file mode 100644 index 000000000..ee7cafeab --- /dev/null +++ b/sdext/source/pdfimport/tree/style.hxx @@ -0,0 +1,165 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SDEXT_SOURCE_PDFIMPORT_TREE_STYLE_HXX +#define INCLUDED_SDEXT_SOURCE_PDFIMPORT_TREE_STYLE_HXX + +#include <pdfihelper.hxx> +#include <numeric> +#include <unordered_map> +#include <vector> +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <treevisiting.hxx> + +namespace pdfi +{ + struct Element; + struct EmitContext; + + class StyleContainer + { + public: + struct Style + { + OString Name; + PropertyMap Properties; + OUString Contents; + Element* ContainedElement; + std::vector< Style* > SubStyles; + + Style( const OString& rName, const PropertyMap& rProps ) : + Name( rName ), + Properties( rProps ), + ContainedElement( nullptr ) + {} + }; + + private: + struct HashedStyle + { + OString Name; + PropertyMap Properties; + OUString Contents; + Element* ContainedElement; + std::vector<sal_Int32> SubStyles; + + bool IsSubStyle; + + HashedStyle() : ContainedElement( nullptr ), IsSubStyle( true ) {} + + size_t hashCode() const + { + size_t nRet = std::accumulate(Properties.begin(), Properties.end(), size_t(Name.hashCode()), + [](const size_t& sum, const PropertyMap::value_type& rEntry) { + return sum ^ size_t(rEntry.first.hashCode()) ^ size_t(rEntry.second.hashCode()); + }); + nRet ^= size_t(Contents.hashCode()); + nRet ^= reinterpret_cast<size_t>(ContainedElement); + for( size_t n = 0; n < SubStyles.size(); ++n ) + nRet ^= size_t(SubStyles[n]); + return nRet; + } + + bool operator==(const HashedStyle& rRight) const + { + if( Name != rRight.Name || + Properties != rRight.Properties || + Contents != rRight.Contents || + ContainedElement != rRight.ContainedElement || + SubStyles.size() != rRight.SubStyles.size() + ) + return false; + for( size_t n = 0; n < SubStyles.size(); ++n ) + { + if( SubStyles[n] != rRight.SubStyles[n] ) + return false; + } + return true; + } + }; + + struct RefCountedHashedStyle { + HashedStyle style; + sal_Int32 RefCount = 0; + }; + + struct StyleHash; + friend struct StyleHash; + struct StyleHash + { + size_t operator()( const StyleContainer::HashedStyle& rStyle ) const + { + return rStyle.hashCode(); + } + }; + + struct StyleIdNameSort; + friend struct StyleIdNameSort; + struct StyleIdNameSort + { + const std::unordered_map< sal_Int32, RefCountedHashedStyle >* m_pMap; + + explicit StyleIdNameSort( const std::unordered_map< sal_Int32, RefCountedHashedStyle >* pMap ) : + m_pMap(pMap) + {} + bool operator()( sal_Int32 nLeft, sal_Int32 nRight ) + { + const std::unordered_map< sal_Int32, RefCountedHashedStyle >::const_iterator left_it = + m_pMap->find( nLeft ); + const std::unordered_map< sal_Int32, RefCountedHashedStyle >::const_iterator right_it = + m_pMap->find( nRight ); + if( left_it == m_pMap->end() ) + return false; + else if( right_it == m_pMap->end() ) + return true; + else + return left_it->second.style.Name < right_it->second.style.Name; + } + }; + + sal_Int32 m_nNextId; + std::unordered_map< sal_Int32, RefCountedHashedStyle > m_aIdToStyle; + std::unordered_map< HashedStyle, sal_Int32, StyleHash > m_aStyleToId; + + void impl_emitStyle( sal_Int32 nStyleId, + EmitContext& rContext, + ElementTreeVisitor& rContainedElemVisitor ); + + public: + StyleContainer(); + + void emit( EmitContext& rContext, + ElementTreeVisitor& rContainedElemVisitor ); + + sal_Int32 impl_getStyleId( const Style& rStyle, bool bSubStyle ); + sal_Int32 getStyleId( const Style& rStyle ) + { return impl_getStyleId( rStyle, false ); } + sal_Int32 getStandardStyleId( const OString& rFamily ); + + // returns NULL for an invalid style id + const PropertyMap* getProperties( sal_Int32 nStyleId ) const; + sal_Int32 setProperties( sal_Int32 nStyleId, const PropertyMap &rNewProps ); + OUString getStyleName( sal_Int32 nStyle ) const; + }; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |