Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sdext/source/pdfimport/tree/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 9 kB image not shown  

Quelle  style.cxx   Sprache: C

 
/* -*- 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 .
 */



#include "style.hxx"
#include <genericelements.hxx>
#include <xmlemitter.hxx>
#include <rtl/ustrbuf.hxx>

#include <algorithm>
#include <string_view>

using namespace pdfi;


StyleContainer::StyleContainer() :
    m_nNextId( 1 )
{
}

sal_Int32 StyleContainer::impl_getStyleId( const Style& rStyle, bool bSubStyle )
{
    sal_Int32 nRet = -1;

    // construct HashedStyle to find or insert
    HashedStyle aSearchStyle;
    aSearchStyle.Name                   = rStyle.Name;
    aSearchStyle.Properties             = rStyle.Properties;
    aSearchStyle.Contents               = rStyle.Contents;
    aSearchStyle.ContainedElement       = rStyle.ContainedElement;
    for(Style* pSubStyle : rStyle.SubStyles)
        aSearchStyle.SubStyles.push_back( impl_getStyleId( *pSubStyle, true ) );

    std::unordered_map< HashedStyle, sal_Int32, StyleHash >::iterator it =
        m_aStyleToId.find( aSearchStyle );

    if( it != m_aStyleToId.end() )
    {
        nRet = it->second;
        RefCountedHashedStyle& rFound = m_aIdToStyle[ nRet ];
        // increase refcount on this style
        rFound.RefCount++;
        if( ! bSubStyle )
            rFound.style.IsSubStyle = false;
    }
    else
    {
        nRet = m_nNextId++;
        // create new style
        RefCountedHashedStyle& rNew = m_aIdToStyle[ nRet ];
        rNew.style = std::move(aSearchStyle);
        rNew.RefCount           = 1;
        rNew.style.IsSubStyle         = bSubStyle;
        // fill the style hash to find the id
        m_aStyleToId[ rNew.style ] = nRet;
    }
    return nRet;
}

sal_Int32 StyleContainer::getStandardStyleId( std::string_view rName )
{
    PropertyMap aProps;
    aProps[ u"style:family"_ustr ] = OStringToOUString( rName, RTL_TEXTENCODING_UTF8 );
    aProps[ u"style:name"_ustr ] = "standard";

    Style aStyle( "style:style"_ostr, std::move(aProps) );
    return getStyleId( aStyle );
}

const PropertyMap* StyleContainer::getProperties( sal_Int32 nStyleId ) const
{
    std::unordered_map< sal_Int32, RefCountedHashedStyle >::const_iterator it =
        m_aIdToStyle.find( nStyleId );
    return it != m_aIdToStyle.end() ? &(it->second.style.Properties) : nullptr;
}

sal_Int32 StyleContainer::setProperties( sal_Int32 nStyleId, PropertyMap&& rNewProps )
{
    sal_Int32 nRet = -1;
    std::unordered_map< sal_Int32, RefCountedHashedStyle >::iterator it =
        m_aIdToStyle.find( nStyleId );
    if( it != m_aIdToStyle.end() )
    {
        if( it->second.RefCount == 1 )
        {
            nRet = it->first;
            // erase old hash to id mapping
            m_aStyleToId.erase( it->second.style );
            // change properties
            it->second.style.Properties = std::move(rNewProps);
            // fill in new hash to id mapping
            m_aStyleToId[ it->second.style ] = nRet;
        }
        else
        {
            // decrease refcount on old instance
            it->second.RefCount--;
            // acquire new HashedStyle
            HashedStyle aSearchStyle;
            aSearchStyle.Name                   = it->second.style.Name;
            aSearchStyle.Properties             = std::move(rNewProps);
            aSearchStyle.Contents               = it->second.style.Contents;
            aSearchStyle.ContainedElement       = it->second.style.ContainedElement;
            aSearchStyle.SubStyles              = it->second.style.SubStyles;
            aSearchStyle.IsSubStyle             = it->second.style.IsSubStyle;

            // find out whether this new style already exists
            std::unordered_map< HashedStyle, sal_Int32, StyleHash >::iterator new_it =
                m_aStyleToId.find( aSearchStyle );
            if( new_it != m_aStyleToId.end() )
            {
                nRet = new_it->second;
                m_aIdToStyle[ nRet ].RefCount++;
            }
            else
            {
                nRet = m_nNextId++;
                // create new style with new id
                RefCountedHashedStyle& rNew = m_aIdToStyle[ nRet ];
                rNew.style = aSearchStyle;
                rNew.RefCount = 1;
                // fill style to id hash
                m_aStyleToId[ aSearchStyle ] = nRet;
            }
        }
    }
    return nRet;
}

OUString StyleContainer::getStyleName( sal_Int32 nStyle ) const
{
    OUStringBuffer aRet( 64 );

    std::unordered_map< sal_Int32, RefCountedHashedStyle >::const_iterator style_it =
        m_aIdToStyle.find( nStyle );
    if( style_it != m_aIdToStyle.end() )
    {
        const HashedStyle& rStyle = style_it->second.style;

        PropertyMap::const_iterator name_it = rStyle.Properties.find( u"style:name"_ustr );
        if( name_it != rStyle.Properties.end() )
            aRet.append( name_it->second );
        else
        {
            PropertyMap::const_iterator fam_it = rStyle.Properties.find( u"style:family"_ustr );
            OUString aStyleName;
            if( fam_it != rStyle.Properties.end() )
            {
                aStyleName = fam_it->second;
            }
            else
                aStyleName = OStringToOUString( rStyle.Name, RTL_TEXTENCODING_ASCII_US );
            sal_Int32 nIndex = aStyleName.lastIndexOf( ':' );
            aRet.append( aStyleName.subView(nIndex+1) + OUString::number( nStyle ) );
        }
    }
    else
    {
        aRet.append( "invalid style id " + OUString::number(nStyle) );
    }

    return aRet.makeStringAndClear();
}

void StyleContainer::impl_emitStyle( sal_Int32           nStyleId,
                                     EmitContext&        rContext,
                                     ElementTreeVisitor& rContainedElemVisitor )
{
    std::unordered_map< sal_Int32, RefCountedHashedStyle >::const_iterator it = m_aIdToStyle.find( nStyleId );
    if( it == m_aIdToStyle.end() )
        return;

    const HashedStyle& rStyle = it->second.style;
    PropertyMap aProps( rStyle.Properties );
    if( !rStyle.IsSubStyle )
        aProps[ u"style:name"_ustr ] = getStyleName( nStyleId );
    if (rStyle.Name == "draw:stroke-dash" || rStyle.Name == "draw:fill-image")
        aProps[ u"draw:name"_ustr ] = aProps[ u"style:name"_ustr ];
    rContext.rEmitter.beginTag( rStyle.Name.getStr(), aProps );

    for(sal_Int32 nSubStyle : rStyle.SubStyles)
        impl_emitStyle( nSubStyle, rContext, rContainedElemVisitor );
    if( !rStyle.Contents.isEmpty() )
    {
        rContext.rEmitter.beginTag( "office:binary-data", PropertyMap() );
        rContext.rEmitter.write( rStyle.Contents );
        rContext.rEmitter.endTag( "office:binary-data" );
    }
    if( rStyle.ContainedElement )
        rStyle.ContainedElement->visitedBy( rContainedElemVisitor,
                                            std::list<std::unique_ptr<Element>>::iterator() );
    rContext.rEmitter.endTag( rStyle.Name.getStr() );
}

void StyleContainer::emit( EmitContext&        rContext,
                           ElementTreeVisitor& rContainedElemVisitor )
{
    std::vector< sal_Int32 > aMasterPageSection, aAutomaticStyleSection, aOfficeStyleSection;
    forconst auto& rEntry : m_aIdToStyle )
    {
        if( ! rEntry.second.style.IsSubStyle )
        {
            if( rEntry.second.style.Name == "style:master-page" )
                aMasterPageSection.push_back( rEntry.first );
            else if( getStyleName( rEntry.first ) == "standard" )
                aOfficeStyleSection.push_back( rEntry.first );
            else
                aAutomaticStyleSection.push_back( rEntry.first );
        }
    }

    if( ! aMasterPageSection.empty() )
        std::stable_sort( aMasterPageSection.begin(), aMasterPageSection.end(), StyleIdNameSort(&m_aIdToStyle) );
    if( ! aAutomaticStyleSection.empty() )
        std::stable_sort( aAutomaticStyleSection.begin(), aAutomaticStyleSection.end(), StyleIdNameSort(&m_aIdToStyle) );
    if( ! aOfficeStyleSection.empty() )
        std::stable_sort( aOfficeStyleSection.begin(), aOfficeStyleSection.end(), StyleIdNameSort(&m_aIdToStyle) );

    int n = 0, nElements = 0;
    rContext.rEmitter.beginTag( "office:styles", PropertyMap() );
    for( n = 0, nElements = aOfficeStyleSection.size(); n < nElements; n++ )
        impl_emitStyle( aOfficeStyleSection[n], rContext, rContainedElemVisitor );
    rContext.rEmitter.endTag( "office:styles" );
    rContext.rEmitter.beginTag( "office:automatic-styles", PropertyMap() );
    for( n = 0, nElements = aAutomaticStyleSection.size(); n < nElements; n++ )
        impl_emitStyle( aAutomaticStyleSection[n], rContext, rContainedElemVisitor );
    rContext.rEmitter.endTag( "office:automatic-styles" );
    rContext.rEmitter.beginTag( "office:master-styles", PropertyMap() );
    for( n = 0, nElements = aMasterPageSection.size(); n < nElements; n++ )
        impl_emitStyle( aMasterPageSection[n], rContext, rContainedElemVisitor );
    rContext.rEmitter.endTag( "office:master-styles" );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=94 H=96 G=94

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.