blob: 78811c22ae48d74fc6bb02065f27f93c2e7d95c9 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#ifndef _PORMULTI_HXX
#define _PORMULTI_HXX
#include "porlay.hxx"
#include "porexp.hxx"
class SwTxtFormatInfo;
class SwFldPortion;
class SwTxtCursor;
class SwLineLayout;
class SwTxtPaintInfo;
class SwTxtAttr;
class SfxPoolItem;
class SwFont;
/*-----------------02.02.01 15:01-------------------
* SwMultiCreator is a small structur to create a multiportion.
* It contains the kind of multiportion and a textattribute
* or a poolitem.
* The GetMultiCreator-function fills this structur and
* the Ctor of the SwMultiPortion uses it.
* --------------------------------------------------*/
#define SW_MC_DOUBLE 0
#define SW_MC_RUBY 1
#define SW_MC_ROTATE 2
#define SW_MC_BIDI 3
struct SwMultiCreator
{
const SwTxtAttr* pAttr;
const SfxPoolItem* pItem;
sal_uInt8 nId;
sal_uInt8 nLevel;
};
/*-----------------25.10.00 16:19-------------------
* A two-line-portion (SwMultiPortion) could have surrounding brackets,
* in this case the structur SwBracket will be used.
* --------------------------------------------------*/
struct SwBracket
{
xub_StrLen nStart; // Start of text attribute determins the font
KSHORT nAscent; // Ascent of the brackets
KSHORT nHeight; // Height of them
KSHORT nPreWidth; // Width of the opening bracket
KSHORT nPostWidth; // Width of the closing bracket
sal_Unicode cPre; // Initial character, e.g. '('
sal_Unicode cPost; // Final character, e.g. ')'
sal_uInt8 nPreScript; // Script of the initial character
sal_uInt8 nPostScript; // Script of the final character
};
/*-----------------16.10.00 12:45-------------------
* The SwMultiPortion is line portion inside a line portion,
* it's a group of portions,
* e.g. a double line portion in a line
* or phonetics (ruby)
* or combined characters
* or a rotated portion.
* --------------------------------------------------*/
class SwMultiPortion : public SwLinePortion
{
SwLineLayout aRoot; // One or more lines
SwFldPortion *pFldRest; // Field rest from the previous line
sal_Bool bTab1 :1; // First line tabulator
sal_Bool bTab2 :1; // Second line includes tabulator
sal_Bool bDouble :1; // Double line
sal_Bool bRuby :1; // Phonetics
sal_Bool bBidi :1;
sal_Bool bTop :1; // Phonetic position
sal_Bool bFormatted :1; // Already formatted
sal_Bool bFollowFld :1; // Field follow inside
sal_uInt8 nDirection:2; // Direction (0/90/180/270 degrees)
sal_Bool bFlyInCntnt:1; // Fly as character inside
protected:
SwMultiPortion( xub_StrLen nEnd ) : pFldRest( 0 ), bTab1( sal_False ),
bTab2( sal_False ), bDouble( sal_False ), bRuby( sal_False ),
bBidi( sal_False ), bFormatted( sal_False ), bFollowFld( sal_False ),
nDirection( 0 ), bFlyInCntnt( sal_False )
{ SetWhichPor( POR_MULTI ); SetLen( nEnd ); }
inline void SetDouble() { bDouble = sal_True; }
inline void SetRuby() { bRuby = sal_True; }
inline void SetBidi() { bBidi = sal_True; }
inline void SetTop( sal_Bool bNew ) { bTop = bNew; }
inline void SetTab1( sal_Bool bNew ) { bTab1 = bNew; }
inline void SetTab2( sal_Bool bNew ) { bTab2 = bNew; }
inline void SetDirection( sal_uInt8 nNew ) { nDirection = nNew; }
inline sal_Bool GetTab1() const { return bTab1; }
inline sal_Bool GetTab2() const { return bTab2; }
public:
~SwMultiPortion();
const SwLineLayout& GetRoot() const { return aRoot; }
SwLineLayout& GetRoot() { return aRoot; }
SwFldPortion* GetFldRest() { return pFldRest; }
void SetFldRest( SwFldPortion* pNew ) { pFldRest = pNew; }
inline sal_Bool HasTabulator() const { return bTab1 || bTab2; }
inline sal_Bool IsFormatted() const { return bFormatted; }
inline void SetFormatted() { bFormatted = sal_True; }
inline sal_Bool IsFollowFld() const { return bFollowFld; }
inline void SetFollowFld() { bFollowFld = sal_True; }
inline sal_Bool HasFlyInCntnt() const { return bFlyInCntnt; }
inline void SetFlyInCntnt( sal_Bool bNew ) { bFlyInCntnt = bNew; }
inline sal_Bool IsDouble() const { return bDouble; }
inline sal_Bool IsRuby() const { return bRuby; }
inline sal_Bool IsBidi() const { return bBidi; }
inline sal_Bool OnTop() const { return bTop; }
void ActualizeTabulator();
virtual void Paint( const SwTxtPaintInfo &rInf ) const;
virtual long CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
virtual sal_Bool ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const;
// Summarize the internal lines to calculate the (external) size
void CalcSize( SwTxtFormatter& rLine, SwTxtFormatInfo &rInf );
inline sal_Bool HasBrackets() const;
inline sal_Bool HasRotation() const { return 0 != (1 & nDirection); }
inline sal_Bool IsRevers() const { return 0 != (2 & nDirection); }
inline sal_uInt8 GetDirection() const { return nDirection; }
inline sal_uInt16 GetFontRotation() const
{ return ( HasRotation() ? ( IsRevers() ? 2700 : 900 ) : 0 ); }
// Accessibility: pass information about this portion to the PortionHandler
virtual void HandlePortion( SwPortionHandler& rPH ) const;
OUTPUT_OPERATOR
};
class SwDoubleLinePortion : public SwMultiPortion
{
SwBracket* pBracket; // Surrounding brackets
SwTwips nLineDiff; // Difference of the width of the both lines
xub_StrLen nBlank1; // Number of blanks in the first line
xub_StrLen nBlank2; // Number of blanks in the second line
public:
SwDoubleLinePortion( SwDoubleLinePortion& rDouble, xub_StrLen nEnd );
SwDoubleLinePortion( const SwMultiCreator& rCreate, xub_StrLen nEnd );
~SwDoubleLinePortion();
inline SwBracket* GetBrackets() const { return pBracket; }
void SetBrackets( const SwDoubleLinePortion& rDouble );
void PaintBracket( SwTxtPaintInfo& rInf, long nSpaceAdd, sal_Bool bOpen ) const;
void FormatBrackets( SwTxtFormatInfo &rInf, SwTwips& nMaxWidth );
inline KSHORT PreWidth() const { return pBracket->nPreWidth; };
inline KSHORT PostWidth() const { return pBracket->nPostWidth; }
inline void ClearBrackets()
{ pBracket->nPreWidth = pBracket->nPostWidth=0; Width( 0 ); }
inline KSHORT BracketWidth(){ return PreWidth() + PostWidth(); }
void CalcBlanks( SwTxtFormatInfo &rInf );
static void ResetSpaceAdd( SwLineLayout* pCurr );
inline SwTwips GetLineDiff() const { return nLineDiff; }
inline xub_StrLen GetSpaceCnt() const
{ return ( nLineDiff < 0 ) ? nBlank2 : nBlank1; }
inline xub_StrLen GetSmallerSpaceCnt() const
{ return ( nLineDiff < 0 ) ? nBlank1 : nBlank2; }
inline xub_StrLen GetBlank1() const { return nBlank1; }
inline xub_StrLen GetBlank2() const { return nBlank2; }
virtual long CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
virtual sal_Bool ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const;
};
class SwRubyPortion : public SwMultiPortion
{
xub_StrLen nRubyOffset;
sal_uInt16 nAdjustment;
void _Adjust( SwTxtFormatInfo &rInf);
public:
SwRubyPortion( const SwRubyPortion& rRuby, xub_StrLen nEnd );
SwRubyPortion( const SwMultiCreator& rCreate, const SwFont& rFnt,
const IDocumentSettingAccess& rIDocumentSettingAccess,
xub_StrLen nEnd, xub_StrLen nOffs,
const sal_Bool* pForceRubyPos );
void CalcRubyOffset();
inline void Adjust( SwTxtFormatInfo &rInf )
{ if(nAdjustment && GetRoot().GetNext()) _Adjust(rInf); }
inline sal_uInt16 GetAdjustment() const { return nAdjustment; }
inline xub_StrLen GetRubyOffset() const { return nRubyOffset; }
};
class SwRotatedPortion : public SwMultiPortion
{
public:
SwRotatedPortion( xub_StrLen nEnd, sal_uInt8 nDir = 1 )
: SwMultiPortion( nEnd ) { SetDirection( nDir ); }
SwRotatedPortion( const SwMultiCreator& rCreate, xub_StrLen nEnd,
sal_Bool bRTL );
};
class SwBidiPortion : public SwMultiPortion
{
sal_uInt8 nLevel;
public:
SwBidiPortion( xub_StrLen nEnd, sal_uInt8 nLv );
inline sal_uInt8 GetLevel() const { return nLevel; }
// Get number of blanks for justified alignment
xub_StrLen GetSpaceCnt( const SwTxtSizeInfo &rInf ) const;
// Calculates extra spacing based on number of blanks
virtual long CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
// Manipulate the spacing array at pCurr
virtual sal_Bool ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const;
};
// For cursor travelling in multiportions
class SwTxtCursorSave
{
SwTxtCursor* pTxtCrsr;
SwLineLayout* pCurr;
SwTwips nWidth;
xub_StrLen nStart;
sal_uInt8 nOldProp;
sal_Bool bSpaceChg;
public:
SwTxtCursorSave( SwTxtCursor* pTxtCursor, SwMultiPortion* pMulti,
SwTwips nY, sal_uInt16& nX, xub_StrLen nCurrStart, long nSpaceAdd );
~SwTxtCursorSave();
};
/*************************************************************************
* inline - Implementations
*************************************************************************/
inline sal_Bool SwMultiPortion::HasBrackets() const
{
return sal::static_int_cast< sal_Bool >( IsDouble() ?
0 != ((SwDoubleLinePortion*)this)->GetBrackets() :
sal_False );
}
CLASSIO( SwMultiPortion )
#endif