summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorFrank Meies <fme@openoffice.org>2001-12-14 11:13:58 +0000
committerFrank Meies <fme@openoffice.org>2001-12-14 11:13:58 +0000
commit70c60c5fff49c43ad4921e183ab8b3be2b93a962 (patch)
tree35b70c990de0982866d107f0c50be8507bb68065 /sw/source
parent4ddb013b3b3eaf74369be74192fd937108eb3cb8 (diff)
Fix #95904#: Consider font changes during weak character classification
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/core/inc/drawfont.hxx7
-rw-r--r--sw/source/core/text/itratr.cxx75
-rw-r--r--sw/source/core/text/itratr.hxx32
-rw-r--r--sw/source/core/text/porlay.cxx46
-rw-r--r--sw/source/core/text/redlnitr.cxx6
-rw-r--r--sw/source/core/text/txtfrm.cxx67
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