diff options
author | Frank Meies <fme@openoffice.org> | 2001-12-14 11:13:58 +0000 |
---|---|---|
committer | Frank Meies <fme@openoffice.org> | 2001-12-14 11:13:58 +0000 |
commit | 70c60c5fff49c43ad4921e183ab8b3be2b93a962 (patch) | |
tree | 35b70c990de0982866d107f0c50be8507bb68065 /sw/source | |
parent | 4ddb013b3b3eaf74369be74192fd937108eb3cb8 (diff) |
Fix #95904#: Consider font changes during weak character classification
Diffstat (limited to 'sw/source')
-rw-r--r-- | sw/source/core/inc/drawfont.hxx | 7 | ||||
-rw-r--r-- | sw/source/core/text/itratr.cxx | 75 | ||||
-rw-r--r-- | sw/source/core/text/itratr.hxx | 32 | ||||
-rw-r--r-- | sw/source/core/text/porlay.cxx | 46 | ||||
-rw-r--r-- | sw/source/core/text/redlnitr.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/text/txtfrm.cxx | 67 |
6 files changed, 200 insertions, 33 deletions
diff --git a/sw/source/core/inc/drawfont.hxx b/sw/source/core/inc/drawfont.hxx index 8f42a5724a0f..35f5fd3e0f2e 100644 --- a/sw/source/core/inc/drawfont.hxx +++ b/sw/source/core/inc/drawfont.hxx @@ -2,9 +2,9 @@ * * $RCSfile: drawfont.hxx,v $ * - * $Revision: 1.11 $ + * $Revision: 1.12 $ * - * last change: $Author: fme $ $Date: 2001-12-12 12:44:27 $ + * last change: $Author: fme $ $Date: 2001-12-14 12:03:34 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -86,6 +86,7 @@ class Size; class SwFont; class ViewShell; class SwTxtNode; +class SwAttrHandler; #ifdef VERTICAL_LAYOUT class SwTxtFrm; @@ -113,7 +114,7 @@ public: inline SwScriptInfo() : nInvalidityPos( 0 ) {}; // determines script changes - void InitScriptInfo( const SwTxtNode& rNode, const SwFont& rFnt, + void InitScriptInfo( const SwTxtNode& rNode, SwAttrHandler& rAH, const OutputDevice& rOut ); // set/get position from which data is invalid diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index 0631871108e8..6cdba9a34f27 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -2,9 +2,9 @@ * * $RCSfile: itratr.cxx,v $ * - * $Revision: 1.20 $ + * $Revision: 1.21 $ * - * last change: $Author: ama $ $Date: 2001-11-30 13:52:05 $ + * last change: $Author: fme $ $Date: 2001-12-14 12:06:24 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -1121,3 +1121,74 @@ USHORT SwTxtNode::GetScalingOfSelectedText( xub_StrLen nStt, xub_StrLen nEnd ) ( nWidth ? ((100 * aIter.GetFnt()->_GetTxtSize( aDrawInf ).Height()) / nWidth ) : 0 ); } +SwFontIter::SwFontIter( const SwTxtNode& rNode, SwAttrHandler& rAH, + xub_StrLen nStt, xub_StrLen nEnd ) + : aFnt( *rAH.GetFont() ), rAttrHandler( rAH ), pHints( rNode.GetpSwpHints() ), + nStartIndex( 0 ), nEndIndex( 0 ), nCurrPos( nStt ), nEndPos( nEnd ) +{ + ASSERT( pHints, + "I think SwFontIter is too expensive if we do not have hints" ) +} + +SwFontIter::~SwFontIter() +{ + rAttrHandler.Reset(); +} + +xub_StrLen SwFontIter::NextFontChg() const +{ + xub_StrLen nNextPos = STRING_LEN; + + if (pHints->GetStartCount() > nStartIndex) // Gibt es noch Starts? + nNextPos = (*pHints->GetStart(nStartIndex)->GetStart()); + if (pHints->GetEndCount() > nEndIndex) // Gibt es noch Enden? + { + xub_StrLen nNextEnd = (*pHints->GetEnd(nEndIndex)->GetAnyEnd()); + if ( nNextEnd < nNextPos ) nNextPos = nNextEnd; // Wer ist naeher? + } + + return Min( nEndPos, nNextPos ); +} + +const SwFont& SwFontIter::GetCurrFont( xub_StrLen nNewPos ) +{ + ASSERT( nNewPos >= nCurrPos, "Do not use me (SwFontIter) like this" ) + + // change font for position nPos: + const SwTxtAttr *pTxtAttr; + + if ( nStartIndex ) + { + while ( ( nEndIndex < pHints->GetEndCount() ) && + (*(pTxtAttr = pHints->GetEnd(nEndIndex))->GetAnyEnd() <= nNewPos)) + { + // close attributes in front of old position + if ( *pTxtAttr->GetStart() <= nCurrPos ) + rAttrHandler.PopAndChg( *pTxtAttr, aFnt ); + + nEndIndex++; + } + } + else // skip non open attributes + { + while ( ( nEndIndex < pHints->GetEndCount() ) && + (*(pTxtAttr = pHints->GetEnd(nEndIndex))->GetAnyEnd() <= nNewPos)) + { + nEndIndex++; + } + } + + while ( ( nStartIndex < pHints->GetStartCount() ) && + (*(pTxtAttr = pHints->GetStart(nStartIndex))->GetStart() <= nNewPos)) + { + // open attributes behind new position + if ( *pTxtAttr->GetAnyEnd() > nNewPos ) + rAttrHandler.PushAndChg( *pTxtAttr, aFnt ); + + nStartIndex++; + } + + nCurrPos = nNewPos; + + return aFnt; +} diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx index 630ca7792e01..5035c0b7eec1 100644 --- a/sw/source/core/text/itratr.hxx +++ b/sw/source/core/text/itratr.hxx @@ -2,9 +2,9 @@ * * $RCSfile: itratr.hxx,v $ * - * $Revision: 1.12 $ + * $Revision: 1.13 $ * - * last change: $Author: fme $ $Date: 2001-11-19 12:13:07 $ + * last change: $Author: fme $ $Date: 2001-12-14 12:07:00 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -175,5 +175,33 @@ public: #endif }; +/************************************************************************* + * class SwFontIter + * + * A minimal attribute iterator class. In opposite to the other iterators + * it does not need an SwScriptInfo object. + *************************************************************************/ + +class SwFontIter +{ + SwFont aFnt; + SwAttrHandler& rAttrHandler; + const SwpHints* pHints; + xub_StrLen nStartIndex, nEndIndex, nCurrPos, nEndPos; + +public: + // Konstruktor, Destruktor + // be sure to pass a fully initialised AttrHandler + // (i.e., it has to have a valid pFnt member ) + SwFontIter( const SwTxtNode& rNode, SwAttrHandler& rAH, + xub_StrLen nStt, xub_StrLen nEnd ); + ~SwFontIter(); + + // returns the next position the font changes and changes the font + xub_StrLen NextFontChg() const; + + // return the current cont + const SwFont& GetCurrFont( xub_StrLen nNewPos ); +}; #endif diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index 68059db164a9..fce51ea7ba7f 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -2,9 +2,9 @@ * * $RCSfile: porlay.cxx,v $ * - * $Revision: 1.17 $ + * $Revision: 1.18 $ * - * last change: $Author: fme $ $Date: 2001-11-30 15:29:03 $ + * last change: $Author: fme $ $Date: 2001-12-14 12:10:57 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -509,7 +509,7 @@ BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, const SwScriptInfo* pSI ) * searches for script changes in rTxt and stores them *************************************************************************/ -void SwScriptInfo::InitScriptInfo( const SwTxtNode& rNode, const SwFont& rFnt, +void SwScriptInfo::InitScriptInfo( const SwTxtNode& rNode, SwAttrHandler& rAH, const OutputDevice& rOut ) { @@ -588,24 +588,41 @@ void SwScriptInfo::InitScriptInfo( const SwTxtNode& rNode, const SwFont& rFnt, if( nEnd > rTxt.Len() ) nEnd = rTxt.Len(); - ASSERT( GetScriptTypeOfLanguage( (USHORT)GetAppLanguage() ), - "Wrong default language" ); - - if ( WEAK == nScript ) +// if ( WEAK == nScript ) nScript = (BYTE)GetScriptTypeOfLanguage( (USHORT)GetAppLanguage() ); - // map scripts to font indices + ASSERT( LATIN == nScript || ASIAN == nScript || COMPLEX == nScript, + "Wrong default language" ); + + // map scripts to font indices, CTL font is always the last one const BYTE nScripts[3] = { - nScript - 1, nScript % 3, ( nScript + 1 ) % 3 }; + nScript - 1, + LATIN == nScript ? 1 : 0, + 2 }; xub_StrLen nOldChg = nChg; + const SwFont* pCurrFont = rAH.GetFont(); + + SwFontIter* pIter = 0; + + if ( rNode.GetpSwpHints() ) + { + // this is only necessary if there are font changes within the + // weak region + pIter = new SwFontIter( rNode, rAH, 0, nEnd ); + pCurrFont = &pIter->GetCurrFont( nChg ); + // the next end is the next font change + nEnd = pIter->NextFontChg(); + } + + ASSERT( pCurrFont, "I told you not to use an AttrHandler without a font" ) while ( nChg < nEnd ) { for ( BYTE i = 0; i < 3; ++i ) { nChg = rOut.HasGlyphs( - rFnt.GetFnt( nScripts[i] ), rTxt, nChg, nEnd - nChg ); + pCurrFont->GetFnt( nScripts[i] ), rTxt, nChg, nEnd - nChg ); if ( nChg > nOldChg ) { @@ -631,8 +648,17 @@ void SwScriptInfo::InitScriptInfo( const SwTxtNode& rNode, const SwFont& rFnt, if ( nChg == nEnd ) break; } + + if ( pIter ) + { + pCurrFont = &pIter->GetCurrFont( nChg ); + // advance to the next font change + nEnd = pIter->NextFontChg(); + } } + delete pIter; + // Get next script type or set to weak in order to exit nScript = ( nEnd < rTxt.Len() ) ? (BYTE)pBreakIt->xBreak->getScriptType( rTxt, nEnd ) : diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx index f85ce06e00fa..1bd83738d965 100644 --- a/sw/source/core/text/redlnitr.cxx +++ b/sw/source/core/text/redlnitr.cxx @@ -2,9 +2,9 @@ * * $RCSfile: redlnitr.cxx,v $ * - * $Revision: 1.23 $ + * $Revision: 1.24 $ * - * last change: $Author: fme $ $Date: 2001-11-20 10:49:48 $ + * last change: $Author: fme $ $Date: 2001-12-14 12:12:05 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -229,7 +229,7 @@ void SwAttrIter::CtorInit( SwTxtNode& rTxtNode, SwScriptInfo& rScrInf ) // determine script changes if not already done for current paragraph ASSERT( pScriptInfo, "No script info available"); if ( pScriptInfo->GetInvalidity() != STRING_LEN ) - pScriptInfo->InitScriptInfo( rTxtNode, *pFnt, *pOut ); + pScriptInfo->InitScriptInfo( rTxtNode, aAttrHandler, *pOut ); if ( pBreakIt->xBreak.is() ) { diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index e392c2f66b22..7d5403df1842 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -2,9 +2,9 @@ * * $RCSfile: txtfrm.cxx,v $ * - * $Revision: 1.22 $ + * $Revision: 1.23 $ * - * last change: $Author: fme $ $Date: 2001-12-06 10:59:24 $ + * last change: $Author: fme $ $Date: 2001-12-14 12:13:58 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -326,6 +326,25 @@ long SwTxtFrm::SwitchVerticalToHorizontal( long nLimit ) const SwitchVerticalToHorizontal( aTmp ); return aTmp.Y(); } + +SwFrmSwapper::SwFrmSwapper( const SwTxtFrm* pTxtFrm, sal_Bool bSwapIfNotSwapped ) + : pFrm( pTxtFrm ), bUndo( sal_False ) +{ + if ( pFrm->IsVertical() && + ( ( bSwapIfNotSwapped && ! pFrm->IsSwapped() ) || + ( ! bSwapIfNotSwapped && pFrm->IsSwapped() ) ) ) + { + bUndo = sal_True; + ((SwTxtFrm*)pFrm)->SwapWidthAndHeight(); + } +} + +SwFrmSwapper::~SwFrmSwapper() +{ + if ( bUndo ) + ((SwTxtFrm*)pFrm)->SwapWidthAndHeight(); +} + #endif /************************************************************************* @@ -685,8 +704,10 @@ void SwTxtFrm::CalcLineSpace() } #define SET_SCRIPT_INVAL( nPos )\ - if( GetPara() )\ - GetPara()->GetScriptInfo().SetInvalidity( nPos ); +{ \ + if( GetPara() ) \ + GetPara()->GetScriptInfo().SetInvalidity( nPos ); \ +} void lcl_ModifyOfst( SwTxtFrm* pFrm, xub_StrLen nPos, xub_StrLen nLen ) { @@ -825,9 +846,17 @@ void SwTxtFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) _InvalidateRange( SwCharRange( nPos, nLen) ); MSHORT nTmp = ((SwUpdateAttr*)pNew)->nWhichAttr; - if( !nTmp || RES_CHRATR_LANGUAGE == nTmp || - RES_TXTATR_CHARFMT == nTmp || RES_FMT_CHG == nTmp ) - SET_WRONG( nPos, nPos + nLen, Invalidate ); + + if( !nTmp || RES_TXTATR_CHARFMT == nTmp || RES_FMT_CHG == nTmp ) + { + SET_WRONG( nPos, nPos + nLen, Invalidate ) + SET_SCRIPT_INVAL( nPos ) + } + else if ( RES_CHRATR_LANGUAGE == nTmp ) + SET_WRONG( nPos, nPos + nLen, Invalidate ) + else if ( RES_CHRATR_FONT == nTmp || RES_CHRATR_CJK_FONT == nTmp || + RES_CHRATR_CTL_FONT == nTmp ) + SET_SCRIPT_INVAL( nPos ) } } break; @@ -1001,10 +1030,22 @@ void SwTxtFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) } } - if( SFX_ITEM_SET == rNewSet.GetItemState( RES_CHRATR_LANGUAGE, - sal_False ) || SFX_ITEM_SET == rNewSet.GetItemState( - RES_TXTATR_CHARFMT, sal_False ) ) - SET_WRONG( 0, STRING_LEN, Invalidate ); + if ( SFX_ITEM_SET == + rNewSet.GetItemState( RES_TXTATR_CHARFMT, sal_False ) ) + { + SET_WRONG( 0, STRING_LEN, Invalidate ) + SET_SCRIPT_INVAL( 0 ) + } + else if ( SFX_ITEM_SET == + rNewSet.GetItemState( RES_CHRATR_LANGUAGE, sal_False ) ) + SET_WRONG( 0, STRING_LEN, Invalidate ) + else if ( SFX_ITEM_SET == + rNewSet.GetItemState( RES_CHRATR_FONT, sal_False ) || + SFX_ITEM_SET == + rNewSet.GetItemState( RES_CHRATR_CJK_FONT, sal_False ) || + SFX_ITEM_SET == + rNewSet.GetItemState( RES_CHRATR_CTL_FONT, sal_False ) ) + SET_SCRIPT_INVAL( 0 ) if( nCount ) { @@ -1237,9 +1278,9 @@ void SwTxtFrm::Prepare( const PrepareHint ePrep, const void* pVoid, sal_Bool bNotify ) { #ifdef VERTICAL_LAYOUT - ASSERT( ! IsVertical() || ! IsSwapped(), - "SwTxtFrm::Prepare with swapped frame" ) + SwFrmSwapper aSwapper( this, sal_False ); #endif + #ifdef DEBUG const SwTwips nDbgY = Frm().Top(); #endif |