diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/AknLineBreaker.cpp --- /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 +#include //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