Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  atrstck.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 "atrhndl.hxx"
#include <svl/itemiter.hxx>
#include <vcl/outdev.hxx>
#include <editeng/cmapitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/contouritem.hxx>
#include <editeng/crossedoutitem.hxx>
#include <editeng/escapementitem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/kernitem.hxx>
#include <editeng/charreliefitem.hxx>
#include <editeng/langitem.hxx>
#include <editeng/postitem.hxx>
#include <editeng/shdditem.hxx>
#include <editeng/udlnitem.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/wrlmitem.hxx>
#include <editeng/autokernitem.hxx>
#include <editeng/charrotateitem.hxx>
#include <editeng/emphasismarkitem.hxx>
#include <editeng/charscaleitem.hxx>
#include <editeng/twolinesitem.hxx>
#include <editeng/charhiddenitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/nhypitem.hxx>
#include <editeng/shaditem.hxx>
#include <viewopt.hxx>
#include <charfmt.hxx>
#include <fchrfmt.hxx>
#include <fmtautofmt.hxx>
#include <editeng/brushitem.hxx>
#include <fmtinfmt.hxx>
#include <txtinet.hxx>
#include <IDocumentSettingAccess.hxx>
#include <viewsh.hxx>

/**
 * Attribute to Stack Mapping
 *
 * Attributes applied to a text are pushed on different stacks. For each
 * stack, the top most attribute on the stack is valid. Because some
 * kinds of attributes have to be pushed to the same stacks we map their
 * ids to stack ids
 * Attention: Stacks for character attributes (RES_CHRATR_*)
 * are stored in the defaultitem-cache, if you add one, you have to increase
 * NUM_DEFAULT_VALUES (defined in swfntcch.hxx), and ensure your new stack id
 * is below this number.
 * Also adjust NUM_ATTRIBUTE_STACKS in atrhndl.hxx.
 */

const sal_uInt8 StackPos[ RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN + 1 ] =
{
     0, //                                       //  0
     1, // RES_CHRATR_CASEMAP = RES_CHRATR_BEGIN //  1
     0, // RES_CHRATR_CHARSETCOLOR,              //  2
     2, // RES_CHRATR_COLOR,                     //  3
     3, // RES_CHRATR_CONTOUR,                   //  4
     4, // RES_CHRATR_CROSSEDOUT,                //  5
     5, // RES_CHRATR_ESCAPEMENT,                //  6
     6, // RES_CHRATR_FONT,                      //  7
     7, // RES_CHRATR_FONTSIZE,                  //  8
     8, // RES_CHRATR_KERNING,                   //  9
     9, // RES_CHRATR_LANGUAGE,                  // 10
    10, // RES_CHRATR_POSTURE,                   // 11
     0, // RES_CHRATR_UNUSED1,                   // 12
    11, // RES_CHRATR_SHADOWED,                  // 13
    12, // RES_CHRATR_UNDERLINE,                 // 14
    13, // RES_CHRATR_WEIGHT,                    // 15
    14, // RES_CHRATR_WORDLINEMODE,              // 16
    15, // RES_CHRATR_AUTOKERN,                  // 17
    16, // RES_CHRATR_BLINK,                     // 18
    17, // RES_CHRATR_NOHYPHEN,                  // 19
     0, // RES_CHRATR_UNUSED2,                   // 20
    18, // RES_CHRATR_BACKGROUND,                // 21
    19, // RES_CHRATR_CJK_FONT,                  // 22
    20, // RES_CHRATR_CJK_FONTSIZE,              // 23
    21, // RES_CHRATR_CJK_LANGUAGE,              // 24
    22, // RES_CHRATR_CJK_POSTURE,               // 25
    23, // RES_CHRATR_CJK_WEIGHT,                // 26
    24, // RES_CHRATR_CTL_FONT,                  // 27
    25, // RES_CHRATR_CTL_FONTSIZE,              // 28
    26, // RES_CHRATR_CTL_LANGUAGE,              // 29
    27, // RES_CHRATR_CTL_POSTURE,               // 30
    28, // RES_CHRATR_CTL_WEIGHT,                // 31
    29, // RES_CHRATR_ROTATE,                    // 32
    30, // RES_CHRATR_EMPHASIS_MARK,             // 33
    31, // RES_CHRATR_TWO_LINES,                 // 34
    32, // RES_CHRATR_SCALEW,                    // 35
    33, // RES_CHRATR_RELIEF,                    // 36
    34, // RES_CHRATR_HIDDEN,                    // 37
    35, // RES_CHRATR_OVERLINE,                  // 38
     0, // RES_CHRATR_RSID,                      // 39
    36, // RES_CHRATR_BOX,                       // 40
    37, // RES_CHRATR_SHADOW,                    // 41
    38, // RES_CHRATR_HIGHLIGHT,                 // 42
     0, // RES_CHRATR_GRABBAG,                   // 43
     0, // RES_CHRATR_BIDIRTL,                   // 44
     0, // RES_CHRATR_UNUSED3,                   // 45
    39, // RES_CHRATR_SCRIPT_HINT,               // 46
    40, // RES_TXTATR_REFMARK,                   // 47
    41, // RES_TXTATR_TOXMARK,                   // 48
    42, // RES_TXTATR_META,                      // 49
    42, // RES_TXTATR_METAFIELD,                 // 50
     0, // RES_TXTATR_AUTOFMT,                   // 51
     0, // RES_TXTATR_INETFMT                    // 52
     0, // RES_TXTATR_CHARFMT,                   // 53
    43, // RES_TXTATR_CJK_RUBY,                  // 54
     0, // RES_TXTATR_UNKNOWN_CONTAINER,         // 55
    44, // RES_TXTATR_INPUTFIELD                 // 56
    45, // RES_TXTATR_CONTENTCONTROL             // 57
};

namespace CharFormat
{

/// Returns the item set associated with a character/inet/auto style
const SfxItemSet* GetItemSet( const SfxPoolItem& rAttr )
{
    const SfxItemSet* pSet = nullptr;

    if ( RES_TXTATR_AUTOFMT == rAttr.Which() )
    {
        pSet = rAttr.StaticWhichCast(RES_TXTATR_AUTOFMT).GetStyleHandle().get();
    }
    else
    {
        // Get the attributes from the template
        const SwCharFormat* pFormat = RES_TXTATR_INETFMT == rAttr.Which() ?
                        rAttr.StaticWhichCast(RES_TXTATR_INETFMT).GetTextINetFormat()->GetCharFormat() :
                        static_cast<const SwFormatCharFormat&>(rAttr).GetCharFormat();
        if( pFormat )
        {
            pSet = &pFormat->GetAttrSet();
        }
    }

    return pSet;
}

/// Extracts pool item of type nWhich from rAttr
const SfxPoolItem* GetItem( const SwTextAttr& rAttr, sal_uInt16 nWhich )
{
    if ( RES_TXTATR_INETFMT == rAttr.Which() ||
         RES_TXTATR_CHARFMT == rAttr.Which() ||
         RES_TXTATR_AUTOFMT == rAttr.Which() )
    {
        const SfxItemSet* pSet = CharFormat::GetItemSet( rAttr.GetAttr() );
        if ( !pSet ) return nullptr;

        bool bInParent = RES_TXTATR_AUTOFMT != rAttr.Which();
        const SfxPoolItem* pItem;
        bool bRet = SfxItemState::SET == pSet->GetItemState( nWhich, bInParent, &pItem );

        return bRet ? pItem : nullptr;
    }

    return ( nWhich == rAttr.Which() ) ? &rAttr.GetAttr() : nullptr;
}

/// Checks if item is included in character/inet/auto style
bool IsItemIncluded( const sal_uInt16 nWhich, const SwTextAttr *pAttr )
{
    bool bRet = false;

    const SfxItemSet* pItemSet = CharFormat::GetItemSet( pAttr->GetAttr() );
    if ( pItemSet )
        bRet = SfxItemState::SET == pItemSet->GetItemState( nWhich );

    return bRet;
}
}

/**
 * The color of hyperlinks is taken from the associated character attribute,
 * depending on its 'visited' state. There are actually two cases, which
 * should override the colors from the character attribute:
 *     1. We never take the 'visited' color during printing/pdf export/preview
 *     2. The user has chosen to override these colors in the view options
 */

static bool lcl_ChgHyperLinkColor( const SwTextAttr& rAttr,
                            const SfxPoolItem& rItem,
                            const SwViewShell* pShell,
                            Color* pColor )
{
    if ( !pShell ||
         RES_TXTATR_INETFMT != rAttr.Which() ||
         RES_CHRATR_COLOR != rItem.Which() )
        return false;

    // #i15455#
    // 1. case:
    // We do not want to show visited links:
    // (printing, pdf export, page preview)

    SwTextINetFormat & rINetAttr(const_cast<SwTextINetFormat&>(
                            static_txtattr_cast<SwTextINetFormat const&>(rAttr)));
    if ( pShell->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
         pShell->GetViewOptions()->IsPDFExport() ||
         pShell->GetViewOptions()->IsPagePreview() )
    {
        if (rINetAttr.IsVisited())
        {
            if ( pColor )
            {
                // take color from character format 'unvisited link'
                rINetAttr.SetVisited(false);
                const SwCharFormat* pTmpFormat = rINetAttr.GetCharFormat();
                if (const SvxColorItem* pItem = pTmpFormat->GetItemIfSet(RES_CHRATR_COLOR))
                    *pColor = pItem->GetValue();
                rINetAttr.SetVisited(true);
            }
            return true;
        }

        return false;
    }

    // 2. case:
    // We do not want to apply the color set in the hyperlink
    // attribute, instead we take the colors from the view options:

    if ( pShell->GetWin() &&
        (
          (rINetAttr.IsVisited() && pShell->GetViewOptions()->IsVisitedLinks()) ||
          (!rINetAttr.IsVisited() && pShell->GetViewOptions()->IsLinks())
        )
       )
    {
        if ( pColor )
        {
            if (rINetAttr.IsVisited())
            {
                // take color from view option 'visited link color'
                *pColor = pShell->GetViewOptions()->GetVisitedLinksColor();
            }
            else
            {
                // take color from view option 'unvisited link color'
                *pColor = pShell->GetViewOptions()->GetLinksColor();
            }
        }
        return true;
    }

    return false;
}

SwAttrHandler::SwAttrHandler()
    : m_pIDocumentSettingAccess(nullptr)
    , m_pShell(nullptr)
    , m_bVertLayout(false)
    , m_bVertLayoutLRBT(false)
{
    memset( m_pDefaultArray, 0, NUM_DEFAULT_VALUES * sizeof(SfxPoolItem*) );
}

SwAttrHandler::~SwAttrHandler()
{
}

void SwAttrHandler::Init( const SwAttrSet& rAttrSet,
                          const IDocumentSettingAccess& rIDocumentSettingAcces )
{
    m_pIDocumentSettingAccess = &rIDocumentSettingAcces;
    m_pShell = nullptr;

    for ( sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++ )
        m_pDefaultArray[ StackPos[ i ] ] = &rAttrSet.Get( i );
}

void SwAttrHandler::Init( const SfxPoolItem** pPoolItem, const SwAttrSet* pAS,
                          const IDocumentSettingAccess& rIDocumentSettingAcces,
                          const SwViewShell* pSh,
                          SwFont& rFnt, bool bVL, bool bVertLayoutLRBT )
{
    // initialize default array
    memcpy( m_pDefaultArray, pPoolItem,
            NUM_DEFAULT_VALUES * sizeof(SfxPoolItem*) );

    m_pIDocumentSettingAccess = &rIDocumentSettingAcces;
    m_pShell = pSh;

    // do we have to apply additional paragraph attributes?
    m_bVertLayout = bVL;
    m_bVertLayoutLRBT = bVertLayoutLRBT;

    if ( pAS && pAS->Count() )
    {
        SfxItemIter aIter( *pAS );
        sal_uInt16 nWhich;
        const SfxPoolItem* pItem = aIter.GetCurItem();
        do
        {
            nWhich = pItem->Which();
            if (isCHRATR(nWhich))
            {
                m_pDefaultArray[ StackPos[ nWhich ] ] = pItem;
                FontChg( *pItem, rFnt, true );
            }

            pItem = aIter.NextItem();
        } while (pItem);
    }

    // It is possible, that Init is called more than once, e.g., in a
    // SwTextFrame::FormatOnceMore situation or (since sw_redlinehide)
    // from SwAttrIter::Seek(); in the latter case SwTextSizeInfo::m_pFnt
    // is an alias of m_pFnt so it must not be deleted!
    if (m_oFnt)
        *m_oFnt = rFnt;
    else
        m_oFnt.emplace(rFnt);
}

void SwAttrHandler::Reset( )
{
    for (auto& i : m_aAttrStack)
        i.clear();
}

void SwAttrHandler::PushAndChg( const SwTextAttr& rAttr, SwFont& rFnt )
{
    // these special attributes in fact represent a collection of attributes
    // they have to be pushed to each stack they belong to
    if ( RES_TXTATR_INETFMT == rAttr.Which() ||
         RES_TXTATR_CHARFMT == rAttr.Which() ||
         RES_PARATR_LIST_AUTOFMT == rAttr.Which() ||
         RES_TXTATR_AUTOFMT == rAttr.Which() )
    {
        const SfxItemSet* pSet = rAttr.Which() == RES_PARATR_LIST_AUTOFMT
            ? rAttr.GetAttr().StaticWhichCast(RES_PARATR_LIST_AUTOFMT).GetStyleHandle().get()
            : CharFormat::GetItemSet( rAttr.GetAttr() );
        if ( !pSet ) return;

        bool const inParent{rAttr.Which() != RES_TXTATR_AUTOFMT && rAttr.Which() != RES_PARATR_LIST_AUTOFMT};
        for ( sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++)
        {
            const SfxPoolItem* pItem;
            bool bRet = SfxItemState::SET == pSet->GetItemState(i, inParent, &pItem);

            if ( bRet )
            {
                // we push rAttr onto the appropriate stack
                if ( Push( rAttr, *pItem ) )
                {
                    // we let pItem change rFnt
                    Color aColor;
                    if (lcl_ChgHyperLinkColor(rAttr, *pItem, m_pShell, &aColor))
                    {
                        SvxColorItem aItemNext( aColor, RES_CHRATR_COLOR );
                        FontChg( aItemNext, rFnt, true );
                    }
                    else
                        FontChg( *pItem, rFnt, true );
                }
            }
        }

        if (rAttr.Which() == RES_TXTATR_INETFMT)
        {
            if (m_nINETFMT == 0)
                rFnt.SetURL(true);
            ++m_nINETFMT;
        }
    }
    // this is the usual case, we have a basic attribute, push it onto the
    // stack and change the font
    else
    {
        if ( Push( rAttr, rAttr.GetAttr() ) )
            // we let pItem change rFnt
            FontChg( rAttr.GetAttr(), rFnt, true );
    }
}

const SwTextAttr* SwAttrHandler::GetTop(sal_uInt16 nStack)
{
    return m_aAttrStack[nStack].empty() ? nullptr : m_aAttrStack[nStack].back();
}

bool SwAttrHandler::Push( const SwTextAttr& rAttr, const SfxPoolItem& rItem )
{
    OSL_ENSURE( rItem.Which() < RES_TXTATR_WITHEND_END,
            "I do not want this attribute, nWhich >= RES_TXTATR_WITHEND_END" );

    // robust
    if ( RES_TXTATR_WITHEND_END <= rItem.Which() )
        return false;

    const sal_uInt16 nStack = StackPos[ rItem.Which() ];

    // attributes originating from redlining have highest priority
    // second priority are hyperlink attributes, which have a color replacement
    const SwTextAttr* pTopAttr = GetTop(nStack);
    if ( !pTopAttr
         || rAttr.IsPriorityAttr()
         || ( !pTopAttr->IsPriorityAttr()
              && !lcl_ChgHyperLinkColor(*pTopAttr, rItem, m_pShell, nullptr)))
    {
        m_aAttrStack[nStack].push_back(&rAttr);
        return true;
    }

    const auto it = m_aAttrStack[nStack].end() - 1;
    m_aAttrStack[nStack].insert(it, &rAttr);
    return false;
}

void SwAttrHandler::RemoveFromStack(sal_uInt16 nWhich, const SwTextAttr& rAttr)
{
    auto& rStack = m_aAttrStack[StackPos[nWhich]];
    const auto it = std::find(rStack.begin(), rStack.end(), &rAttr);
    if (it != rStack.end())
        rStack.erase(it);
}

void SwAttrHandler::PopAndChg( const SwTextAttr& rAttr, SwFont& rFnt )
{
    if ( RES_TXTATR_WITHEND_END <= rAttr.Which() )
        return// robust

    // these special attributes in fact represent a collection of attributes
    // they have to be removed from each stack they belong to
    if ( RES_TXTATR_INETFMT == rAttr.Which() ||
         RES_TXTATR_CHARFMT == rAttr.Which() ||
         RES_TXTATR_AUTOFMT == rAttr.Which() )
    {
        const SfxItemSet* pSet = CharFormat::GetItemSet( rAttr.GetAttr() );
        if ( !pSet ) return;

        if (rAttr.Which() == RES_TXTATR_INETFMT)
        {
            assert(m_nINETFMT > 0);
            --m_nINETFMT;
            if (m_nINETFMT == 0)
                rFnt.SetURL(false);
        }

        for ( sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++)
        {
            const SfxPoolItem* pItem;
            bool bRet = SfxItemState::SET == pSet->GetItemState( i, RES_TXTATR_AUTOFMT != rAttr.Which(), &pItem );
            if ( bRet )
            {
                // we remove rAttr from the appropriate stack
                RemoveFromStack(i, rAttr);
                // reset font according to attribute on top of stack
                // or default value
                ActivateTop( rFnt, i );
            }
        }
    }
    // this is the usual case, we have a basic attribute, remove it from the
    // stack and reset the font
    else
    {
        RemoveFromStack(rAttr.Which(), rAttr);
        // reset font according to attribute on top of stack
        // or default value
        ActivateTop( rFnt, rAttr.Which() );
    }
}

/// Only used during redlining
void SwAttrHandler::Pop( const SwTextAttr& rAttr )
{
    OSL_ENSURE( rAttr.Which() < RES_TXTATR_WITHEND_END,
            "I do not have this attribute, nWhich >= RES_TXTATR_WITHEND_END" );

    if ( rAttr.Which() < RES_TXTATR_WITHEND_END )
    {
        RemoveFromStack(rAttr.Which(), rAttr);
    }
}

void SwAttrHandler::ActivateTop( SwFont& rFnt, const sal_uInt16 nAttr )
{
    assert(nAttr < RES_TXTATR_WITHEND_END);

    const sal_uInt16 nStackPos = StackPos[ nAttr ];
    const SwTextAttr* pTopAt = GetTop(nStackPos);
    if ( pTopAt )
    {
        const SfxPoolItem* pItemNext(nullptr);

        // check if top attribute is collection of attributes
        if ( RES_TXTATR_INETFMT == pTopAt->Which() ||
             RES_TXTATR_CHARFMT == pTopAt->Which() ||
             RES_TXTATR_AUTOFMT == pTopAt->Which() )
        {
            const SfxItemSet* pSet = CharFormat::GetItemSet( pTopAt->GetAttr() );
            if (pSet)
                pSet->GetItemState( nAttr, RES_TXTATR_AUTOFMT != pTopAt->Which(), &pItemNext );
        }

        if (pItemNext)
        {
            Color aColor;
            if (lcl_ChgHyperLinkColor(*pTopAt, *pItemNext, m_pShell, &aColor))
            {
                SvxColorItem aItemNext( aColor, RES_CHRATR_COLOR );
                FontChg( aItemNext, rFnt, false );
            }
            else
                FontChg( *pItemNext, rFnt, false );
        }
        else
            FontChg( pTopAt->GetAttr(), rFnt, false );
    }

    // default value has to be set, we only have default values for char attribs
    else if ( nStackPos < NUM_DEFAULT_VALUES )
        FontChg( *m_pDefaultArray[ nStackPos ], rFnt, false );
    else if ( RES_TXTATR_REFMARK == nAttr )
        rFnt.GetRef()--;
    else if ( RES_TXTATR_TOXMARK == nAttr )
        rFnt.GetTox()--;
    else if ( (RES_TXTATR_META == nAttr) || (RES_TXTATR_METAFIELD == nAttr) )
    {
        rFnt.GetMeta()--;
    }
    else if (nAttr == RES_TXTATR_CONTENTCONTROL)
    {
        rFnt.GetContentControl()--;
    }
    else if ( RES_TXTATR_CJK_RUBY == nAttr )
    {
        // ruby stack has no more attributes
        // check, if a rotation attribute has to be applied
        const sal_uInt16 nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ];
        bool bTwoLineAct = false;
        const SwTextAttr* pTwoLineAttr = GetTop(nTwoLineStack);

        if ( pTwoLineAttr )
        {
             const auto& rTwoLineItem = *CharFormat::GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES );
             bTwoLineAct = rTwoLineItem.GetValue();
        }
        else
            bTwoLineAct = m_pDefaultArray[ nTwoLineStack ]->StaticWhichCast(RES_CHRATR_TWO_LINES).GetValue();

        if ( bTwoLineAct )
            return;

        // eventually, a rotate attribute has to be activated
        const sal_uInt16 nRotateStack = StackPos[ RES_CHRATR_ROTATE ];
        const SwTextAttr* pRotateAttr = GetTop(nRotateStack);

        if ( pRotateAttr )
        {
            const auto& rRotateItem = *CharFormat::GetItem( *pRotateAttr, RES_CHRATR_ROTATE );
            rFnt.SetVertical( rRotateItem.GetValue(), m_bVertLayout );
        }
        else
            rFnt.SetVertical( m_pDefaultArray[ nRotateStack ]->StaticWhichCast(RES_CHRATR_ROTATE).GetValue(), m_bVertLayout );
    }
    else if ( RES_TXTATR_INPUTFIELD == nAttr )
        rFnt.GetInputField()--;
}

/**
 * When popping an attribute from the stack, the top more remaining
 * attribute in the stack becomes valid. The following function change
 * a font depending on the stack id.
 */

void SwAttrHandler::FontChg(const SfxPoolItem& rItem, SwFont& rFnt, bool bPush )
{
    switch ( rItem.Which() )
    {
        case RES_CHRATR_CASEMAP :
            rFnt.SetCaseMap( rItem.StaticWhichCast(RES_CHRATR_CASEMAP).GetCaseMap() );
            break;
        case RES_CHRATR_COLOR :
            rFnt.SetColor( rItem.StaticWhichCast(RES_CHRATR_COLOR).GetValue() );
            break;
        case RES_CHRATR_CONTOUR :
            rFnt.SetOutline( rItem.StaticWhichCast(RES_CHRATR_CONTOUR).GetValue() );
            break;
        case RES_CHRATR_CROSSEDOUT :
            rFnt.SetStrikeout( rItem.StaticWhichCast(RES_CHRATR_CROSSEDOUT).GetStrikeout() );
            break;
        case RES_CHRATR_ESCAPEMENT :
            rFnt.SetEscapement( rItem.StaticWhichCast(RES_CHRATR_ESCAPEMENT).GetEsc() );
            rFnt.SetProportion( rItem.StaticWhichCast(RES_CHRATR_ESCAPEMENT).GetProportionalHeight() );
            break;
        case RES_CHRATR_FONT :
        {
            auto& rFontItem = rItem.StaticWhichCast(RES_CHRATR_FONT);
            rFnt.SetName( rFontItem.GetFamilyName(), SwFontScript::Latin );
            rFnt.SetStyleName( rFontItem.GetStyleName(), SwFontScript::Latin );
            rFnt.SetFamily( rFontItem.GetFamily(), SwFontScript::Latin );
            rFnt.SetPitch( rFontItem.GetPitch(), SwFontScript::Latin );
            rFnt.SetCharSet( rFontItem.GetCharSet(), SwFontScript::Latin );
            break;
        }
        case RES_CHRATR_FONTSIZE :
            rFnt.SetSize(Size(0, rItem.StaticWhichCast(RES_CHRATR_FONTSIZE).GetHeight() ), SwFontScript::Latin );
            break;
        case RES_CHRATR_KERNING :
            rFnt.SetFixKerning( rItem.StaticWhichCast(RES_CHRATR_KERNING).GetValue() );
            break;
        case RES_CHRATR_LANGUAGE :
            rFnt.SetLanguage( rItem.StaticWhichCast(RES_CHRATR_LANGUAGE).GetLanguage(), SwFontScript::Latin );
            break;
        case RES_CHRATR_POSTURE :
            rFnt.SetItalic( rItem.StaticWhichCast(RES_CHRATR_POSTURE).GetPosture(), SwFontScript::Latin );
            break;
        case RES_CHRATR_SHADOWED :
            rFnt.SetShadow( rItem.StaticWhichCast(RES_CHRATR_SHADOWED).GetValue() );
            break;
        case RES_CHRATR_UNDERLINE :
        {
            const sal_uInt16 nStackPos = StackPos[ RES_CHRATR_HIDDEN ];
            const SwTextAttr* pTopAt = GetTop(nStackPos);

            const SfxPoolItem* pTmpItem = pTopAt ?
                                          CharFormat::GetItem( *pTopAt, RES_CHRATR_HIDDEN ) :
                                          m_pDefaultArray[ nStackPos ];

            const sal_uInt16 nStackPos2 = StackPos[ RES_CHRATR_NOHYPHEN ];
            const SwTextAttr* pTopAt2 = GetTop(nStackPos2);

            const SfxPoolItem* pTmpItem2 = pTopAt2 ?
                                          CharFormat::GetItem( *pTopAt2, RES_CHRATR_NOHYPHEN ) :
                                          m_pDefaultArray[ nStackPos2 ];

            if ((m_pShell && !m_pShell->GetWin()) ||
                (pTmpItem && !pTmpItem->StaticWhichCast(RES_CHRATR_HIDDEN).GetValue()) ||
                (pTmpItem2 && !pTmpItem2->StaticWhichCast(RES_CHRATR_NOHYPHEN).GetValue()) )
            {
                rFnt.SetUnderline( rItem.StaticWhichCast(RES_CHRATR_UNDERLINE).GetLineStyle() );
                rFnt.SetUnderColor( rItem.StaticWhichCast(RES_CHRATR_UNDERLINE).GetColor() );
            }
            break;
        }
        case RES_CHRATR_BOX:
        {
            const SvxBoxItem& aBoxItem = rItem.StaticWhichCast(RES_CHRATR_BOX);
            rFnt.SetTopBorder( aBoxItem.GetTop() );
            rFnt.SetBottomBorder( aBoxItem.GetBottom() );
            rFnt.SetRightBorder( aBoxItem.GetRight() );
            rFnt.SetLeftBorder( aBoxItem.GetLeft() );
            rFnt.SetTopBorderDist( aBoxItem.GetDistance(SvxBoxItemLine::TOP) );
            rFnt.SetBottomBorderDist( aBoxItem.GetDistance(SvxBoxItemLine::BOTTOM) );
            rFnt.SetRightBorderDist( aBoxItem.GetDistance(SvxBoxItemLine::RIGHT) );
            rFnt.SetLeftBorderDist( aBoxItem.GetDistance(SvxBoxItemLine::LEFT) );
            break;
        }
        case RES_CHRATR_SHADOW:
        {
            const SvxShadowItem& aShadowItem = rItem.StaticWhichCast(RES_CHRATR_SHADOW);
            rFnt.SetShadowColor( aShadowItem.GetColor() );
            rFnt.SetShadowWidth( aShadowItem.GetWidth() );
            rFnt.SetShadowLocation( aShadowItem.GetLocation() );
            break;
        }
        case RES_CHRATR_OVERLINE :
            rFnt.SetOverline( rItem.StaticWhichCast(RES_CHRATR_OVERLINE).GetLineStyle() );
            rFnt.SetOverColor( rItem.StaticWhichCast(RES_CHRATR_OVERLINE).GetColor() );
            break;
        case RES_CHRATR_WEIGHT :
            rFnt.SetWeight( rItem.StaticWhichCast(RES_CHRATR_WEIGHT).GetWeight(), SwFontScript::Latin );
            break;
        case RES_CHRATR_WORDLINEMODE :
            rFnt.SetWordLineMode( rItem.StaticWhichCast(RES_CHRATR_WORDLINEMODE).GetValue() );
            break;
        case RES_CHRATR_AUTOKERN :
            if( rItem.StaticWhichCast(RES_CHRATR_AUTOKERN).GetValue() )
            {
                rFnt.SetAutoKern( (!m_pIDocumentSettingAccess ||
                                   !m_pIDocumentSettingAccess->get(DocumentSettingId::KERN_ASIAN_PUNCTUATION)) ?
                                     FontKerning::FontSpecific :
                                     FontKerning::Asian );
            }
            else
                rFnt.SetAutoKern( FontKerning::NONE );
            break;
        case RES_CHRATR_BACKGROUND :
            rFnt.SetBackColor(rItem.StaticWhichCast(RES_CHRATR_BACKGROUND).GetColor());
            break;
        case RES_CHRATR_HIGHLIGHT :
            rFnt.SetHighlightColor( rItem.StaticWhichCast(RES_CHRATR_HIGHLIGHT).GetColor() );
            break;
        case RES_CHRATR_NOHYPHEN :
            if ( m_pShell && m_pShell->GetWin() &&
                            m_pShell->GetViewOptions()->IsViewMetaChars() )
            {
                if ( rItem.StaticWhichCast(RES_CHRATR_NOHYPHEN).GetValue() )
                {
                    rFnt.SetUnderline( LINESTYLE_DOTTED );
                    rFnt.SetUnderColor( COL_LIGHTGRAY );
                }
                else
                    ActivateTop( rFnt, RES_CHRATR_UNDERLINE );
            }
            break;
        case RES_CHRATR_CJK_FONT :
        {
            auto& rFontItem = rItem.StaticWhichCast(RES_CHRATR_CJK_FONT);
            rFnt.SetName( rFontItem.GetFamilyName(), SwFontScript::CJK );
            rFnt.SetStyleName( rFontItem.GetStyleName(), SwFontScript::CJK );
            rFnt.SetFamily( rFontItem.GetFamily(), SwFontScript::CJK );
            rFnt.SetPitch( rFontItem.GetPitch(), SwFontScript::CJK );
            rFnt.SetCharSet( rFontItem.GetCharSet(), SwFontScript::CJK );
            break;
        }
        case RES_CHRATR_CJK_FONTSIZE :
            rFnt.SetSize(Size( 0, rItem.StaticWhichCast(RES_CHRATR_CJK_FONTSIZE).GetHeight()), SwFontScript::CJK);
            break;
        case RES_CHRATR_CJK_LANGUAGE :
            rFnt.SetLanguage( rItem.StaticWhichCast(RES_CHRATR_CJK_LANGUAGE).GetLanguage(), SwFontScript::CJK );
            break;
        case RES_CHRATR_CJK_POSTURE :
            rFnt.SetItalic( rItem.StaticWhichCast(RES_CHRATR_CJK_POSTURE).GetPosture(), SwFontScript::CJK );
            break;
        case RES_CHRATR_CJK_WEIGHT :
            rFnt.SetWeight( rItem.StaticWhichCast(RES_CHRATR_CJK_WEIGHT).GetWeight(), SwFontScript::CJK );
            break;
        case RES_CHRATR_CTL_FONT :
        {
            auto& rFontItem = rItem.StaticWhichCast(RES_CHRATR_CTL_FONT);
            rFnt.SetName( rFontItem.GetFamilyName(), SwFontScript::CTL );
            rFnt.SetStyleName( rFontItem.GetStyleName(), SwFontScript::CTL );
            rFnt.SetFamily( rFontItem.GetFamily(), SwFontScript::CTL );
            rFnt.SetPitch( rFontItem.GetPitch(), SwFontScript::CTL );
            rFnt.SetCharSet( rFontItem.GetCharSet(), SwFontScript::CTL );
            break;
        }
        case RES_CHRATR_CTL_FONTSIZE :
            rFnt.SetSize(Size(0, rItem.StaticWhichCast(RES_CHRATR_CTL_FONTSIZE).GetHeight() ), SwFontScript::CTL);
            break;
        case RES_CHRATR_CTL_LANGUAGE :
            rFnt.SetLanguage( rItem.StaticWhichCast(RES_CHRATR_CTL_LANGUAGE).GetLanguage(), SwFontScript::CTL );
            break;
        case RES_CHRATR_CTL_POSTURE :
            rFnt.SetItalic( rItem.StaticWhichCast(RES_CHRATR_CTL_POSTURE).GetPosture(), SwFontScript::CTL );
            break;
        case RES_CHRATR_CTL_WEIGHT :
            rFnt.SetWeight( rItem.StaticWhichCast(RES_CHRATR_CTL_WEIGHT).GetWeight(), SwFontScript::CTL );
            break;
        case RES_CHRATR_EMPHASIS_MARK :
            rFnt.SetEmphasisMark( rItem.StaticWhichCast(RES_CHRATR_EMPHASIS_MARK).GetEmphasisMark() );
            break;
        case RES_CHRATR_SCALEW :
            rFnt.SetPropWidth( rItem.StaticWhichCast(RES_CHRATR_SCALEW).GetValue() );
            break;
        case RES_CHRATR_RELIEF :
            rFnt.SetRelief( rItem.StaticWhichCast(RES_CHRATR_RELIEF).GetValue() );
            break;
        case RES_CHRATR_HIDDEN :
            if (m_pShell && m_pShell->GetWin())
            {
                if ( rItem.StaticWhichCast(RES_CHRATR_HIDDEN).GetValue() )
                    rFnt.SetUnderline( LINESTYLE_DOTTED );
                else
                    ActivateTop( rFnt, RES_CHRATR_UNDERLINE );
            }
            break;
        case RES_CHRATR_ROTATE :
        {
            // rotate attribute is applied, when:
            // 1. ruby stack is empty and
            // 2. top of two line stack ( or default attribute )is an
            //    deactivated two line attribute
            const bool bRuby =
                0 != m_aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].size();

            if ( bRuby )
                break;

            const sal_uInt16 nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ];
            bool bTwoLineAct = false;
            const SwTextAttr* pTwoLineAttr = GetTop(nTwoLineStack);

            if ( pTwoLineAttr )
            {
                const auto& rTwoLineItem = *CharFormat::GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES );
                bTwoLineAct = rTwoLineItem.GetValue();
            }
            else
                bTwoLineAct = m_pDefaultArray[ nTwoLineStack ]->StaticWhichCast(RES_CHRATR_TWO_LINES).GetValue();

            if ( !bTwoLineAct )
                rFnt.SetVertical( rItem.StaticWhichCast(RES_CHRATR_ROTATE).GetValue(), m_bVertLayout, m_bVertLayoutLRBT );

            break;
        }
        case RES_CHRATR_TWO_LINES :
        {
            bool bRuby = 0 !=
                    m_aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].size();

            // two line is activated, if
            // 1. no ruby attribute is set and
            // 2. attribute is active
            if ( !bRuby && rItem.StaticWhichCast(RES_CHRATR_TWO_LINES).GetValue() )
            {
                rFnt.SetVertical( 0_deg10, m_bVertLayout );
                break;
            }

            // a deactivating two line attribute is on top of stack,
            // check if rotate attribute has to be enabled
            if ( bRuby )
                break;

            const sal_uInt16 nRotateStack = StackPos[ RES_CHRATR_ROTATE ];
            const SwTextAttr* pRotateAttr = GetTop(nRotateStack);

            if ( pRotateAttr )
            {
                const auto& rRotateItem = *CharFormat::GetItem( *pRotateAttr, RES_CHRATR_ROTATE );
                rFnt.SetVertical( rRotateItem.GetValue(), m_bVertLayout );
            }
            else
                rFnt.SetVertical(m_pDefaultArray[ nRotateStack ]->StaticWhichCast(RES_CHRATR_ROTATE).GetValue(), m_bVertLayout);
            break;
        }
        case RES_TXTATR_CJK_RUBY :
            rFnt.SetVertical( 0_deg10, m_bVertLayout );
            break;
        case RES_TXTATR_REFMARK :
            if ( bPush )
                rFnt.GetRef()++;
            else
                rFnt.GetRef()--;
            break;
        case RES_TXTATR_TOXMARK :
            if ( bPush )
                rFnt.GetTox()++;
            else
                rFnt.GetTox()--;
            break;
        case RES_TXTATR_META:
        case RES_TXTATR_METAFIELD:
            if ( bPush )
                rFnt.GetMeta()++;
            else
                rFnt.GetMeta()--;
            break;
        case RES_TXTATR_CONTENTCONTROL:
            if (bPush)
            {
                rFnt.GetContentControl()++;
            }
            else
            {
                rFnt.GetContentControl()--;
            }
            break;
        case RES_TXTATR_INPUTFIELD :
            if ( bPush )
                rFnt.GetInputField()++;
            else
                rFnt.GetInputField()--;
            break;
    }
}

/// Takes the default font and calculated the ascent and height
void SwAttrHandler::GetDefaultAscentAndHeight( SwViewShell const * pShell, OutputDevicconst & rOut,
                                               sal_uInt16& nAscent, sal_uInt16& nHeight ) const
{
    OSL_ENSURE(m_oFnt, "No font available for GetDefaultAscentAndHeight");

    if (m_oFnt)
    {
        SwFont aFont( *m_oFnt );
        nHeight = aFont.GetHeight( pShell, rOut );
        nAscent = aFont.GetAscent( pShell, rOut );
    }
}

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

Messung V0.5
C=93 H=98 G=95

¤ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet)  ¤

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






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge