tdf#153684 spellcheck: ignore non-case character when !IsSpellUpperCase

This fixes a 7.5 regression from
commit ab0adac692
    Fix everything using XCharacterClassification::getStringType()...

Prior to erack's commit, all of the character-type-flags were grouped
together. So it could be a mix of UPPER, LOWER, and TITLE_CASE.
IsUpper returned true if there was at least one UPPER and no LOWER.
    return      (nFlags & KCharacterType::UPPER)
            && !(nFlags & KCharacterType::LOWER);

Since it was a group of flags, any characters that were non-case
(like a fullstop) did not affect the result of IsUpper.

But when it was changed in 7.5 to
    return aCC.isUpper( rText, nPos, nLen );
now every character needed to be considered to be upper-case,
even if it was a non-case character.

So this patch changes the logic back to the original state
(more or less).
The fly in the ointment are any Unicode characters
that would be considered to be TITLE_CASE.
Previously they were ignored (i.e. they didn't affect the outcome),
but now I consider them to be non-uppercase.
That seems to me to be the intent here anyway,
so probably this implementation "fixes a bug"
when a word consisted of a mixture of UPPER and TITLE_CASE chars.

See the first patchset where I added a dummy parameter
to ensure that this was still the only place
using erack's new function.
This proves it is safe to change the logic back,
since this is the only place IsUpper is called.

Change-Id: I7cf1d68bc3eb0a1a468da9e67ab54d1148f097aa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187934
Reviewed-by: Justin Luth <jluth@mail.com>
Tested-by: Jenkins
This commit is contained in:
Justin Luth
2025-07-16 00:51:27 +02:00
parent 11bdec0424
commit 53a9cee017
3 changed files with 18 additions and 30 deletions
-2
View File
@@ -176,8 +176,6 @@ public:
bool isNumeric( const OUString& rStr ) const;
bool isLetterNumeric( const OUString& rStr ) const;
bool isUpper( const OUString& rStr, sal_Int32 nPos, sal_Int32 nCount ) const;
private:
const css::lang::Locale & getMyLocale() const;
+18 -1
View File
@@ -556,8 +556,25 @@ rtl::Reference< HyphenatedWord > RebuildHyphensAndControlChars(
bool IsUpper( const OUString &rText, sal_Int32 nPos, sal_Int32 nLen, LanguageType nLanguage )
{
assert(nPos >= 0 && nLen > 0);
CharClass aCC(( LanguageTag( nLanguage ) ));
return aCC.isUpper( rText, nPos, nLen );
bool bCaseIsAlwaysUppercase = false;
const sal_Int32 nEnd = std::min(nPos + nLen, rText.getLength());
while (nPos < nEnd)
{
// only consider characters that have case-status
if (aCC.isAlpha(rText, nPos))
{
if (aCC.isUpper(rText, nPos))
bCaseIsAlwaysUppercase = true;
else
return false;
}
rText.iterateCodePoints(&nPos);
}
return bCaseIsAlwaysUppercase;
}
CapType capitalType(const OUString& aTerm, CharClass const * pCC)
-27
View File
@@ -288,33 +288,6 @@ bool CharClass::isUpper( const OUString& rStr, sal_Int32 nPos ) const
return false;
}
bool CharClass::isUpper( const OUString& rStr, sal_Int32 nPos, sal_Int32 nCount ) const
{
if (rStr.isEmpty())
return false;
assert(nPos >= 0 && nPos < rStr.getLength() && nCount > 0);
if (nPos < 0 || nPos >= rStr.getLength() || nCount == 0)
return false;
try
{
const sal_Int32 nLen = std::min( nPos + nCount, rStr.getLength());
while (nPos < nLen)
{
if (!isUpper( rStr, nPos))
return false;
rStr.iterateCodePoints( &nPos);
}
return true;
}
catch ( const Exception& )
{
TOOLS_WARN_EXCEPTION("unotools.i18n", "" );
}
return false;
}
OUString CharClass::titlecase(const OUString& rStr, sal_Int32 nPos, sal_Int32 nCount) const
{
try