uifw/AvKon/src/AknLineBreaker.cpp
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknLineBreaker.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,272 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Line breaker class customized to meet Series 60 specifications.
+*
+*/
+
+
+// INCLUDE FILES
+#include "AknLineBreaker.h"
+#include "aknenv.h"
+#include <linebreak.h>
+#include <featmgr.h>                //FeatureManager
+
+// CONSTANTS
+
+const TUint KOpFlag = 1 << MLineBreaker::EOpLineBreakClass;
+const TUint KClFlag = 1 << MLineBreaker::EClLineBreakClass;
+// const TUint KQuFlag = 1 << MLineBreaker::EQuLineBreakClass;
+// const TUint KGlFlag = 1 << MLineBreaker::EGlLineBreakClass;
+const TUint KNsFlag = 1 << MLineBreaker::ENsLineBreakClass;
+const TUint KExFlag = 1 << MLineBreaker::EExLineBreakClass;
+const TUint KSyFlag = 1 << MLineBreaker::ESyLineBreakClass;
+const TUint KIsFlag = 1 << MLineBreaker::EIsLineBreakClass;
+const TUint KPrFlag = 1 << MLineBreaker::EPrLineBreakClass;
+const TUint KPoFlag = 1 << MLineBreaker::EPoLineBreakClass;
+const TUint KNuFlag = 1 << MLineBreaker::ENuLineBreakClass;
+const TUint KAlFlag = 1 << MLineBreaker::EAlLineBreakClass;
+const TUint KIdFlag = 1 << MLineBreaker::EIdLineBreakClass;
+const TUint KInFlag = 1 << MLineBreaker::EInLineBreakClass;
+// const TUint KHyFlag = 1 << MLineBreaker::EHyLineBreakClass;
+// const TUint KBaFlag = 1 << MLineBreaker::EBaLineBreakClass;
+const TUint KBbFlag = 1 << MLineBreaker::EBbLineBreakClass;
+const TUint KB2Flag = 1 << MLineBreaker::EB2LineBreakClass;
+const TUint KZwFlag = 1 << MLineBreaker::EZwLineBreakClass;
+const TUint KCmFlag = 1 << MLineBreaker::ECmLineBreakClass;
+// const TUint KBkFlag = 1 << MLineBreaker::EBkLineBreakClass;
+// const TUint KCrFlag = 1 << MLineBreaker::ECrLineBreakClass;
+// const TUint KLfFlag = 1 << MLineBreaker::ELfLineBreakClass;
+// const TUint KSgFlag = 1 << MLineBreaker::ESgLineBreakClass;
+// const TUint KCbFlag = 1 << MLineBreaker::ECbLineBreakClass;
+// const TUint KSpFlag = 1 << MLineBreaker::ESpLineBreakClass;
+// const TUint KSaFlag = 1 << MLineBreaker::ESaLineBreakClass;
+const TUint KAiFlag = 1 << MLineBreaker::EAiLineBreakClass;
+// const TUint KXxFlag = 1 << MLineBreaker::EXxLineBreakClass;
+
+const TUint KAllBreaks = 0xFFFFFFFF;
+
+const TUint KUsualForbidden = KClFlag | KExFlag | KSyFlag | KIsFlag | KZwFlag;
+
+const TUint KUsualAllowed =
+    KOpFlag | KPrFlag | KPoFlag | KNuFlag | KAlFlag | KIdFlag | KInFlag |
+    KBbFlag | KB2Flag | KAiFlag;
+
+struct TLineBreakRule
+    {
+    // Classes that breaks are illegal before, even after spaces.
+    TUint iForbid;
+    // Classes that breaks are legal before, even without spaces.
+    TUint iAllow;
+    };
+
+// A table of break rules, indexed by the class of the character before the
+// possible break.
+static const TLineBreakRule
+    TheLineBreakRuleTable[MLineBreaker::ELineBreakClasses] =
+    {
+    { KAllBreaks - KCmFlag,0 },                                                     // Op
+    { KUsualForbidden | KNsFlag,KUsualAllowed - KPoFlag },                          // Cl
+    { KUsualForbidden | KOpFlag,0 },                                                // Qu
+    { KUsualForbidden, 0 },                                                         // Gl
+    { KUsualForbidden, KUsualAllowed },                                             // Ns
+    { KUsualForbidden, KUsualAllowed },                                             // Ex
+    { KUsualForbidden, KUsualAllowed - KNuFlag },                                   // Sy
+    { KUsualForbidden, KUsualAllowed - KNuFlag },                                   // Is
+    { KUsualForbidden, KPrFlag | KPoFlag | KInFlag | KBbFlag | KB2Flag },           // Pr
+    { KUsualForbidden, KUsualAllowed },                                             // Po
+    { KUsualForbidden, KOpFlag | KPrFlag | KIdFlag | KBbFlag | KB2Flag },           // Nu
+    { KUsualForbidden, KOpFlag | KPrFlag | KPoFlag | KIdFlag | KBbFlag | KB2Flag }, // Al
+    { KUsualForbidden, KUsualAllowed - KPoFlag - KInFlag },                         // Id
+    { KUsualForbidden, KUsualAllowed - KInFlag },                                   // In
+    { KUsualForbidden, KUsualAllowed },                                             // Hy
+    { KUsualForbidden, KUsualAllowed },                                             // Ba
+    { KUsualForbidden, 0 },                                                         // Bb
+    { KUsualForbidden | KB2Flag, KUsualAllowed },                                   // B2
+    { KZwFlag, KAllBreaks - KZwFlag - KCmFlag},                                     // Zw
+    { KUsualForbidden, KOpFlag | KPrFlag | KPoFlag | KIdFlag | KBbFlag | KB2Flag }, // Cm
+    { 0, 0, },                                                                      // Bk
+    { 0, 0, },                                                                      // Cr
+    { 0, 0, },                                                                      // Lf
+    { 0, 0, },                                                                      // Sg
+    { 0, 0, },                                                                      // Cb
+    { KAllBreaks, 0, },                                                             // Sp
+    { 0, 0, },                                                                      // Sa
+    // the next line is different from GDI's table!
+    { KUsualForbidden, KOpFlag | KPrFlag | KPoFlag | KIdFlag | KBbFlag | KB2Flag }, // Ai
+    { 0, 0, }                                                                       // Xx
+    };
+
+// These are from editing UI spec.
+// 0xFFxx values are corresponding full width forms used in Chinese translations
+
+_LIT( KWrappingBeforeOrAfterChars,
+      "#_@&/\\=\xFF03\xFF3F\xFF20\xFF06\xFF0F\xFF3C\xFF1D" );
+
+const TText KPrivateUseAreaStart = 0xE000;
+const TText KPrivateUseAreaEnd = 0xF900;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// TAknLineBreaker::LineBreakClass()
+// -----------------------------------------------------------------------------
+//
+TUint TAknLineBreaker::LineBreakClass(
+    TUint aCode, TUint& aRangeStart, TUint& aRangeEnd ) const
+    {
+    aRangeStart = aCode;
+    aRangeEnd = aCode + 1;
+
+    // Need to fix those areas of TheLineBreakRangeTable (see linebreak.cpp)
+    // here, where our special wrapping characters reside.
+
+    TUint lineclass;
+    if (IsSpecialVariantChar(aCode, aRangeStart, aRangeEnd, lineclass))
+        {
+        return lineclass;
+        }
+
+    if ( aCode == 0x003C || aCode == 0x003E || aCode == 0x005E )
+        {
+        return EAlLineBreakClass;
+        }
+
+    if ( aCode >= 0x0041 && aCode <= 0x005A )
+        {
+        aRangeStart = 0x0041;
+        aRangeEnd = 0x005B;
+        return EAlLineBreakClass;
+        }
+
+    if ( aCode >= 0x0060 && aCode <= 0x007A )
+        {
+        aRangeStart = 0x0060;
+        aRangeEnd = 0x007B;
+        return EAlLineBreakClass;
+        }
+
+    // Regions, where our full with form special wrapping characters reside,
+    // already return EIdLineBreakClass in TheLineBreakRangeTable, so no
+    // need to fix them.
+
+    if ( KWrappingBeforeOrAfterChars().Locate( aCode ) != KErrNotFound )
+        {
+        // this allows break before and after
+        return EIdLineBreakClass;
+        }
+    if ( aCode >= KPrivateUseAreaStart && aCode < KPrivateUseAreaEnd )
+        {
+        aRangeStart = KPrivateUseAreaStart;
+        aRangeEnd = KPrivateUseAreaEnd;
+        // this allows break before and after
+        return EIdLineBreakClass;
+        }
+    else
+        {
+        return MLineBreaker::LineBreakClass( aCode, aRangeStart, aRangeEnd );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// TAknLineBreaker::LineBreakPossible()
+// This function is identical with the base implementation in LineBreak.dll.
+// Only the used table TheLineBreakRuleTable is different.
+// -----------------------------------------------------------------------------
+//
+TBool TAknLineBreaker::LineBreakPossible(
+    TUint aPrevClass, TUint aNextClass, TBool aHaveSpaces ) const
+    {
+    if (aPrevClass >= ELineBreakClasses || aNextClass >= ELineBreakClasses)
+        return FALSE;
+    const TLineBreakRule& rule = TheLineBreakRuleTable[aPrevClass];
+    TUint flag = 1 << aNextClass;
+    if (rule.iForbid & flag)
+        return FALSE;
+    return aHaveSpaces || (rule.iAllow & flag);
+    }
+
+
+struct TLineBreakRangeForSpecialVariant
+    {
+    TUint iStart;
+    TUint iEnd;
+    TUint iClass;
+    };
+
+// -----------------------------------------------------------------------------
+// The following definitions are for Japane variant
+// -----------------------------------------------------------------------------
+//
+static const TLineBreakRangeForSpecialVariant TheLineBreakRangeTableForJapanese[] =
+    {
+    { 0x301c, 0x301d, MLineBreaker::EIdLineBreakClass },  //wave dash
+    { 0x30fc, 0x30fd, MLineBreaker::ENsLineBreakClass },  //katakana-hiragana prolonged sound mark
+    { 0x30fe, 0x30ff, MLineBreaker::ENsLineBreakClass },  //katakana voiced iteration mark
+    { 0xff66, 0xff67, MLineBreaker::EIdLineBreakClass },  //halfwidth katakana letter wo
+    { 0xff71, 0xff9e, MLineBreaker::EIdLineBreakClass },  //halfwidth katakana letter a - nn
+    };
+
+// -----------------------------------------------------------------------------
+// TAknLineBreaker::IsSpecialVariantChar()
+// Converts Unicode character into line breaking class for special variant.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool TAknLineBreaker::IsSpecialVariantChar(TUint aCode, TUint& aRangeStart,TUint& aRangeEnd, TUint& aClass)
+    {
+    TBool ret = EFalse;
+
+    // return if feature language is not Japanese
+    CAknEnv* env = CAknEnv::Static();
+    if (env)
+        {
+        if (!env->IsFeatureLanguage(KFeatureIdJapanese))
+            {
+            return ret;
+            }
+        }
+    else
+        {
+        return ret;
+        }
+
+    // Now search the table.
+    const TLineBreakRangeForSpecialVariant* base = TheLineBreakRangeTableForJapanese;
+    const TLineBreakRangeForSpecialVariant* end = base +
+                            (sizeof(TheLineBreakRangeTableForJapanese)
+                             / sizeof(TheLineBreakRangeTableForJapanese[0]));
+    while (base < end)
+        {
+        TInt n = end - base;
+        const TLineBreakRangeForSpecialVariant* r = &base[n / 2];
+        if (r->iStart > aCode)
+            {
+            end = r;
+            }
+        else if (r->iEnd <= aCode)
+            {
+            base = r + 1;
+            }
+        else
+            {
+            aRangeStart = r->iStart;
+            aRangeEnd = r->iEnd;
+            aClass = r->iClass;
+            ret = ETrue;
+            break;
+            }
+        }
+    return ret;
+    }
+
+//  End of File