summaryrefslogtreecommitdiff
path: root/editeng
diff options
context:
space:
mode:
authorJonathan Clark <jonathan@libreoffice.org>2024-09-23 15:26:45 -0600
committerJonathan Clark <jonathan@libreoffice.org>2024-09-25 01:25:07 +0200
commitfe4687ed174c54f2eb25f8088bf3fb6cb4858175 (patch)
treefe64da5a021f47d573da539d2df414ce6035e646 /editeng
parent2fc1034de4fd23d810593533b70ff674b0ccd706 (diff)
tdf#163105 Consolidated duplicated kashida justification code
The kashida candidate position selection logic was copied-and-pasted from Writer into Edit Engine. This change consolidates the shared code into a library. This change also adds some minimal characteristic tests, which previously did not exist. Change-Id: I2bfbfa79858347803474b754566436f3e74d1a54 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173883 Reviewed-by: Jonathan Clark <jonathan@libreoffice.org> Tested-by: Jenkins
Diffstat (limited to 'editeng')
-rw-r--r--editeng/source/editeng/impedit3.cxx239
1 files changed, 4 insertions, 235 deletions
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 6f7d1e7ac928..b961393bb24b 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -68,6 +68,7 @@
#include <com/sun/star/i18n/InputSequenceChecker.hpp>
#include <vcl/pdfextoutdevdata.hxx>
#include <i18nlangtag/mslangid.hxx>
+#include <i18nutil/kashida.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/lok.hxx>
@@ -232,93 +233,6 @@ static void lcl_DrawRedLines( OutputDevice& rOutDev,
}
}
-// For Kashidas from sw/source/core/text/porlay.cxx
-
-#define IS_JOINING_GROUP(c, g) ( u_getIntPropertyValue( (c), UCHAR_JOINING_GROUP ) == U_JG_##g )
-#define isAinChar(c) IS_JOINING_GROUP((c), AIN)
-#define isAlefChar(c) IS_JOINING_GROUP((c), ALEF)
-#define isDalChar(c) IS_JOINING_GROUP((c), DAL)
-#define isFehChar(c) (IS_JOINING_GROUP((c), FEH) || IS_JOINING_GROUP((c), AFRICAN_FEH))
-#define isGafChar(c) IS_JOINING_GROUP((c), GAF)
-#define isHehChar(c) IS_JOINING_GROUP((c), HEH)
-#define isKafChar(c) IS_JOINING_GROUP((c), KAF)
-#define isLamChar(c) IS_JOINING_GROUP((c), LAM)
-#define isQafChar(c) (IS_JOINING_GROUP((c), QAF) || IS_JOINING_GROUP((c), AFRICAN_QAF))
-#define isRehChar(c) IS_JOINING_GROUP((c), REH)
-#define isTahChar(c) IS_JOINING_GROUP((c), TAH)
-#define isTehMarbutaChar(c) IS_JOINING_GROUP((c), TEH_MARBUTA)
-#define isWawChar(c) IS_JOINING_GROUP((c), WAW)
-#define isSeenOrSadChar(c) (IS_JOINING_GROUP((c), SAD) || IS_JOINING_GROUP((c), SEEN))
-
-// Beh and characters that behave like Beh in medial form.
-static bool isBehChar(sal_Unicode cCh)
-{
- bool bRet = false;
- switch (u_getIntPropertyValue(cCh, UCHAR_JOINING_GROUP))
- {
- case U_JG_BEH:
- case U_JG_NOON:
- case U_JG_AFRICAN_NOON:
- case U_JG_NYA:
- case U_JG_YEH:
- case U_JG_FARSI_YEH:
- case U_JG_BURUSHASKI_YEH_BARREE:
- bRet = true;
- break;
- default:
- bRet = false;
- break;
- }
-
- return bRet;
-}
-
-// Yeh and characters that behave like Yeh in final form.
-static bool isYehChar(sal_Unicode cCh)
-{
- bool bRet = false;
- switch (u_getIntPropertyValue(cCh, UCHAR_JOINING_GROUP))
- {
- case U_JG_YEH:
- case U_JG_FARSI_YEH:
- case U_JG_YEH_BARREE:
- case U_JG_BURUSHASKI_YEH_BARREE:
- case U_JG_YEH_WITH_TAIL:
- bRet = true;
- break;
- default:
- bRet = false;
- break;
- }
-
- return bRet;
-}
-
-static bool isTransparentChar ( sal_Unicode cCh )
-{
- return u_getIntPropertyValue( cCh, UCHAR_JOINING_TYPE ) == U_JT_TRANSPARENT;
-}
-
-static bool lcl_IsLigature( sal_Unicode cCh, sal_Unicode cNextCh )
-{
- // Lam + Alef
- return ( isLamChar ( cCh ) && isAlefChar ( cNextCh ));
-}
-
-static bool lcl_ConnectToPrev( sal_Unicode cCh, sal_Unicode cPrevCh )
-{
- const int32_t nJoiningType = u_getIntPropertyValue( cPrevCh, UCHAR_JOINING_TYPE );
- bool bRet = nJoiningType != U_JT_RIGHT_JOINING && nJoiningType != U_JT_NON_JOINING;
-
- // check for ligatures cPrevChar + cChar
- if ( bRet )
- bRet = ! lcl_IsLigature( cPrevCh, cCh );
-
- return bRet;
-}
-
-
-
void ImpEditEngine::UpdateViews( EditView* pCurView )
{
if ( !IsUpdateLayout() || IsFormatting() || maInvalidRect.IsEmpty() )
@@ -2317,9 +2231,6 @@ void ImpEditEngine::ImpAdjustBlocks(ParaPortion& rParaPortion, EditLine& rLine,
{
EditPaM aPaM( pNode, nChar+1 );
sal_uInt16 nScript = GetI18NScriptType(aPaM);
- // Arabic script is handled above, but if no Kashida positions are found, use blanks.
- if (nKashidas)
- continue;
if ( pNode->GetChar(nChar) == ' ' )
{
@@ -2460,154 +2371,12 @@ void ImpEditEngine::ImpFindKashidas(ContentNode* pNode, sal_Int32 nStart, sal_In
// restore selection for proper iteration at the end of the function
aWordSel.Max().SetIndex( nSavPos );
- sal_Int32 nIdx = 0, nPrevIdx = 0;
- sal_Int32 nKashidaPos = -1;
- sal_Unicode cCh, cPrevCh = 0;
-
- int nPriorityLevel = 7; // 0..6 = level found
- // 7 not found
-
- sal_Int32 nWordLen = aWord.getLength();
+ auto stKashidaPos = i18nutil::GetWordKashidaPosition(aWord);
- // ignore trailing vowel chars
- while( nWordLen && isTransparentChar( aWord[ nWordLen - 1 ] ))
- --nWordLen;
-
- while ( nIdx < nWordLen )
+ if (stKashidaPos.has_value())
{
- cCh = aWord[ nIdx ];
-
- // 1. Priority:
- // after user inserted kashida
- if ( 0x640 == cCh )
- {
- nKashidaPos = aWordSel.Min().GetIndex() + nIdx;
- nPriorityLevel = 0;
- }
-
- // 2. Priority:
- // after a Seen or Sad
- if (nPriorityLevel >= 1 && nIdx < nWordLen - 1)
- {
- if( isSeenOrSadChar( cCh )
- && (aWord[ nIdx+1 ] != 0x200C) ) // #i98410#: prevent ZWNJ expansion
- {
- nKashidaPos = aWordSel.Min().GetIndex() + nIdx;
- nPriorityLevel = 1;
- }
- }
-
- // 3. Priority:
- // before final form of Teh Marbuta, Heh, Dal
- if ( nPriorityLevel >= 2 && nIdx > 0 )
- {
- if ( isTehMarbutaChar ( cCh ) || // Teh Marbuta (right joining)
- isDalChar ( cCh ) || // Dal (right joining) final form may appear in the middle of word
- ( isHehChar ( cCh ) && nIdx == nWordLen - 1)) // Heh (dual joining) only at end of word
- {
-
- SAL_WARN_IF( 0 == cPrevCh, "editeng", "No previous character" );
- // check if character is connectable to previous character,
- if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
- {
- nKashidaPos = aWordSel.Min().GetIndex() + nPrevIdx;
- nPriorityLevel = 2;
- }
- }
- }
-
- // 4. Priority:
- // before final form of Alef, Tah, Lam, Kaf or Gaf
- if ( nPriorityLevel >= 3 && nIdx > 0 )
- {
- if ( isAlefChar ( cCh ) || // Alef (right joining) final form may appear in the middle of word
- (( isLamChar ( cCh ) || // Lam,
- isTahChar ( cCh ) || // Tah,
- isKafChar ( cCh ) || // Kaf (all dual joining)
- isGafChar ( cCh ) )
- && nIdx == nWordLen - 1)) // only at end of word
- {
- SAL_WARN_IF( 0 == cPrevCh, "editeng", "No previous character" );
- // check if character is connectable to previous character,
- if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
- {
- nKashidaPos = aWordSel.Min().GetIndex() + nPrevIdx;
- nPriorityLevel = 3;
- }
- }
- }
-
- // 5. Priority:
- // before medial Beh-like
- if ( nPriorityLevel >= 4 && nIdx > 0 && nIdx < nWordLen - 1 )
- {
- if ( isBehChar ( cCh ) )
- {
- // check if next character is Reh or Yeh-like
- sal_Unicode cNextCh = aWord[ nIdx + 1 ];
- if ( isRehChar ( cNextCh ) || isYehChar ( cNextCh ))
- {
- SAL_WARN_IF( 0 == cPrevCh, "editeng", "No previous character" );
- // check if character is connectable to previous character,
- if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
- {
- nKashidaPos = aWordSel.Min().GetIndex() + nPrevIdx;
- nPriorityLevel = 4;
- }
- }
- }
- }
+ sal_Int32 nKashidaPos = aWordSel.Min().GetIndex() + stKashidaPos->nIndex;
- // 6. Priority:
- // before the final form of Waw, Ain, Qaf and Feh
- if ( nPriorityLevel >= 5 && nIdx > 0 )
- {
- if ( isWawChar ( cCh ) || // Wav (right joining)
- // final form may appear in the middle of word
- (( isAinChar ( cCh ) || // Ain (dual joining)
- isQafChar ( cCh ) || // Qaf (dual joining)
- isFehChar ( cCh ) ) // Feh (dual joining)
- && nIdx == nWordLen - 1)) // only at end of word
- {
- SAL_WARN_IF( 0 == cPrevCh, "editeng", "No previous character" );
- // check if character is connectable to previous character,
- if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
- {
- nKashidaPos = aWordSel.Min().GetIndex() + nPrevIdx;
- nPriorityLevel = 5;
- }
- }
- }
-
- // other connecting possibilities
- if ( nPriorityLevel >= 6 && nIdx > 0 )
- {
- // Reh, Zain
- if ( isRehChar ( cCh ) )
- {
- SAL_WARN_IF( 0 == cPrevCh, "editeng", "No previous character" );
- // check if character is connectable to previous character,
- if ( lcl_ConnectToPrev( cCh, cPrevCh ) )
- {
- nKashidaPos = aWordSel.Min().GetIndex() + nPrevIdx;
- nPriorityLevel = 6;
- }
- }
- }
-
- // Do not consider vowel marks when checking if a character
- // can be connected to previous character.
- if ( !isTransparentChar ( cCh) )
- {
- cPrevCh = cCh;
- nPrevIdx = nIdx;
- }
-
- ++nIdx;
- } // end of current word
-
- if (nKashidaPos >= 0)
- {
SeekCursor(pNode, nKashidaPos + 1, aTmpFont);
aTmpFont.SetPhysFont(*GetRefDevice());