include/unotools/charclass.hxx     |    2 --
 linguistic/source/misc.cxx         |   19 ++++++++++++++++++-
 unotools/source/i18n/charclass.cxx |   27 ---------------------------
 3 files changed, 18 insertions(+), 30 deletions(-)

New commits:
commit 952412154a4872d0f06a60c44506278924bb9c62
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Tue Jul 15 15:36:16 2025 -0400
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Thu Jul 17 13:26:15 2025 +0200

    tdf#153684 spellcheck: ignore non-case character when !IsSpellUpperCase
    
    This fixes a 7.5 regression from
    commit ab0adac692b67fe7b63dee665607400c6a7e6c01
        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.
    
    Change-Id: I7cf1d68bc3eb0a1a468da9e67ab54d1148f097aa
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187934
    Reviewed-by: Justin Luth <jl...@mail.com>
    Tested-by: Jenkins
    (cherry picked from commit 53a9cee01759ce54c4ee50468958531a360640f9)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187936
    Reviewed-by: Eike Rathke <er...@redhat.com>

diff --git a/include/unotools/charclass.hxx b/include/unotools/charclass.hxx
index bc91aca63631..561cdc09c22a 100644
--- a/include/unotools/charclass.hxx
+++ b/include/unotools/charclass.hxx
@@ -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;
diff --git a/linguistic/source/misc.cxx b/linguistic/source/misc.cxx
index 5b826d0ec758..1391d76ee91a 100644
--- a/linguistic/source/misc.cxx
+++ b/linguistic/source/misc.cxx
@@ -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)
diff --git a/unotools/source/i18n/charclass.cxx 
b/unotools/source/i18n/charclass.cxx
index 423f9530f2cb..da66b0fa59d2 100644
--- a/unotools/source/i18n/charclass.cxx
+++ b/unotools/source/i18n/charclass.cxx
@@ -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

Reply via email to