<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drawfont.hxx,v $
 *
 *  $Revision: 1.38 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 08:55:25 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _DRAWFONT_HXX
#define _DRAWFONT_HXX

#include <tools/solar.h>
#include <tools/string.hxx>
#include <errhdl.hxx>

class SwTxtFrm;
class OutputDevice;
class ViewShell;
class SwScriptInfo;
class Point;
class SwWrongList;
class Size;
class SwFont;
class Font;
class SwUnderlineFont;

/*************************************************************************
 *                      class SwDrawTextInfo
 *
 * encapsulates information for drawing text
 *************************************************************************/

class SwDrawTextInfo
{
    const SwTxtFrm* pFrm;
    OutputDevice* pOut;
    ViewShell* pSh;
    const SwScriptInfo* pScriptInfo;
    const Point* pPos;
    const XubString* pText;
    const SwWrongList* pWrong;
    const SwWrongList* pSmartTags; // SMARTTAGS
    const Size* pSize;
    SwFont *pFnt;
    SwUnderlineFont* pUnderFnt;
    xub_StrLen* pHyphPos;
    long nLeft;
    long nRight;
    long nKanaDiff;
    xub_StrLen nIdx;
    xub_StrLen nLen;
    xub_StrLen nOfst;
    USHORT nWidth;
    USHORT nAscent;
    USHORT nCompress;
    long nSperren;
    long nSpace;
    long nKern;
    xub_StrLen nNumberOfBlanks;
    BYTE nCursorBidiLevel;
    BOOL bBullet : 1;
    BOOL bUpper : 1;        // Fuer Kapitaelchen: Grossbuchstaben-Flag
    BOOL bDrawSpace : 1;    // Fuer Kapitaelchen: Unter/Durchstreichung
    BOOL bGreyWave  : 1;    // Graue Wellenlinie beim extended TextInput
    BOOL bSpaceStop : 1;    // For underlining we need to know, if a portion
                            // is right in front of a hole portion or a
                            // fix margin portion.
    BOOL bSnapToGrid : 1;   // Does paragraph snap to grid?
    BOOL bIgnoreFrmRTL : 1; // Paint text as if text has LTR direction, used for
                            // line numbering
    BOOL bPosMatchesBounds :1;  // GetCrsrOfst should not return the next
                                // position if screen position is inside second
                                // half of bound rect, used for Accessibility

    SwDrawTextInfo();       // nicht zulaessig
public:

#ifndef PRODUCT
    BOOL bPos   : 1;    // These flags should control, that the appropriate
    BOOL bWrong : 1;    // Set-function has been called before calling
    BOOL bSize  : 1;    //  the Get-function of a member
    BOOL bFnt   : 1;
    BOOL bHyph  : 1;
    BOOL bLeft  : 1;
    BOOL bRight : 1;
    BOOL bKana  : 1;
    BOOL bOfst  : 1;
    BOOL bAscent: 1;
    BOOL bSperr : 1;
    BOOL bSpace : 1;
    BOOL bNumberOfBlanks : 1;
    BOOL bUppr  : 1;
    BOOL bDrawSp: 1;
#endif

    SwDrawTextInfo( ViewShell *pS, OutputDevice &rO, const SwScriptInfo* pSI,
                    const XubString &rSt, xub_StrLen nI, xub_StrLen nL,
                    USHORT nW = 0, BOOL bB = FALSE )
    {
        pFrm = NULL;
        pSh = pS;
        pOut = &rO;
        pScriptInfo = pSI;
        pText = &rSt;
        nIdx = nI;
        nLen = nL;
        nKern = 0;
        nCompress = 0;
        nWidth = nW;
        nNumberOfBlanks = 0;
        nCursorBidiLevel = 0;
        bBullet = bB;
        pUnderFnt = 0;
        bGreyWave = FALSE;
        bSpaceStop = FALSE;
        bSnapToGrid = FALSE;
        bIgnoreFrmRTL = FALSE;
        bPosMatchesBounds = FALSE;

        // These values are initialized but, they have to be
        // set explicitly via their Set-function before they may
        // be accessed by their Get-function:
        pPos = 0;
        pWrong = 0;
        pSmartTags = 0;
        pSize = 0;
        pFnt = 0;
        pHyphPos = 0;
        nLeft = 0;
        nRight = 0;
        nKanaDiff = 0;
        nOfst = 0;
        nAscent = 0;
        nSperren = 0;
        nSpace = 0;
        bUpper = FALSE;
        bDrawSpace = FALSE;

#ifndef PRODUCT
        // these flags control, whether the matching member variables have
        // been set by using the Set-function before they may be accessed
        // by their Get-function:
        bPos = bWrong = bSize = bFnt = bAscent = bSpace = bNumberOfBlanks = bUppr =
        bDrawSp = bLeft = bRight = bKana = bOfst = bHyph = bSperr = FALSE;
#endif
    }

    const SwTxtFrm* GetFrm() const
    {
        return pFrm;
    }

    void SetFrm( const SwTxtFrm* pNewFrm )
    {
        pFrm = pNewFrm;
    }

    ViewShell *GetShell() const
    {
        return pSh;
    }

    OutputDevice& GetOut() const
    {
        return *pOut;
    }

    OutputDevice *GetpOut() const
    {
        return pOut;
    }

    const SwScriptInfo* GetScriptInfo() const
    {
        return pScriptInfo;
    }

    const Point &GetPos() const
    {
        ASSERT( bPos, "DrawTextInfo: Undefined Position" );
        return *pPos;
    }

    xub_StrLen *GetHyphPos() const
    {
        ASSERT( bHyph, "DrawTextInfo: Undefined Hyph Position" );
        return pHyphPos;
    }

    const XubString &GetText() const
    {
        return *pText;
    }

    const SwWrongList* GetWrong() const
    {
        ASSERT( bWrong, "DrawTextInfo: Undefined WrongList" );
        return pWrong;
    }

    const SwWrongList* GetSmartTags() const
    {
        return pSmartTags;
    }

    const Size &GetSize() const
    {
        ASSERT( bSize, "DrawTextInfo: Undefined Size" );
        return *pSize;
    }

    SwFont* GetFont() const
    {
        ASSERT( bFnt, "DrawTextInfo: Undefined Font" );
        return pFnt;
    }

    SwUnderlineFont* GetUnderFnt() const
    {
        return pUnderFnt;
    }

    xub_StrLen GetIdx() const
    {
        return nIdx;
    }

    xub_StrLen GetLen() const
    {
        return nLen;
    }

    xub_StrLen GetOfst() const
    {
        ASSERT( bOfst, "DrawTextInfo: Undefined Offset" );
        return nOfst;
    }

    xub_StrLen GetEnd() const
    {
        return nIdx + nLen;
    }

    long GetLeft() const
    {
        ASSERT( bLeft, "DrawTextInfo: Undefined left range" );
        return nLeft;
    }

    long GetRight() const
    {
        ASSERT( bRight, "DrawTextInfo: Undefined right range" );
        return nRight;
    }

    long GetKanaDiff() const
    {
        ASSERT( bKana, "DrawTextInfo: Undefined kana difference" );
        return nKanaDiff;
    }

    USHORT GetWidth() const
    {
        return nWidth;
    }

    USHORT GetAscent() const
    {
        ASSERT( bAscent, "DrawTextInfo: Undefined Ascent" );
        return nAscent;
    }

    USHORT GetKanaComp() const
    {
        return nCompress;
    }

    long GetSperren() const
    {
        ASSERT( bSperr, "DrawTextInfo: Undefined >Sperren<" );
        return nSperren;
    }

    long GetKern() const
    {
        return nKern;
    }

    long GetSpace() const
    {
        ASSERT( bSpace, "DrawTextInfo: Undefined Spacing" );
        return nSpace;
    }

    xub_StrLen GetNumberOfBlanks() const
    {
        ASSERT( bNumberOfBlanks, "DrawTextInfo::Undefined NumberOfBlanks" );
        return nNumberOfBlanks;
    }

    BYTE GetCursorBidiLevel() const
    {
        return nCursorBidiLevel;
    }

    BOOL GetBullet() const
    {
        return bBullet;
    }

    BOOL GetUpper() const
    {
        ASSERT( bUppr, "DrawTextInfo: Undefined Upperflag" );
        return bUpper;
    }

    BOOL GetDrawSpace() const
    {
        ASSERT( bDrawSp, "DrawTextInfo: Undefined DrawSpaceflag" );
        return bDrawSpace;
    }

    BOOL GetGreyWave() const
    {
        return bGreyWave;
    }

    BOOL IsSpaceStop() const
    {
        return bSpaceStop;
    }

    BOOL SnapToGrid() const
    {
        return bSnapToGrid;
    }

    BOOL IsIgnoreFrmRTL() const
    {
        return bIgnoreFrmRTL;
    }

    BOOL IsPosMatchesBounds() const
    {
        return bPosMatchesBounds;
    }

    void SetOut( OutputDevice &rNew )
    {
        pOut = &rNew;
    }

    void SetPos( const Point &rNew )
    {
        pPos = &rNew;
#ifndef PRODUCT
        bPos = TRUE;
#endif
    }

    void SetHyphPos( xub_StrLen *pNew )
    {
        pHyphPos = pNew;
#ifndef PRODUCT
        bHyph = TRUE;
#endif
    }

    void SetText( const XubString &rNew )
    {
        pText = &rNew;
    }

    void SetWrong( const SwWrongList* pNew )
    {
        pWrong = pNew;
#ifndef PRODUCT
        bWrong = TRUE;
#endif
    }

    void SetSmartTags( const SwWrongList* pNew )
    {
        pSmartTags = pNew;
    }

    void SetSize( const Size &rNew )
    {
        pSize = &rNew;
#ifndef PRODUCT
        bSize = TRUE;
#endif
    }

    void SetFont( SwFont* pNew )
    {
        pFnt = pNew;
#ifndef PRODUCT
        bFnt = TRUE;
#endif
    }

    void SetIdx( xub_StrLen nNew )
    {
        nIdx = nNew;
    }

    void SetLen( xub_StrLen nNew )
    {
        nLen = nNew;
    }

    void SetOfst( xub_StrLen nNew )
    {
        nOfst = nNew;
#ifndef PRODUCT
        bOfst = TRUE;
#endif
    }

    void SetLeft( long nNew )
    {
        nLeft = nNew;
#ifndef PRODUCT
        bLeft = TRUE;
#endif
    }

    void SetRight( long nNew )
    {
        nRight = nNew;
#ifndef PRODUCT
        bRight = TRUE;
#endif
    }

    void SetKanaDiff( long nNew )
    {
        nKanaDiff = nNew;
#ifndef PRODUCT
        bKana = TRUE;
#endif
    }

    void SetWidth( USHORT nNew )
    {
        nWidth = nNew;
    }

    void SetAscent( USHORT nNew )
    {
        nAscent = nNew;
#ifndef PRODUCT
        bAscent = TRUE;
#endif
    }

    void SetKern( long nNew )
    {
        nKern = nNew;
    }

    void SetSpace( long nNew )
    {
        if( nNew < 0 )
        {
            nSperren = -nNew;
            nSpace = 0;
        }
        else
        {
            nSpace = nNew;
            nSperren = 0;
        }
#ifndef PRODUCT
        bSpace = TRUE;
        bSperr = TRUE;
#endif
    }

    void SetNumberOfBlanks( xub_StrLen nNew )
    {
#ifndef PRODUCT
        bNumberOfBlanks = TRUE;
#endif
        nNumberOfBlanks = nNew;
    }

    void SetCursorBidiLevel( BYTE nNew )
    {
        nCursorBidiLevel = nNew;
    }

    void SetKanaComp( short nNew )
    {
        nCompress = nNew;
    }

    void SetBullet( BOOL bNew )
    {
        bBullet = bNew;
    }

    void SetUnderFnt( SwUnderlineFont* pULFnt )
    {
        pUnderFnt = pULFnt;
    }

    void SetUpper( BOOL bNew )
    {
        bUpper = bNew;
#ifndef PRODUCT
        bUppr = TRUE;
#endif
    }

    void SetDrawSpace( BOOL bNew )
    {
        bDrawSpace = bNew;
#ifndef PRODUCT
        bDrawSp = TRUE;
#endif
    }

    void SetGreyWave( BOOL bNew )
    {
        bGreyWave = bNew;
    }

    void SetSpaceStop( BOOL bNew )
    {
        bSpaceStop = bNew;
    }

    void SetSnapToGrid( BOOL bNew )
    {
        bSnapToGrid = bNew;
    }

    void SetIgnoreFrmRTL( BOOL bNew )
    {
        bIgnoreFrmRTL = bNew;
    }

    void SetPosMatchesBounds( BOOL bNew )
    {
        bPosMatchesBounds = bNew;
    }

    void Shift( USHORT nDir );

    // sets a new color at the output device if necessary
    // if a font is passed as argument, the change if made to the font
    // otherwise the font at the output device is changed
    // returns if the font has been changed
    sal_Bool ApplyAutoColor( Font* pFnt = 0 );
};

#endif
<commit_msg>INTEGRATION: CWS gcframework_DEV300 (1.37.364); FILE MERGED 2008/01/08 10:04:49 tl 1.37.364.2: RESYNC: (1.37-1.38); FILE MERGED 2007/11/26 09:14:31 tl 1.37.364.1: #i83776# get SwXTextMarkup::commitTextMarkup working<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drawfont.hxx,v $
 *
 *  $Revision: 1.39 $
 *
 *  last change: $Author: obo $ $Date: 2008-02-26 09:45:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _DRAWFONT_HXX
#define _DRAWFONT_HXX

#include <tools/solar.h>
#include <tools/string.hxx>
#include <errhdl.hxx>

class SwTxtFrm;
class OutputDevice;
class ViewShell;
class SwScriptInfo;
class Point;
class SwWrongList;
class Size;
class SwFont;
class Font;
class SwUnderlineFont;

/*************************************************************************
 *                      class SwDrawTextInfo
 *
 * encapsulates information for drawing text
 *************************************************************************/

class SwDrawTextInfo
{
    const SwTxtFrm* pFrm;
    OutputDevice* pOut;
    ViewShell* pSh;
    const SwScriptInfo* pScriptInfo;
    const Point* pPos;
    const XubString* pText;
    const SwWrongList* pWrong;
    const SwWrongList* pGrammarCheck;
    const SwWrongList* pSmartTags; // SMARTTAGS
    const Size* pSize;
    SwFont *pFnt;
    SwUnderlineFont* pUnderFnt;
    xub_StrLen* pHyphPos;
    long nLeft;
    long nRight;
    long nKanaDiff;
    xub_StrLen nIdx;
    xub_StrLen nLen;
    xub_StrLen nOfst;
    USHORT nWidth;
    USHORT nAscent;
    USHORT nCompress;
    long nSperren;
    long nSpace;
    long nKern;
    xub_StrLen nNumberOfBlanks;
    BYTE nCursorBidiLevel;
    BOOL bBullet : 1;
    BOOL bUpper : 1;        // Fuer Kapitaelchen: Grossbuchstaben-Flag
    BOOL bDrawSpace : 1;    // Fuer Kapitaelchen: Unter/Durchstreichung
    BOOL bGreyWave  : 1;    // Graue Wellenlinie beim extended TextInput
    BOOL bSpaceStop : 1;    // For underlining we need to know, if a portion
                            // is right in front of a hole portion or a
                            // fix margin portion.
    BOOL bSnapToGrid : 1;   // Does paragraph snap to grid?
    BOOL bIgnoreFrmRTL : 1; // Paint text as if text has LTR direction, used for
                            // line numbering
    BOOL bPosMatchesBounds :1;  // GetCrsrOfst should not return the next
                                // position if screen position is inside second
                                // half of bound rect, used for Accessibility

    SwDrawTextInfo();       // nicht zulaessig
public:

#ifndef PRODUCT
    BOOL bPos   : 1;            // These flags should control, that the appropriate
    BOOL bWrong : 1;            // Set-function has been called before calling
    BOOL bGrammarCheck : 1;     //  the Get-function of a member
    BOOL bSize  : 1;
    BOOL bFnt   : 1;
    BOOL bHyph  : 1;
    BOOL bLeft  : 1;
    BOOL bRight : 1;
    BOOL bKana  : 1;
    BOOL bOfst  : 1;
    BOOL bAscent: 1;
    BOOL bSperr : 1;
    BOOL bSpace : 1;
    BOOL bNumberOfBlanks : 1;
    BOOL bUppr  : 1;
    BOOL bDrawSp: 1;
#endif

    SwDrawTextInfo( ViewShell *pS, OutputDevice &rO, const SwScriptInfo* pSI,
                    const XubString &rSt, xub_StrLen nI, xub_StrLen nL,
                    USHORT nW = 0, BOOL bB = FALSE )
    {
        pFrm = NULL;
        pSh = pS;
        pOut = &rO;
        pScriptInfo = pSI;
        pText = &rSt;
        nIdx = nI;
        nLen = nL;
        nKern = 0;
        nCompress = 0;
        nWidth = nW;
        nNumberOfBlanks = 0;
        nCursorBidiLevel = 0;
        bBullet = bB;
        pUnderFnt = 0;
        bGreyWave = FALSE;
        bSpaceStop = FALSE;
        bSnapToGrid = FALSE;
        bIgnoreFrmRTL = FALSE;
        bPosMatchesBounds = FALSE;

        // These values are initialized but, they have to be
        // set explicitly via their Set-function before they may
        // be accessed by their Get-function:
        pPos = 0;
        pWrong = 0;
        pGrammarCheck = 0;
        pSmartTags = 0;
        pSize = 0;
        pFnt = 0;
        pHyphPos = 0;
        nLeft = 0;
        nRight = 0;
        nKanaDiff = 0;
        nOfst = 0;
        nAscent = 0;
        nSperren = 0;
        nSpace = 0;
        bUpper = FALSE;
        bDrawSpace = FALSE;

#ifndef PRODUCT
        // these flags control, whether the matching member variables have
        // been set by using the Set-function before they may be accessed
        // by their Get-function:
        bPos = bWrong = bGrammarCheck = bSize = bFnt = bAscent = bSpace = bNumberOfBlanks = bUppr =
        bDrawSp = bLeft = bRight = bKana = bOfst = bHyph = bSperr = FALSE;
#endif
    }

    const SwTxtFrm* GetFrm() const
    {
        return pFrm;
    }

    void SetFrm( const SwTxtFrm* pNewFrm )
    {
        pFrm = pNewFrm;
    }

    ViewShell *GetShell() const
    {
        return pSh;
    }

    OutputDevice& GetOut() const
    {
        return *pOut;
    }

    OutputDevice *GetpOut() const
    {
        return pOut;
    }

    const SwScriptInfo* GetScriptInfo() const
    {
        return pScriptInfo;
    }

    const Point &GetPos() const
    {
        ASSERT( bPos, "DrawTextInfo: Undefined Position" );
        return *pPos;
    }

    xub_StrLen *GetHyphPos() const
    {
        ASSERT( bHyph, "DrawTextInfo: Undefined Hyph Position" );
        return pHyphPos;
    }

    const XubString &GetText() const
    {
        return *pText;
    }

    const SwWrongList* GetWrong() const
    {
        ASSERT( bWrong, "DrawTextInfo: Undefined WrongList" );
        return pWrong;
    }

    const SwWrongList* GetGrammarCheck() const
    {
        ASSERT( bGrammarCheck, "DrawTextInfo: Undefined GrammarCheck List" );
        return pGrammarCheck;
    }

    const SwWrongList* GetSmartTags() const
    {
        return pSmartTags;
    }

    const Size &GetSize() const
    {
        ASSERT( bSize, "DrawTextInfo: Undefined Size" );
        return *pSize;
    }

    SwFont* GetFont() const
    {
        ASSERT( bFnt, "DrawTextInfo: Undefined Font" );
        return pFnt;
    }

    SwUnderlineFont* GetUnderFnt() const
    {
        return pUnderFnt;
    }

    xub_StrLen GetIdx() const
    {
        return nIdx;
    }

    xub_StrLen GetLen() const
    {
        return nLen;
    }

    xub_StrLen GetOfst() const
    {
        ASSERT( bOfst, "DrawTextInfo: Undefined Offset" );
        return nOfst;
    }

    xub_StrLen GetEnd() const
    {
        return nIdx + nLen;
    }

    long GetLeft() const
    {
        ASSERT( bLeft, "DrawTextInfo: Undefined left range" );
        return nLeft;
    }

    long GetRight() const
    {
        ASSERT( bRight, "DrawTextInfo: Undefined right range" );
        return nRight;
    }

    long GetKanaDiff() const
    {
        ASSERT( bKana, "DrawTextInfo: Undefined kana difference" );
        return nKanaDiff;
    }

    USHORT GetWidth() const
    {
        return nWidth;
    }

    USHORT GetAscent() const
    {
        ASSERT( bAscent, "DrawTextInfo: Undefined Ascent" );
        return nAscent;
    }

    USHORT GetKanaComp() const
    {
        return nCompress;
    }

    long GetSperren() const
    {
        ASSERT( bSperr, "DrawTextInfo: Undefined >Sperren<" );
        return nSperren;
    }

    long GetKern() const
    {
        return nKern;
    }

    long GetSpace() const
    {
        ASSERT( bSpace, "DrawTextInfo: Undefined Spacing" );
        return nSpace;
    }

    xub_StrLen GetNumberOfBlanks() const
    {
        ASSERT( bNumberOfBlanks, "DrawTextInfo::Undefined NumberOfBlanks" );
        return nNumberOfBlanks;
    }

    BYTE GetCursorBidiLevel() const
    {
        return nCursorBidiLevel;
    }

    BOOL GetBullet() const
    {
        return bBullet;
    }

    BOOL GetUpper() const
    {
        ASSERT( bUppr, "DrawTextInfo: Undefined Upperflag" );
        return bUpper;
    }

    BOOL GetDrawSpace() const
    {
        ASSERT( bDrawSp, "DrawTextInfo: Undefined DrawSpaceflag" );
        return bDrawSpace;
    }

    BOOL GetGreyWave() const
    {
        return bGreyWave;
    }

    BOOL IsSpaceStop() const
    {
        return bSpaceStop;
    }

    BOOL SnapToGrid() const
    {
        return bSnapToGrid;
    }

    BOOL IsIgnoreFrmRTL() const
    {
        return bIgnoreFrmRTL;
    }

    BOOL IsPosMatchesBounds() const
    {
        return bPosMatchesBounds;
    }

    void SetOut( OutputDevice &rNew )
    {
        pOut = &rNew;
    }

    void SetPos( const Point &rNew )
    {
        pPos = &rNew;
#ifndef PRODUCT
        bPos = TRUE;
#endif
    }

    void SetHyphPos( xub_StrLen *pNew )
    {
        pHyphPos = pNew;
#ifndef PRODUCT
        bHyph = TRUE;
#endif
    }

    void SetText( const XubString &rNew )
    {
        pText = &rNew;
    }

    void SetWrong( const SwWrongList* pNew )
    {
        pWrong = pNew;
#ifndef PRODUCT
        bWrong = TRUE;
#endif
    }

    void SetGrammarCheck( const SwWrongList* pNew )
    {
        pGrammarCheck = pNew;
#ifndef PRODUCT
        bGrammarCheck = TRUE;
#endif
    }

    void SetSmartTags( const SwWrongList* pNew )
    {
        pSmartTags = pNew;
    }

    void SetSize( const Size &rNew )
    {
        pSize = &rNew;
#ifndef PRODUCT
        bSize = TRUE;
#endif
    }

    void SetFont( SwFont* pNew )
    {
        pFnt = pNew;
#ifndef PRODUCT
        bFnt = TRUE;
#endif
    }

    void SetIdx( xub_StrLen nNew )
    {
        nIdx = nNew;
    }

    void SetLen( xub_StrLen nNew )
    {
        nLen = nNew;
    }

    void SetOfst( xub_StrLen nNew )
    {
        nOfst = nNew;
#ifndef PRODUCT
        bOfst = TRUE;
#endif
    }

    void SetLeft( long nNew )
    {
        nLeft = nNew;
#ifndef PRODUCT
        bLeft = TRUE;
#endif
    }

    void SetRight( long nNew )
    {
        nRight = nNew;
#ifndef PRODUCT
        bRight = TRUE;
#endif
    }

    void SetKanaDiff( long nNew )
    {
        nKanaDiff = nNew;
#ifndef PRODUCT
        bKana = TRUE;
#endif
    }

    void SetWidth( USHORT nNew )
    {
        nWidth = nNew;
    }

    void SetAscent( USHORT nNew )
    {
        nAscent = nNew;
#ifndef PRODUCT
        bAscent = TRUE;
#endif
    }

    void SetKern( long nNew )
    {
        nKern = nNew;
    }

    void SetSpace( long nNew )
    {
        if( nNew < 0 )
        {
            nSperren = -nNew;
            nSpace = 0;
        }
        else
        {
            nSpace = nNew;
            nSperren = 0;
        }
#ifndef PRODUCT
        bSpace = TRUE;
        bSperr = TRUE;
#endif
    }

    void SetNumberOfBlanks( xub_StrLen nNew )
    {
#ifndef PRODUCT
        bNumberOfBlanks = TRUE;
#endif
        nNumberOfBlanks = nNew;
    }

    void SetCursorBidiLevel( BYTE nNew )
    {
        nCursorBidiLevel = nNew;
    }

    void SetKanaComp( short nNew )
    {
        nCompress = nNew;
    }

    void SetBullet( BOOL bNew )
    {
        bBullet = bNew;
    }

    void SetUnderFnt( SwUnderlineFont* pULFnt )
    {
        pUnderFnt = pULFnt;
    }

    void SetUpper( BOOL bNew )
    {
        bUpper = bNew;
#ifndef PRODUCT
        bUppr = TRUE;
#endif
    }

    void SetDrawSpace( BOOL bNew )
    {
        bDrawSpace = bNew;
#ifndef PRODUCT
        bDrawSp = TRUE;
#endif
    }

    void SetGreyWave( BOOL bNew )
    {
        bGreyWave = bNew;
    }

    void SetSpaceStop( BOOL bNew )
    {
        bSpaceStop = bNew;
    }

    void SetSnapToGrid( BOOL bNew )
    {
        bSnapToGrid = bNew;
    }

    void SetIgnoreFrmRTL( BOOL bNew )
    {
        bIgnoreFrmRTL = bNew;
    }

    void SetPosMatchesBounds( BOOL bNew )
    {
        bPosMatchesBounds = bNew;
    }

    void Shift( USHORT nDir );

    // sets a new color at the output device if necessary
    // if a font is passed as argument, the change if made to the font
    // otherwise the font at the output device is changed
    // returns if the font has been changed
    sal_Bool ApplyAutoColor( Font* pFnt = 0 );
};

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2018-2020 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/

#ifndef TAO_PEGTL_CONTRIB_ICU_INTERNAL_HPP
#define TAO_PEGTL_CONTRIB_ICU_INTERNAL_HPP

#include <unicode/uchar.h>

#include "../analyze_traits.hpp"

#include "../../config.hpp"
#include "../../type_list.hpp"

#include "../../internal/enable_control.hpp"

namespace TAO_PEGTL_NAMESPACE
{
   namespace internal
   {
      namespace icu
      {
         template< typename Peek, UProperty P, bool V = true >
         struct binary_property
         {
            using rule_t = binary_property;
            using subs_t = empty_list;

            template< typename ParseInput >
            [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) )
            {
               if( const auto r = Peek::peek( in ) ) {
                  if( u_hasBinaryProperty( r.data, P ) == V ) {
                     in.bump( r.size );
                     return true;
                  }
               }
               return false;
            }
         };

         template< typename Peek, UProperty P, int V >
         struct property_value
         {
            using rule_t = property_value;
            using subs_t = empty_list;

            template< typename ParseInput >
            [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) )
            {
               if( const auto r = Peek::peek( in ) ) {
                  if( u_getIntPropertyValue( r.data, P ) == V ) {
                     in.bump( r.size );
                     return true;
                  }
               }
               return false;
            }
         };

      }  // namespace icu

      template< typename Peek, UProperty P, bool V >
      inline constexpr bool enable_control< icu::binary_property< Peek, P, V > > = false;

      template< typename Peek, UProperty P, int V >
      inline constexpr bool enable_control< icu::property_value< Peek, P, V > > = false;

   } // namespace internal

   template< typename Name, typename Peek, UProperty P, bool V >
   struct analyze_traits< Name, internal::icu::binary_property< Peek, P, V > >
      : analyze_any_traits<>
   {};

   template< typename Name, typename Peek, UProperty P, int V >
   struct analyze_traits< Name, internal::icu::property_value< Peek, P, V > >
      : analyze_any_traits<>
   {};

}  // namespace TAO_PEGTL_NAMESPACE

#endif
<commit_msg>clang-format<commit_after>// Copyright (c) 2018-2020 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/

#ifndef TAO_PEGTL_CONTRIB_ICU_INTERNAL_HPP
#define TAO_PEGTL_CONTRIB_ICU_INTERNAL_HPP

#include <unicode/uchar.h>

#include "../analyze_traits.hpp"

#include "../../config.hpp"
#include "../../type_list.hpp"

#include "../../internal/enable_control.hpp"

namespace TAO_PEGTL_NAMESPACE
{
   namespace internal
   {
      namespace icu
      {
         template< typename Peek, UProperty P, bool V = true >
         struct binary_property
         {
            using rule_t = binary_property;
            using subs_t = empty_list;

            template< typename ParseInput >
            [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) )
            {
               if( const auto r = Peek::peek( in ) ) {
                  if( u_hasBinaryProperty( r.data, P ) == V ) {
                     in.bump( r.size );
                     return true;
                  }
               }
               return false;
            }
         };

         template< typename Peek, UProperty P, int V >
         struct property_value
         {
            using rule_t = property_value;
            using subs_t = empty_list;

            template< typename ParseInput >
            [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) )
            {
               if( const auto r = Peek::peek( in ) ) {
                  if( u_getIntPropertyValue( r.data, P ) == V ) {
                     in.bump( r.size );
                     return true;
                  }
               }
               return false;
            }
         };

      }  // namespace icu

      template< typename Peek, UProperty P, bool V >
      inline constexpr bool enable_control< icu::binary_property< Peek, P, V > > = false;

      template< typename Peek, UProperty P, int V >
      inline constexpr bool enable_control< icu::property_value< Peek, P, V > > = false;

   }  // namespace internal

   template< typename Name, typename Peek, UProperty P, bool V >
   struct analyze_traits< Name, internal::icu::binary_property< Peek, P, V > >
      : analyze_any_traits<>
   {};

   template< typename Name, typename Peek, UProperty P, int V >
   struct analyze_traits< Name, internal::icu::property_value< Peek, P, V > >
      : analyze_any_traits<>
   {};

}  // namespace TAO_PEGTL_NAMESPACE

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: devicehelper.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 14:47:31 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_canvas.hxx"

#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>
#include <canvas/base/linepolypolygonbase.hxx>

#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/canvastools.hxx>
#include <basegfx/tools/canvastools.hxx>

#include "devicehelper.hxx"
#include "spritecanvas.hxx"
#include "spritecanvashelper.hxx"
#include "canvasbitmap.hxx"

using namespace ::com::sun::star;

namespace vclcanvas
{
    DeviceHelper::DeviceHelper() :
        mpSpriteCanvas(NULL),
        mpBackBuffer()
    {
    }

    void DeviceHelper::init( Window&        rOutputWindow,
                             SpriteCanvas&  rSpriteCanvas )
    {
        rSpriteCanvas.setWindow(
            uno::Reference<awt::XWindow2>(
                VCLUnoHelper::GetInterface(&rOutputWindow),
                uno::UNO_QUERY_THROW) );

        mpOutputWindow = &rOutputWindow;
        mpSpriteCanvas = &rSpriteCanvas;

        // setup back buffer
        mpBackBuffer.reset( new BackBuffer( rOutputWindow ) );
        mpBackBuffer->setSize( rOutputWindow.GetOutputSizePixel() );
    }

    geometry::RealSize2D DeviceHelper::getPhysicalResolution()
    {
        if( !mpOutputWindow )
            return ::canvas::tools::createInfiniteSize2D(); // we're disposed

        // Map a one-by-one millimeter box to pixel
        const MapMode aOldMapMode( mpOutputWindow->GetMapMode() );
        mpOutputWindow->SetMapMode( MapMode(MAP_MM) );
        const Size aPixelSize( mpOutputWindow->LogicToPixel(Size(1,1)) );
        mpOutputWindow->SetMapMode( aOldMapMode );

        return ::vcl::unotools::size2DFromSize( aPixelSize );
    }

    geometry::RealSize2D DeviceHelper::getPhysicalSize()
    {
        if( !mpOutputWindow )
            return ::canvas::tools::createInfiniteSize2D(); // we're disposed

        // Map the pixel dimensions of the output window to millimeter
        const MapMode aOldMapMode( mpOutputWindow->GetMapMode() );
        mpOutputWindow->SetMapMode( MapMode(MAP_MM) );
        const Size aLogSize( mpOutputWindow->PixelToLogic(mpOutputWindow->GetOutputSizePixel()) );
        mpOutputWindow->SetMapMode( aOldMapMode );

        return ::vcl::unotools::size2DFromSize( aLogSize );
    }

    uno::Reference< rendering::XLinePolyPolygon2D > DeviceHelper::createCompatibleLinePolyPolygon(
        const uno::Reference< rendering::XGraphicDevice >&              ,
        const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >&  points )
    {
        if( !mpOutputWindow )
            return uno::Reference< rendering::XLinePolyPolygon2D >(); // we're disposed

        return uno::Reference< rendering::XLinePolyPolygon2D >(
            new ::canvas::LinePolyPolygonBase(
                ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence( points ) ) );
    }

    uno::Reference< rendering::XBezierPolyPolygon2D > DeviceHelper::createCompatibleBezierPolyPolygon(
        const uno::Reference< rendering::XGraphicDevice >&                      ,
        const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >&  points )
    {
        if( !mpOutputWindow )
            return uno::Reference< rendering::XBezierPolyPolygon2D >(); // we're disposed

        return uno::Reference< rendering::XBezierPolyPolygon2D >(
            new ::canvas::LinePolyPolygonBase(
                ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence( points ) ) );
    }

    uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleBitmap(
        const uno::Reference< rendering::XGraphicDevice >&  ,
        const geometry::IntegerSize2D&                      size )
    {
        if( !mpSpriteCanvas )
            return uno::Reference< rendering::XBitmap >(); // we're disposed

        return uno::Reference< rendering::XBitmap >(
            new CanvasBitmap( ::vcl::unotools::sizeFromIntegerSize2D(size),
                              false,
                              mpSpriteCanvas ) );
    }

    uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileBitmap(
        const uno::Reference< rendering::XGraphicDevice >&  ,
        const geometry::IntegerSize2D&                       )
    {
        return uno::Reference< rendering::XVolatileBitmap >();
    }

    uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleAlphaBitmap(
        const uno::Reference< rendering::XGraphicDevice >&  ,
        const geometry::IntegerSize2D&                      size )
    {
        if( !mpSpriteCanvas )
            return uno::Reference< rendering::XBitmap >(); // we're disposed

        return uno::Reference< rendering::XBitmap >( new CanvasBitmap( ::vcl::unotools::sizeFromIntegerSize2D(size),
                                                                       true,
                                                                       mpSpriteCanvas ) );
    }

    uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileAlphaBitmap(
        const uno::Reference< rendering::XGraphicDevice >&  ,
        const geometry::IntegerSize2D&                       )
    {
        return uno::Reference< rendering::XVolatileBitmap >();
    }

    sal_Bool DeviceHelper::hasFullScreenMode()
    {
        // TODO(F3): offer fullscreen mode the XCanvas way
        return false;
    }

    sal_Bool DeviceHelper::enterFullScreenMode( sal_Bool bEnter )
    {
        (void)bEnter;

        // TODO(F3): offer fullscreen mode the XCanvas way
        return false;
    }

    ::sal_Int32 DeviceHelper::createBuffers( ::sal_Int32 nBuffers )
    {
        (void)nBuffers;

        // TODO(F3): implement XBufferStrategy interface. For now, we
        // _always_ will have exactly one backbuffer
        return 1;
    }

    void DeviceHelper::destroyBuffers()
    {
        // TODO(F3): implement XBufferStrategy interface. For now, we
        // _always_ will have exactly one backbuffer
    }

    ::sal_Bool DeviceHelper::showBuffer( ::sal_Bool bUpdateAll )
    {
        // forward to sprite canvas helper
        if( !mpSpriteCanvas )
            return false;

        return mpSpriteCanvas->updateScreen( bUpdateAll );
    }

    ::sal_Bool DeviceHelper::switchBuffer( ::sal_Bool bUpdateAll )
    {
        // no difference for VCL canvas
        return showBuffer( bUpdateAll );
    }

    void DeviceHelper::disposing()
    {
        // release all references
        mpSpriteCanvas = NULL;
        mpBackBuffer.reset();
    }

    uno::Any DeviceHelper::getDeviceHandle() const
    {
        if( !mpOutputWindow )
            return uno::Any();

        return uno::makeAny(
            reinterpret_cast< sal_Int64 >(mpOutputWindow) );
    }

    uno::Any DeviceHelper::getSurfaceHandle() const
    {
        if( !mpBackBuffer )
            return uno::Any();

        return uno::makeAny(
            reinterpret_cast< sal_Int64 >(&mpBackBuffer->getOutDev()) );
    }

    void DeviceHelper::notifySizeUpdate( const awt::Rectangle& rBounds )
    {
        if( mpBackBuffer )
            mpBackBuffer->setSize( ::Size(rBounds.Width,
                                          rBounds.Height) );
    }

    void DeviceHelper::dumpScreenContent() const
    {
        static sal_uInt32 nFilePostfixCount(0);

        if( mpOutputWindow )
        {
            String aFilename( String::CreateFromAscii("dbg_frontbuffer") );
            aFilename += String::CreateFromInt32(nFilePostfixCount);
            aFilename += String::CreateFromAscii(".bmp");

            SvFileStream aStream( aFilename, STREAM_STD_READWRITE );

            const ::Point aEmptyPoint;
            bool bOldMap( mpOutputWindow->IsMapModeEnabled() );
            mpOutputWindow->EnableMapMode( FALSE );
            aStream << mpOutputWindow->GetBitmap(aEmptyPoint,
                                                mpOutputWindow->GetOutputSizePixel());
            mpOutputWindow->EnableMapMode( bOldMap );

            if( mpBackBuffer )
            {
                String aFilename2( String::CreateFromAscii("dbg_backbuffer") );
                aFilename2 += String::CreateFromInt32(nFilePostfixCount);
                aFilename2 += String::CreateFromAscii(".bmp");

                SvFileStream aStream2( aFilename2, STREAM_STD_READWRITE );

                mpBackBuffer->getOutDev().EnableMapMode( FALSE );
                aStream2 << mpBackBuffer->getOutDev().GetBitmap(aEmptyPoint,
                                                                mpBackBuffer->getOutDev().GetOutputSizePixel());
            }

            ++nFilePostfixCount;
        }
    }

}
<commit_msg>INTEGRATION: CWS changefileheader (1.5.80); FILE MERGED 2008/03/28 16:35:16 rt 1.5.80.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: devicehelper.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_canvas.hxx"

#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>
#include <canvas/base/linepolypolygonbase.hxx>

#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/canvastools.hxx>
#include <basegfx/tools/canvastools.hxx>

#include "devicehelper.hxx"
#include "spritecanvas.hxx"
#include "spritecanvashelper.hxx"
#include "canvasbitmap.hxx"

using namespace ::com::sun::star;

namespace vclcanvas
{
    DeviceHelper::DeviceHelper() :
        mpSpriteCanvas(NULL),
        mpBackBuffer()
    {
    }

    void DeviceHelper::init( Window&        rOutputWindow,
                             SpriteCanvas&  rSpriteCanvas )
    {
        rSpriteCanvas.setWindow(
            uno::Reference<awt::XWindow2>(
                VCLUnoHelper::GetInterface(&rOutputWindow),
                uno::UNO_QUERY_THROW) );

        mpOutputWindow = &rOutputWindow;
        mpSpriteCanvas = &rSpriteCanvas;

        // setup back buffer
        mpBackBuffer.reset( new BackBuffer( rOutputWindow ) );
        mpBackBuffer->setSize( rOutputWindow.GetOutputSizePixel() );
    }

    geometry::RealSize2D DeviceHelper::getPhysicalResolution()
    {
        if( !mpOutputWindow )
            return ::canvas::tools::createInfiniteSize2D(); // we're disposed

        // Map a one-by-one millimeter box to pixel
        const MapMode aOldMapMode( mpOutputWindow->GetMapMode() );
        mpOutputWindow->SetMapMode( MapMode(MAP_MM) );
        const Size aPixelSize( mpOutputWindow->LogicToPixel(Size(1,1)) );
        mpOutputWindow->SetMapMode( aOldMapMode );

        return ::vcl::unotools::size2DFromSize( aPixelSize );
    }

    geometry::RealSize2D DeviceHelper::getPhysicalSize()
    {
        if( !mpOutputWindow )
            return ::canvas::tools::createInfiniteSize2D(); // we're disposed

        // Map the pixel dimensions of the output window to millimeter
        const MapMode aOldMapMode( mpOutputWindow->GetMapMode() );
        mpOutputWindow->SetMapMode( MapMode(MAP_MM) );
        const Size aLogSize( mpOutputWindow->PixelToLogic(mpOutputWindow->GetOutputSizePixel()) );
        mpOutputWindow->SetMapMode( aOldMapMode );

        return ::vcl::unotools::size2DFromSize( aLogSize );
    }

    uno::Reference< rendering::XLinePolyPolygon2D > DeviceHelper::createCompatibleLinePolyPolygon(
        const uno::Reference< rendering::XGraphicDevice >&              ,
        const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >&  points )
    {
        if( !mpOutputWindow )
            return uno::Reference< rendering::XLinePolyPolygon2D >(); // we're disposed

        return uno::Reference< rendering::XLinePolyPolygon2D >(
            new ::canvas::LinePolyPolygonBase(
                ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence( points ) ) );
    }

    uno::Reference< rendering::XBezierPolyPolygon2D > DeviceHelper::createCompatibleBezierPolyPolygon(
        const uno::Reference< rendering::XGraphicDevice >&                      ,
        const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >&  points )
    {
        if( !mpOutputWindow )
            return uno::Reference< rendering::XBezierPolyPolygon2D >(); // we're disposed

        return uno::Reference< rendering::XBezierPolyPolygon2D >(
            new ::canvas::LinePolyPolygonBase(
                ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence( points ) ) );
    }

    uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleBitmap(
        const uno::Reference< rendering::XGraphicDevice >&  ,
        const geometry::IntegerSize2D&                      size )
    {
        if( !mpSpriteCanvas )
            return uno::Reference< rendering::XBitmap >(); // we're disposed

        return uno::Reference< rendering::XBitmap >(
            new CanvasBitmap( ::vcl::unotools::sizeFromIntegerSize2D(size),
                              false,
                              mpSpriteCanvas ) );
    }

    uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileBitmap(
        const uno::Reference< rendering::XGraphicDevice >&  ,
        const geometry::IntegerSize2D&                       )
    {
        return uno::Reference< rendering::XVolatileBitmap >();
    }

    uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleAlphaBitmap(
        const uno::Reference< rendering::XGraphicDevice >&  ,
        const geometry::IntegerSize2D&                      size )
    {
        if( !mpSpriteCanvas )
            return uno::Reference< rendering::XBitmap >(); // we're disposed

        return uno::Reference< rendering::XBitmap >( new CanvasBitmap( ::vcl::unotools::sizeFromIntegerSize2D(size),
                                                                       true,
                                                                       mpSpriteCanvas ) );
    }

    uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileAlphaBitmap(
        const uno::Reference< rendering::XGraphicDevice >&  ,
        const geometry::IntegerSize2D&                       )
    {
        return uno::Reference< rendering::XVolatileBitmap >();
    }

    sal_Bool DeviceHelper::hasFullScreenMode()
    {
        // TODO(F3): offer fullscreen mode the XCanvas way
        return false;
    }

    sal_Bool DeviceHelper::enterFullScreenMode( sal_Bool bEnter )
    {
        (void)bEnter;

        // TODO(F3): offer fullscreen mode the XCanvas way
        return false;
    }

    ::sal_Int32 DeviceHelper::createBuffers( ::sal_Int32 nBuffers )
    {
        (void)nBuffers;

        // TODO(F3): implement XBufferStrategy interface. For now, we
        // _always_ will have exactly one backbuffer
        return 1;
    }

    void DeviceHelper::destroyBuffers()
    {
        // TODO(F3): implement XBufferStrategy interface. For now, we
        // _always_ will have exactly one backbuffer
    }

    ::sal_Bool DeviceHelper::showBuffer( ::sal_Bool bUpdateAll )
    {
        // forward to sprite canvas helper
        if( !mpSpriteCanvas )
            return false;

        return mpSpriteCanvas->updateScreen( bUpdateAll );
    }

    ::sal_Bool DeviceHelper::switchBuffer( ::sal_Bool bUpdateAll )
    {
        // no difference for VCL canvas
        return showBuffer( bUpdateAll );
    }

    void DeviceHelper::disposing()
    {
        // release all references
        mpSpriteCanvas = NULL;
        mpBackBuffer.reset();
    }

    uno::Any DeviceHelper::getDeviceHandle() const
    {
        if( !mpOutputWindow )
            return uno::Any();

        return uno::makeAny(
            reinterpret_cast< sal_Int64 >(mpOutputWindow) );
    }

    uno::Any DeviceHelper::getSurfaceHandle() const
    {
        if( !mpBackBuffer )
            return uno::Any();

        return uno::makeAny(
            reinterpret_cast< sal_Int64 >(&mpBackBuffer->getOutDev()) );
    }

    void DeviceHelper::notifySizeUpdate( const awt::Rectangle& rBounds )
    {
        if( mpBackBuffer )
            mpBackBuffer->setSize( ::Size(rBounds.Width,
                                          rBounds.Height) );
    }

    void DeviceHelper::dumpScreenContent() const
    {
        static sal_uInt32 nFilePostfixCount(0);

        if( mpOutputWindow )
        {
            String aFilename( String::CreateFromAscii("dbg_frontbuffer") );
            aFilename += String::CreateFromInt32(nFilePostfixCount);
            aFilename += String::CreateFromAscii(".bmp");

            SvFileStream aStream( aFilename, STREAM_STD_READWRITE );

            const ::Point aEmptyPoint;
            bool bOldMap( mpOutputWindow->IsMapModeEnabled() );
            mpOutputWindow->EnableMapMode( FALSE );
            aStream << mpOutputWindow->GetBitmap(aEmptyPoint,
                                                mpOutputWindow->GetOutputSizePixel());
            mpOutputWindow->EnableMapMode( bOldMap );

            if( mpBackBuffer )
            {
                String aFilename2( String::CreateFromAscii("dbg_backbuffer") );
                aFilename2 += String::CreateFromInt32(nFilePostfixCount);
                aFilename2 += String::CreateFromAscii(".bmp");

                SvFileStream aStream2( aFilename2, STREAM_STD_READWRITE );

                mpBackBuffer->getOutDev().EnableMapMode( FALSE );
                aStream2 << mpBackBuffer->getOutDev().GetBitmap(aEmptyPoint,
                                                                mpBackBuffer->getOutDev().GetOutputSizePixel());
            }

            ++nFilePostfixCount;
        }
    }

}
<|endoftext|>


<commit_before>#include <cv_bridge/cv_bridge.h>
#include <igvc_msgs/map.h>
#include <pcl/point_cloud.h>
#include <pcl_ros/point_cloud.h>
#include <pcl_ros/transforms.h>
#include <ros/publisher.h>
#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <stdlib.h>
#include <math.h>
#include <Eigen/Core>
#include <opencv2/core/eigen.hpp>
#include <opencv2/opencv.hpp>
#include <nav_msgs/Odometry.h>
#include "tf/transform_datatypes.h"

igvc_msgs::map msgBoi;  // >> message to be sent
cv_bridge::CvImage img_bridge;
sensor_msgs::Image imageBoi;  // >> image in the message

ros::Publisher map_pub;
ros::Publisher debug_pub;
ros::Subscriber odom_sub;
ros::Publisher debug_pcl_pub;
cv::Mat *published_map;  // matrix will be publishing
std::map<std::string, tf::StampedTransform> transforms;
tf::TransformListener *tf_listener;
std::string topics;
Eigen::Map<Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic>> *eigenRep;

double resolution;
double orientation;
int start_x;  // start x location
int start_y;  // start y location
int length_y;
int width_x;
bool debug;
double cur_x;
double cur_y;

std::tuple<double, double> rotate(double x, double y) {
  double newX = x * cos(orientation) + y * -1 * sin(orientation);
  double newY = x * sin(orientation) + y * cos(orientation);
  return (std::make_tuple(newX, newY));
}

void odom_callback(const nav_msgs::Odometry::ConstPtr &msg) {
    cur_x = msg->pose.pose.position.x;
    cur_y = msg->pose.pose.position.y;
    tf::Quaternion quat;
    tf::quaternionMsgToTF(msg->pose.pose.orientation, quat);
    double roll, pitch, yaw;
    tf::Matrix3x3(quat).getRPY(roll, pitch, yaw);
    ROS_INFO_STREAM("orientation " << yaw);
    orientation = yaw;
}

void frame_callback(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &msg, const std::string &topic)
{
  // transform pointcloud into the occupancy grid, no filtering right now

  bool offMap = false;
  int count = 0;

  // make transformed clouds
  pcl::PointCloud<pcl::PointXYZ>::Ptr transformed =
      pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>());

  ros::Time time = ros::Time::now();
  if(transforms.find(topic) == transforms.end()) {
    if(tf_listener->waitForTransform("/base_footprint", msg->header.frame_id, ros::Time(0), ros::Duration(3.0))) {
      ROS_INFO_STREAM("\n\ngetting transform for " << topic << "\n\n");
      tf::StampedTransform transform;
      tf_listener->lookupTransform("/base_footprint", msg->header.frame_id, ros::Time(0), transform);
      transforms.insert(std::pair<std::string, tf::StampedTransform>(topic, transform));
    } else {
      ROS_ERROR_STREAM("\n\nfailed to find transform using empty transform\n\n");
      tf::StampedTransform transform;
      transform.setOrigin(tf::Vector3(0.0, 0.0, 0.0));
      tf::Quaternion q;
      q.setRPY(0, 0, 0);
      transform.setRotation(q);
      transform.child_frame_id_ = "/base_footprint";
      transform.frame_id_ = "/lidar";
      transform.stamp_ = ros::Time::now();
      transforms.insert(std::pair<std::string, tf::StampedTransform>(topic, transform));
    }
  }
  pcl_ros::transformPointCloud(*msg, *transformed, transforms.at(topic));

  pcl::PointCloud<pcl::PointXYZ>::const_iterator point;

  for (point = transformed->begin(); point < transformed->points.end(); point++)
  {
    //ROS_INFO_STREAM("points starts at " << point->x << "," << point->y);
    double x_loc, y_loc;
    std::tie(x_loc, y_loc) = rotate(point->x, point->y);
    //ROS_INFO_STREAM("rotated " << x_loc << "," << y_loc);
    int point_x = static_cast<int>(std::round(x_loc / resolution + cur_x / resolution + start_x));
    int point_y = static_cast<int>(std::round(y_loc / resolution + cur_y / resolution + start_y));
    //ROS_INFO_STREAM("point = " << point_x << "," << point_y);
    if (point_x >= 0 && point_y >= 0 && point_x < length_y && start_y < width_x)
    {
      //ROS_INFO_STREAM("putting point at " << point_x << "," << point_y);
      published_map->at<uchar>(point_x, point_y) = (uchar)255;
      count++;
    }
    else if (!offMap)
    {
      ROS_WARN_STREAM("Some points out of range, won't be put on map.");
      offMap = true;
    }
  }
  published_map->at<uchar>(start_x + cur_x / resolution, start_y + cur_y / resolution) = (uchar)100;
  // make image message from img bridge

  img_bridge = cv_bridge::CvImage(msgBoi.header, sensor_msgs::image_encodings::MONO8, *published_map);
  img_bridge.toImageMsg(imageBoi);    // from cv_bridge to sensor_msgs::Image
  time = ros::Time::now();  // so times are exact same
  imageBoi.header.stamp = time;
  // set fields of map message
  msgBoi.header.stamp = time;
  msgBoi.image = imageBoi;
  msgBoi.length = length_y;
  msgBoi.width = width_x;
  msgBoi.resolution = resolution;
  msgBoi.orientation = orientation;
  map_pub.publish(msgBoi);
  if (debug)
  {
    debug_pub.publish(imageBoi);
    ROS_INFO_STREAM("\nThe robot is located at " << cur_x << "," << cur_y << "," << orientation);
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr fromOcuGrid=
              pcl::PointCloud<pcl::PointXYZRGB>::Ptr(new pcl::PointCloud<pcl::PointXYZRGB>());
    for(int i = 0; i < width_x; i++){ // init frame so edges are easily visible
      for(int j = 0; j < length_y; j++){
        if(published_map->at<uchar>(i, j) == (uchar)255) {
          pcl::PointXYZRGB p(255, published_map->at<uchar>(i, j), published_map->at<uchar>(i, j));
          p.x = (i - start_x) * resolution;
          p.y = (j - start_y) * resolution;
          fromOcuGrid->points.push_back(p);
        }
      }
    }
    fromOcuGrid->header.frame_id = "/odom";
    fromOcuGrid->header.stamp = msg->header.stamp;
    debug_pcl_pub.publish(fromOcuGrid);
  }
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "new_mapper");
  ros::NodeHandle nh;
  ros::NodeHandle pNh("~");

  std::list<ros::Subscriber> subs;
  tf_listener = new tf::TransformListener();

  double cont_start_x;
  double cont_start_y;

  if(!pNh.hasParam("topics") && !pNh.hasParam("occupancy_grid_length") &&
     !pNh.hasParam("occupancy_grid_length") && !pNh.hasParam("occupancy_grid_resolution") &&
     !pNh.hasParam("start_X") & !pNh.hasParam("start_Y") &&
     !pNh.hasParam("debug")) {
    ROS_ERROR_STREAM("missing parameters exiting");
    return 0;
  }

  // assumes all params inputted in meters
  pNh.getParam("topics", topics);
  pNh.getParam("occupancy_grid_length", length_y);
  pNh.getParam("occupancy_grid_width", width_x);
  pNh.getParam("occupancy_grid_resolution", resolution);
  pNh.getParam("start_X", cont_start_x);
  pNh.getParam("start_Y", cont_start_y);
  pNh.getParam("orientation", orientation);
  pNh.getParam("debug", debug);

  // convert from meters to grid
  length_y = (int)std::round(length_y / resolution);
  width_x = (int)std::round(width_x / resolution);
  start_x = (int)std::round(cont_start_x / resolution);
  start_y = (int)std::round(cont_start_y / resolution);
  ROS_INFO_STREAM("cv::Mat length: " << length_y << "  width: " << width_x << "  resolution: " << resolution);

  // set up tokens and get list of subscribers
  std::istringstream iss(topics);
  std::vector<std::string> tokens{ std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>() };
  odom_sub = nh.subscribe("/odometry/filtered", 1, odom_callback);

  for (std::string topic : tokens)
  {
    ROS_INFO_STREAM("Mapper subscribing to " << topic);
    subs.push_back(nh.subscribe<pcl::PointCloud<pcl::PointXYZ>>(topic, 1, boost::bind(frame_callback, _1, topic)));
  }

  published_map = new cv::Mat(length_y, width_x, CV_8UC1);
  eigenRep = new Eigen::Map<Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic>>(
      (unsigned char *)published_map, width_x, length_y);

  map_pub = nh.advertise<igvc_msgs::map>("/map", 1);

  if (debug)
  {

    debug_pub = nh.advertise<sensor_msgs::Image>("/map_debug", 1);
    debug_pcl_pub = nh.advertise<pcl::PointCloud<pcl::PointXYZRGB>>("/map_debug_pcl", 1);
    /*for(int i = 0; i < width_x; i++){ // init frame so edges are easily visible
      for(int j = 0; j < length_y; j++){
        if(i == 0 || i == width_x - 1 || j == 0 || j == length_y - 1) {
          published_map->at<uchar>(i, j) = (uchar)255;
        }
      }
      }*/
  }

  ros::spin();
}
<commit_msg>fixed issues with mapper not publishing current location<commit_after>#include <cv_bridge/cv_bridge.h>
#include <igvc_msgs/map.h>
#include <pcl/point_cloud.h>
#include <pcl_ros/point_cloud.h>
#include <pcl_ros/transforms.h>
#include <ros/publisher.h>
#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <stdlib.h>
#include <math.h>
#include <Eigen/Core>
#include <opencv2/core/eigen.hpp>
#include <opencv2/opencv.hpp>
#include <nav_msgs/Odometry.h>
#include "tf/transform_datatypes.h"

igvc_msgs::map msgBoi;  // >> message to be sent
cv_bridge::CvImage img_bridge;
sensor_msgs::Image imageBoi;  // >> image in the message

ros::Publisher map_pub;
ros::Publisher debug_pub;
ros::Subscriber odom_sub;
ros::Publisher debug_pcl_pub;
cv::Mat *published_map;  // matrix will be publishing
std::map<std::string, tf::StampedTransform> transforms;
tf::TransformListener *tf_listener;
std::string topics;
Eigen::Map<Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic>> *eigenRep;

double resolution;
double orientation;
int start_x;  // start x location
int start_y;  // start y location
int length_y;
int width_x;
bool debug;
double cur_x;
double cur_y;
bool update = true;

std::tuple<double, double> rotate(double x, double y) {
  double newX = x * cos(orientation) + y * -1 * sin(orientation);
  double newY = x * sin(orientation) + y * cos(orientation);
  return (std::make_tuple(newX, newY));
}

void odom_callback(const nav_msgs::Odometry::ConstPtr &msg) {
  if(update) {
    cur_x = msg->pose.pose.position.x;
    cur_y = msg->pose.pose.position.y;
    tf::Quaternion quat;
    tf::quaternionMsgToTF(msg->pose.pose.orientation, quat);
    double roll, pitch, yaw;
    tf::Matrix3x3(quat).getRPY(roll, pitch, yaw);
    orientation = yaw;
    update = false;
  }
}

void frame_callback(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &msg, const std::string &topic)
{
  // transform pointcloud into the occupancy grid, no filtering right now

  bool offMap = false;
  int count = 0;

  // make transformed clouds
  pcl::PointCloud<pcl::PointXYZ>::Ptr transformed =
      pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>());

  ros::Time time = ros::Time::now();
  if(transforms.find(topic) == transforms.end()) {
    if(tf_listener->waitForTransform("/base_footprint", msg->header.frame_id, ros::Time(0), ros::Duration(3.0))) {
      ROS_INFO_STREAM("\n\ngetting transform for " << topic << "\n\n");
      tf::StampedTransform transform;
      tf_listener->lookupTransform("/base_footprint", msg->header.frame_id, ros::Time(0), transform);
      transforms.insert(std::pair<std::string, tf::StampedTransform>(topic, transform));
    } else {
      ROS_ERROR_STREAM("\n\nfailed to find transform using empty transform\n\n");
      tf::StampedTransform transform;
      transform.setOrigin(tf::Vector3(0.0, 0.0, 0.0));
      tf::Quaternion q;
      q.setRPY(0, 0, 0);
      transform.setRotation(q);
      transform.child_frame_id_ = "/base_footprint";
      transform.frame_id_ = "/lidar";
      transform.stamp_ = ros::Time::now();
      transforms.insert(std::pair<std::string, tf::StampedTransform>(topic, transform));
    }
  }
  pcl_ros::transformPointCloud(*msg, *transformed, transforms.at(topic));

  pcl::PointCloud<pcl::PointXYZ>::const_iterator point;

  for (point = transformed->begin(); point < transformed->points.end(); point++)
  {
    //ROS_INFO_STREAM("points starts at " << point->x << "," << point->y);
    double x_loc, y_loc;
    std::tie(x_loc, y_loc) = rotate(point->x, point->y);
    //ROS_INFO_STREAM("rotated " << x_loc << "," << y_loc);
    int point_x = static_cast<int>(std::round(x_loc / resolution + cur_x / resolution + start_x));
    int point_y = static_cast<int>(std::round(y_loc / resolution + cur_y / resolution + start_y));
    //ROS_INFO_STREAM("point = " << point_x << "," << point_y);
    if (point_x >= 0 && point_y >= 0 && point_x < length_y && start_y < width_x)
    {
      //ROS_INFO_STREAM("putting point at " << point_x << "," << point_y);
      published_map->at<uchar>(point_x, point_y) = (uchar)255;
      count++;
    }
    else if (!offMap)
    {
      ROS_WARN_STREAM("Some points out of range, won't be put on map.");
      offMap = true;
    }
  }
  published_map->at<uchar>(start_x + cur_x / resolution, start_y + cur_y / resolution) = (uchar)100;
  // make image message from img bridge

  img_bridge = cv_bridge::CvImage(msgBoi.header, sensor_msgs::image_encodings::MONO8, *published_map);
  img_bridge.toImageMsg(imageBoi);    // from cv_bridge to sensor_msgs::Image
  time = ros::Time::now();  // so times are exact same
  imageBoi.header.stamp = time;
  // set fields of map message
  msgBoi.header.stamp = time;
  msgBoi.image = imageBoi;
  msgBoi.length = length_y;
  msgBoi.width = width_x;
  msgBoi.resolution = resolution;
  msgBoi.orientation = orientation;
  ROS_INFO_STREAM("robot location " << cur_x / resolution << ", " << cur_y / resolution);
  msgBoi.x = std::round(cur_x / resolution);
  msgBoi.y = std::round(cur_y / resolution);
  map_pub.publish(msgBoi);
  if (debug)
  {
    debug_pub.publish(imageBoi);
    //ROS_INFO_STREAM("\nThe robot is located at " << cur_x << "," << cur_y << "," << orientation);
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr fromOcuGrid=
              pcl::PointCloud<pcl::PointXYZRGB>::Ptr(new pcl::PointCloud<pcl::PointXYZRGB>());
    for(int i = 0; i < width_x; i++){ // init frame so edges are easily visible
      for(int j = 0; j < length_y; j++){
        if(published_map->at<uchar>(i, j) == (uchar)255) {
          pcl::PointXYZRGB p(255, published_map->at<uchar>(i, j), published_map->at<uchar>(i, j));
          p.x = (i - start_x) * resolution;
          p.y = (j - start_y) * resolution;
          fromOcuGrid->points.push_back(p);
        }
      }
    }
    fromOcuGrid->header.frame_id = "/odom";
    fromOcuGrid->header.stamp = msg->header.stamp;
    debug_pcl_pub.publish(fromOcuGrid);
  }
  update = true;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "new_mapper");
  ros::NodeHandle nh;
  ros::NodeHandle pNh("~");

  std::list<ros::Subscriber> subs;
  tf_listener = new tf::TransformListener();

  double cont_start_x;
  double cont_start_y;

  if(!pNh.hasParam("topics") && !pNh.hasParam("occupancy_grid_length") &&
     !pNh.hasParam("occupancy_grid_length") && !pNh.hasParam("occupancy_grid_resolution") &&
     !pNh.hasParam("start_X") & !pNh.hasParam("start_Y") &&
     !pNh.hasParam("debug")) {
    ROS_ERROR_STREAM("missing parameters exiting");
    return 0;
  }

  // assumes all params inputted in meters
  pNh.getParam("topics", topics);
  pNh.getParam("occupancy_grid_length", length_y);
  pNh.getParam("occupancy_grid_width", width_x);
  pNh.getParam("occupancy_grid_resolution", resolution);
  pNh.getParam("start_X", cont_start_x);
  pNh.getParam("start_Y", cont_start_y);
  pNh.getParam("orientation", orientation);
  pNh.getParam("debug", debug);

  // convert from meters to grid
  length_y = (int)std::round(length_y / resolution);
  width_x = (int)std::round(width_x / resolution);
  start_x = (int)std::round(cont_start_x / resolution);
  start_y = (int)std::round(cont_start_y / resolution);
  ROS_INFO_STREAM("cv::Mat length: " << length_y << "  width: " << width_x << "  resolution: " << resolution);

  // set up tokens and get list of subscribers
  std::istringstream iss(topics);
  std::vector<std::string> tokens{ std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>() };
  odom_sub = nh.subscribe("/odometry/filtered", 1, odom_callback);

  for (std::string topic : tokens)
  {
    ROS_INFO_STREAM("Mapper subscribing to " << topic);
    subs.push_back(nh.subscribe<pcl::PointCloud<pcl::PointXYZ>>(topic, 1, boost::bind(frame_callback, _1, topic)));
  }

  published_map = new cv::Mat(length_y, width_x, CV_8UC1);
  eigenRep = new Eigen::Map<Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic>>(
      (unsigned char *)published_map, width_x, length_y);

  map_pub = nh.advertise<igvc_msgs::map>("/map", 1);

  if (debug)
  {

    debug_pub = nh.advertise<sensor_msgs::Image>("/map_debug", 1);
    debug_pcl_pub = nh.advertise<pcl::PointCloud<pcl::PointXYZRGB>>("/map_debug_pcl", 1);
    /*for(int i = 0; i < width_x; i++){ // init frame so edges are easily visible
      for(int j = 0; j < length_y; j++){
        if(i == 0 || i == width_x - 1 || j == 0 || j == length_y - 1) {
          published_map->at<uchar>(i, j) = (uchar)255;
        }
      }
      }*/
  }

  ros::spin();
}
<|endoftext|>


<commit_before>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2017 Igor Mironchik

	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:

	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef CFGFILE__TAG_SCALAR_VECTOR_HPP__INCLUDED
#define CFGFILE__TAG_SCALAR_VECTOR_HPP__INCLUDED

//cfgfile include.
#include "tag.hpp"
#include "constraint.hpp"
#include "format.hpp"
#include "string_format.hpp"
#include "types.hpp"
#include "exceptions.hpp"
#include "parser_info.hpp"

#if defined( CFGFILE_string_t_BUILD ) && defined( CFGFILE_XML_SUPPORT )
// Qt include.
#include <QDomDocument>
#include <QDomElement>
#include <QDomText>
#endif

// C++ include.
#include <vector>

namespace cfgfile {

//
// tag_scalar_vector_t
//

//! Tag with multiple scalar values.
template< class T >
class tag_scalar_vector_t
	:	public tag_t
{
public:
	typedef std::vector< T > values_vector_t;

	explicit tag_scalar_vector_t( const string_t & name,
		bool is_mandatory = false )
		:	tag_t( name, is_mandatory )
		,	m_constraint( nullptr )
	{
	}

	tag_scalar_vector_t( tag_t & owner, const string_t & name,
		bool is_mandatory = false )
		:	tag_t( owner, name, is_mandatory )
		,	m_constraint( nullptr )
	{
	}

	~tag_scalar_vector_t()
	{
	}

	//! \return Amount of the values.
	typename values_vector_t::size_type
	size() const
	{
		return m_values.size();
	}

	//! \return Value with the given index.
	const T &
	at( typename values_vector_t::size_type index ) const
	{
		return m_values.at( index );
	}

	//! \return All values.
	const values_vector_t &
	values() const
	{
		return m_values;
	}

	/*!
		Set value.

		Repeatly adds value to the end of vector.
	*/
	void
	set_value( const T & v )
	{
		if( m_constraint )
		{
			if( !m_constraint->check( v ) )
				throw exception_t< Trait >( string_t( Trait::from_ascii( "Invalid value: \"" ) ) +
					string_t( format_t< T >::to_string( v ) ) +
					Trait::from_ascii( "\". Value must match to the constraint in tag \"" ) +
					name() + Trait::from_ascii( "\"." ) );
		}

		m_values.push_back( v );

		set_defined();
	}

	//! Set values.
	void
	set_values( const values_vector_t & v )
	{
		m_values = v;

		set_defined();
	}

	/*!
		Query optional values.

		If isDefined() is true then \a receiver
		will be initialized with values of the tag,
		otherwise nothing with \a receiver will happen.
	*/
	void
	query_opt_values( values_vector_t & receiver )
	{
		if( is_defined() )
			receiver = m_values;
	}

	//! Set constraint for the tag's value.
	void
	set_constraint( constraint_t< T > * c )
	{
		m_constraint = c;
	}

	//! Print tag to the output.
	string_t print( int indent = 0 ) const override
	{
		string_t result;

		if( is_defined() )
		{
			result.append( string_t( indent, const_t< Trait >::c_tab ) );
			result.push_back( const_t< Trait >::c_begin_tag );
			result.append( name() );

			for( const T & v : m_values )
			{
				result.push_back( const_t< Trait >::c_space );

				string_t value = format_t< T >::to_string( v );

				value = to_cfgfile_format( value );

				result.append( value );
			}

			if( !children().empty() )
			{
				result.push_back( const_t< Trait >::c_carriage_return );

				for( const tag_t * tag : children() )
					result.append( tag->print( indent + 1 ) );

				result.append( string_t( indent, const_t< Trait >::c_tab ) );
			}

			result.push_back( const_t< Trait >::c_end_tag );
			result.push_back( const_t< Trait >::c_carriage_return );
		}

		return result;
	}

#if defined( CFGFILE_QT_SUPPORT ) && defined( CFGFILE_XML_SUPPORT )
	//! Print tag to the output.
	void print( QDomDocument & doc, QDomElement * parent = 0 ) const override
	{
		if( is_defined() )
		{
			QDomElement this_element = doc.createElement( name() );

			if( !parent )
				doc.appendChild( this_element );
			else
				parent->appendChild( this_element );

			typename values_vector_t::size_type i = 1;

			for( const T & v : m_values )
			{
				string_t value = format_t< T >::to_string( v );

				value = to_cfgfile_format( value );

				QString tmp = value;

				if( tmp.startsWith( const_t< Trait >::c_quotes ) && tmp.endsWith( const_t< Trait >::c_quotes ) )
					tmp = tmp.mid( 1, tmp.length() - 2 );

				this_element.setAttribute( QString( "a" ) + QString::number( i ),
					tmp );

				++i;
			}

			if( !children().empty() )
			{
				for( const tag_t * tag : children() )
					tag->print( doc, &this_element );
			}
		}
	}
#endif

	//! Called when tag parsing finished.
	void on_finish( const parser_info_t< Trait > & info ) override
	{
		for( const tag_t * tag : children() )
		{
			if( tag->is_mandatory() && !tag->is_defined() )
				throw exception_t< Trait >( string_t( Trait::from_ascii( "Undefined child mandatory tag: \"" ) ) +
					tag->name() + Trait::from_ascii( "\". Where parent is: \"" ) +
					name() + Trait::from_ascii( "\". In file \"" ) +
					info.file_name() + Trait::from_ascii( "\" on line " ) +
					Trait::to_string( info.line_number() ) + Trait::from_ascii( "." ) );
		}
	}

	//! Called when string found.
	void on_string( const parser_info_t< Trait > & info,
		const string_t & str ) override
	{
		if( is_any_child_defined() )
			throw exception_t< Trait >( string_t( Trait::from_ascii( "Value \"" ) ) + str +
				Trait::from_ascii( "\" for tag \"" ) + name() +
				Trait::from_ascii( "\" must be defined before any child tag. In file \"" ) +
				info.file_name() + Trait::from_ascii( "\" on line " ) +
				Trait::to_string( info.line_number() ) + Trait::from_ascii( "." ) );

		const T value = format_t< T >::from_string( info, str );

		if( m_constraint )
		{
			if( !m_constraint->check( value ) )
				throw exception_t< Trait >( string_t( Trait::from_ascii( "Invalid value: \"" ) ) +
					str + Trait::from_ascii( "\". Value must match to the constraint in tag \"" ) +
					name() + Trait::from_ascii( "\". In file \"" ) +
					info.file_name() + Trait::from_ascii( "\" on line " ) +
					Trait::to_string( info.line_number() ) + Trait::from_ascii( "." ) );
		}

		m_values.push_back( value );

		set_defined();
	}

private:
	//! Value of the tag.
	values_vector_t m_values;
	//! Constraint.
	constraint_t< T > * m_constraint;
}; // class tag_scalar_vector_t

} /* namespace cfgfile */

#endif // CFGFILE__TAG_SCALAR_VECTOR_HPP__INCLUDED
<commit_msg>Converted tag_scalar.hpp<commit_after>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2017 Igor Mironchik

	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:

	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef CFGFILE__TAG_SCALAR_VECTOR_HPP__INCLUDED
#define CFGFILE__TAG_SCALAR_VECTOR_HPP__INCLUDED

//cfgfile include.
#include "tag.hpp"
#include "constraint.hpp"
#include "format.hpp"
#include "string_format.hpp"
#include "types.hpp"
#include "exceptions.hpp"
#include "parser_info.hpp"

#if defined( CFGFILE_QT_SUPPORT ) && defined( CFGFILE_XML_SUPPORT )
// Qt include.
#include <QDomDocument>
#include <QDomElement>
#include <QDomText>
#endif

// C++ include.
#include <vector>

namespace cfgfile {

//
// tag_scalar_vector_t
//

//! Tag with multiple scalar values.
template< class T, class Trait >
class tag_scalar_vector_t
	:	public tag_t< Trait >
{
public:
	typedef std::vector< T > values_vector_t;

	explicit tag_scalar_vector_t( const Trait::string_t & name,
		bool is_mandatory = false )
		:	tag_t< Trait >( name, is_mandatory )
		,	m_constraint( nullptr )
	{
	}

	tag_scalar_vector_t( tag_t< Trait > & owner, const Trait::string_t & name,
		bool is_mandatory = false )
		:	tag_t< Trait >( owner, name, is_mandatory )
		,	m_constraint( nullptr )
	{
	}

	~tag_scalar_vector_t()
	{
	}

	//! \return Amount of the values.
	typename values_vector_t::size_type
	size() const
	{
		return m_values.size();
	}

	//! \return Value with the given index.
	const T &
	at( typename values_vector_t::size_type index ) const
	{
		return m_values.at( index );
	}

	//! \return All values.
	const values_vector_t &
	values() const
	{
		return m_values;
	}

	/*!
		Set value.

		Repeatly adds value to the end of vector.
	*/
	void
	set_value( const T & v )
	{
		if( m_constraint )
		{
			if( !m_constraint->check( v ) )
				throw exception_t< Trait >(
					Trait::from_ascii( "Invalid value: \"" ) +
					Trait::string_t( format_t< T >::to_string( v ) ) +
					Trait::from_ascii( "\". Value must match to the constraint in tag \"" ) +
					name() + Trait::from_ascii( "\"." ) );
		}

		m_values.push_back( v );

		set_defined();
	}

	//! Set values.
	void
	set_values( const values_vector_t & v )
	{
		m_values = v;

		set_defined();
	}

	/*!
		Query optional values.

		If isDefined() is true then \a receiver
		will be initialized with values of the tag,
		otherwise nothing with \a receiver will happen.
	*/
	void
	query_opt_values( values_vector_t & receiver )
	{
		if( is_defined() )
			receiver = m_values;
	}

	//! Set constraint for the tag's value.
	void
	set_constraint( constraint_t< T > * c )
	{
		m_constraint = c;
	}

	//! Print tag to the output.
	Trait::string_t print( int indent = 0 ) const override
	{
		Trait::string_t result;

		if( is_defined() )
		{
			result.append( Trait::string_t( indent, const_t< Trait >::c_tab ) );
			result.push_back( const_t< Trait >::c_begin_tag );
			result.append( name() );

			for( const T & v : m_values )
			{
				result.push_back( const_t< Trait >::c_space );

				Trait::string_t value = format_t< T >::to_string( v );

				value = to_cfgfile_format( value );

				result.append( value );
			}

			if( !children().empty() )
			{
				result.push_back( const_t< Trait >::c_carriage_return );

				for( const tag_t< Trait > * tag : children() )
					result.append( tag->print( indent + 1 ) );

				result.append( Trait::string_t( indent, const_t< Trait >::c_tab ) );
			}

			result.push_back( const_t< Trait >::c_end_tag );
			result.push_back( const_t< Trait >::c_carriage_return );
		}

		return result;
	}

#if defined( CFGFILE_QT_SUPPORT ) && defined( CFGFILE_XML_SUPPORT )
	//! Print tag to the output.
	void print( QDomDocument & doc, QDomElement * parent = 0 ) const override
	{
		if( is_defined() )
		{
			QDomElement this_element = doc.createElement( name() );

			if( !parent )
				doc.appendChild( this_element );
			else
				parent->appendChild( this_element );

			typename values_vector_t::size_type i = 1;

			for( const T & v : m_values )
			{
				Trait::string_t value = format_t< T >::to_string( v );

				value = to_cfgfile_format( value );

				QString tmp = value;

				if( tmp.startsWith( const_t< Trait >::c_quotes ) && tmp.endsWith( const_t< Trait >::c_quotes ) )
					tmp = tmp.mid( 1, tmp.length() - 2 );

				this_element.setAttribute( QString( "a" ) + QString::number( i ),
					tmp );

				++i;
			}

			if( !children().empty() )
			{
				for( const tag_t< Trait > * tag : children() )
					tag->print( doc, &this_element );
			}
		}
	}
#endif

	//! Called when tag parsing finished.
	void on_finish( const parser_info_t< Trait > & info ) override
	{
		for( const tag_t< Trait > * tag : children() )
		{
			if( tag->is_mandatory() && !tag->is_defined() )
				throw exception_t< Trait >(
					Trait::from_ascii( "Undefined child mandatory tag: \"" ) +
					tag->name() + Trait::from_ascii( "\". Where parent is: \"" ) +
					name() + Trait::from_ascii( "\". In file \"" ) +
					info.file_name() + Trait::from_ascii( "\" on line " ) +
					Trait::to_string( info.line_number() ) + Trait::from_ascii( "." ) );
		}
	}

	//! Called when string found.
	void on_string( const parser_info_t< Trait > & info,
		const Trait::string_t & str ) override
	{
		if( is_any_child_defined() )
			throw exception_t< Trait >(
				Trait::from_ascii( "Value \"" ) + str +
				Trait::from_ascii( "\" for tag \"" ) + name() +
				Trait::from_ascii( "\" must be defined before any child tag. In file \"" ) +
				info.file_name() + Trait::from_ascii( "\" on line " ) +
				Trait::to_string( info.line_number() ) + Trait::from_ascii( "." ) );

		const T value = format_t< T, Trait >::from_string( info, str );

		if( m_constraint )
		{
			if( !m_constraint->check( value ) )
				throw exception_t< Trait >(
					Trait::from_ascii( "Invalid value: \"" ) +
					str + Trait::from_ascii( "\". Value must match to the constraint in tag \"" ) +
					name() + Trait::from_ascii( "\". In file \"" ) +
					info.file_name() + Trait::from_ascii( "\" on line " ) +
					Trait::to_string( info.line_number() ) + Trait::from_ascii( "." ) );
		}

		m_values.push_back( value );

		set_defined();
	}

private:
	//! Value of the tag.
	values_vector_t m_values;
	//! Constraint.
	constraint_t< T > * m_constraint;
}; // class tag_scalar_vector_t

} /* namespace cfgfile */

#endif // CFGFILE__TAG_SCALAR_VECTOR_HPP__INCLUDED
<|endoftext|>


<commit_before>/* cperf_type_lookup_test.cpp                                 -*- C++ -*-
   Rémi Attab (remi.attab@gmail.com), 12 Apr 2014
   FreeBSD-style copyright and disclaimer apply

   Used to tests the complexity of type lookups within the compiler.

   In other words, if we have thousands of reflected types in our project,
   what's the overhead of looking up one of those types. gcc 4.7 seems to have a
   complexity of O(1) as was expected.
 */

#include "reflect.h"

#include <boost/test/unit_test.hpp>

using namespace reflect;

#define reflectThing1Impl(name)                 \
    struct name {};                             \
    reflectClassDecl(name)

#define reflectThing1()                         \
    reflectThing1Impl(reflectUniqueName(Thing))

#define reflectThing10()                        \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()

#define reflectThing100()                       \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()

#define reflectThing1000()                      \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()

reflectThing1000()

struct Target {};
reflectClass(Target) {}

int main(int, char**)
{
    (void) type<Target>();
    (void) type<Thing_100>();
}
<commit_msg>cperf: type lookup will run without crashing.<commit_after>/* cperf_type_lookup_test.cpp                                 -*- C++ -*-
   Rémi Attab (remi.attab@gmail.com), 12 Apr 2014
   FreeBSD-style copyright and disclaimer apply

   Used to tests the complexity of type lookups within the compiler.

   In other words, if we have thousands of reflected types in our project,
   what's the overhead of looking up one of those types. gcc 4.7 seems to have a
   complexity of O(1) as was expected.

*/

#include "reflect.h"

#include <boost/test/unit_test.hpp>

using namespace reflect;

/******************************************************************************/
/* REFLECT THING                                                              */
/******************************************************************************/

#define reflectThing1Impl(name)                 \
    struct name {};                             \
    reflectClassDecl(name)

#define reflectThing1()                         \
    reflectThing1Impl(reflectUniqueName(Thing))

#define reflectThing10()                        \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()                             \
    reflectThing1()

#define reflectThing100()                       \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()                            \
    reflectThing10()

#define reflectThing1000()                      \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()                           \
    reflectThing100()

/******************************************************************************/
/* MAIN                                                                       */
/******************************************************************************/

reflectThing1000()

struct Target {};
reflectClass(Target) {}

int main(int, char**)
{
    (void) type<Target>();
}
<|endoftext|>


<commit_before>//----------------------------  dof_renumbering.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2000, 2001 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  dof_renumbering.cc  ---------------------------

/* Author: Wolfgang Bangerth, University of Heidelberg, 2001 */

#include <base/logstream.h>
#include <base/function_lib.h>
#include <lac/vector.h>
#include <grid/tria.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>
#include <grid/grid_generator.h>
#include <dofs/dof_handler.h>
#include <fe/fe_q.h>
#include <fe/fe_dgq.h>
#include <fe/fe_system.h>
#include <numerics/dof_renumbering.h>

#include <fstream>

template <int dim>
void
print_dofs (const DoFHandler<dim> &dof)
{
  std::vector<unsigned int> v (dof.get_fe().dofs_per_cell);
  for (typename DoFHandler<dim>::active_cell_iterator cell=dof.begin_active();
       cell != dof.end(); ++cell)
    {
      deallog << "Cell " << cell << " -- ";
      cell->get_dof_indices (v);
      for (unsigned int i=0; i<v.size(); ++i)
	deallog << v[i] << ' ';
      deallog << std::endl;
    }
}

template <int dim>
void
check ()
{
  Functions::CosineFunction<dim> cosine;

  Triangulation<dim> tr;
  if (dim==2)
    GridGenerator::hyper_ball(tr, Point<dim>(), 1);
  else
    GridGenerator::hyper_cube(tr, -1,1);
  tr.refine_global (1);
  tr.begin_active()->set_refine_flag ();
  tr.execute_coarsening_and_refinement ();
  if (dim==1)
    tr.refine_global(2);

  FESystem<dim> element (FE_Q<dim>(2), 2, FE_DGQ<dim>(1), 1);
  DoFHandler<dim> dof(tr);
  dof.distribute_dofs(element);

  print_dofs (dof);

  DoFRenumbering::Cuthill_McKee (dof);              print_dofs (dof);
  DoFRenumbering::Cuthill_McKee (dof, true);        print_dofs (dof);
  DoFRenumbering::Cuthill_McKee (dof, true, true);  print_dofs (dof);

  std::vector<unsigned int> order(element.n_components());
  for (unsigned int i=0; i<order.size(); ++i) order[i] = order.size()-i-1;
  DoFRenumbering::component_wise (dof, order);      print_dofs (dof);

  std::vector<bool> selected_dofs (dof.n_dofs(), false);
  for (unsigned int i=0; i<dof.n_dofs(); ++i) if (i%2==0) selected_dofs[i] = true;
  DoFRenumbering::sort_selected_dofs_back (dof, selected_dofs);
  print_dofs (dof);
}

int main ()
{
  std::ofstream logfile ("dof_renumbering.output");
  logfile.precision (2);
  logfile.setf(std::ios::fixed);
  deallog.attach(logfile);
  deallog.depth_console (0);

  deallog.push ("1d");
  check<1> ();
  deallog.pop ();
  deallog.push ("2d");
  check<2> ();
  deallog.pop ();
  deallog.push ("3d");
  check<3> ();
  deallog.pop ();
}
<commit_msg>tests for multilevel numbering added<commit_after>//----------------------------  dof_renumbering.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2000, 2001 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  dof_renumbering.cc  ---------------------------

/* Author: Wolfgang Bangerth, University of Heidelberg, 2001 */

#include <base/logstream.h>
#include <base/function_lib.h>
#include <lac/vector.h>
#include <grid/tria.h>
#include <grid/tria_iterator.h>
#include <grid/grid_generator.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_handler.h>
#include <multigrid/mg_dof_accessor.h>
#include <multigrid/mg_dof_handler.h>
#include <fe/fe_q.h>
#include <fe/fe_dgq.h>
#include <fe/fe_system.h>
#include <numerics/dof_renumbering.h>

#include <fstream>

template <int dim>
void
print_dofs (const DoFHandler<dim> &dof)
{
  std::vector<unsigned int> v (dof.get_fe().dofs_per_cell);
  for (typename DoFHandler<dim>::active_cell_iterator cell=dof.begin_active();
       cell != dof.end(); ++cell)
    {
      deallog << "Cell " << cell << " -- ";
      cell->get_dof_indices (v);
      for (unsigned int i=0; i<v.size(); ++i)
	deallog << v[i] << ' ';
      deallog << std::endl;
    }
}

template <int dim>
void
print_dofs (const MGDoFHandler<dim> &dof, unsigned int level)
{
  std::vector<unsigned int> v (dof.get_fe().dofs_per_cell);
  for (typename MGDoFHandler<dim>::cell_iterator cell=dof.begin(level);
       cell != dof.end(level); ++cell)
    {
      deallog << "Cell " << cell << " -- ";
      cell->get_mg_dof_indices (v);
      for (unsigned int i=0; i<v.size(); ++i)
	deallog << v[i] << ' ';
      deallog << std::endl;
    }
}

template <int dim>
void
check ()
{
  Functions::CosineFunction<dim> cosine;

  Triangulation<dim> tr;
  if (dim==2)
    GridGenerator::hyper_ball(tr, Point<dim>(), 1);
  else
    GridGenerator::hyper_cube(tr, -1,1);
  tr.refine_global (1);
  tr.begin_active()->set_refine_flag ();
  tr.execute_coarsening_and_refinement ();
  if (dim==1)
    tr.refine_global(2);

  FESystem<dim> element (FE_Q<dim>(2), 2, FE_DGQ<dim>(1), 1);
  MGDoFHandler<dim> mgdof(tr);
  DoFHandler<dim>& dof = mgdof;
  dof.distribute_dofs(element);

				   // Prepare a reordering of
				   // components for later use
  std::vector<unsigned int> order(element.n_components());
  for (unsigned int i=0; i<order.size(); ++i) order[i] = order.size()-i-1;

				   // Check global ordering
  print_dofs (dof);

  DoFRenumbering::Cuthill_McKee (dof);
  print_dofs (dof);
  DoFRenumbering::Cuthill_McKee (dof, true);
  print_dofs (dof);
  DoFRenumbering::Cuthill_McKee (dof, true, true);
  print_dofs (dof);

  DoFRenumbering::component_wise (dof, order);
  print_dofs (dof);

  std::vector<bool> selected_dofs (dof.n_dofs(), false);
  for (unsigned int i=0; i<dof.n_dofs(); ++i) if (i%2==0) selected_dofs[i] = true;
  DoFRenumbering::sort_selected_dofs_back (dof, selected_dofs);
  print_dofs (dof);

				   // Check level ordering
  for (unsigned int level=0;level<tr.n_levels();++level)
    {
      print_dofs (mgdof, level);

// Reinsert after fixing
//        DoFRenumbering::Cuthill_McKee (mgdof, level);
//        print_dofs (mgdof, level);
//        DoFRenumbering::Cuthill_McKee (mgdof, level, true);
//        print_dofs (mgdof, level);

      DoFRenumbering::component_wise (mgdof, order);
      print_dofs (mgdof, level);
    }
}

int main ()
{
  std::ofstream logfile ("dof_renumbering.output");
  logfile.precision (2);
  logfile.setf(std::ios::fixed);
  deallog.attach(logfile);
  deallog.depth_console (0);

  deallog.push ("1d");
  check<1> ();
  deallog.pop ();
  deallog.push ("2d");
  check<2> ();
  deallog.pop ();
  deallog.push ("3d");
  check<3> ();
  deallog.pop ();
}
<|endoftext|>