/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include using ::rtl::OUString; namespace com { namespace sun { namespace star { namespace i18n { InputSequenceChecker_th::InputSequenceChecker_th() { serviceName = "com.sun.star.i18n.InputSequenceChecker_th"; } InputSequenceChecker_th::~InputSequenceChecker_th() { } /* Table for Thai Cell Manipulation */ sal_Char _TAC_celltype_inputcheck[17][17] = { /* Cn */ /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F */ /* Cn-1 00 */{ 'X', 'A', 'A', 'A', 'A', 'A', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* 10 */{ 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* 20 */{ 'X', 'A', 'A', 'A', 'A', 'S', 'A', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C' }, /* 30 */{ 'X', 'S', 'A', 'S', 'S', 'S', 'S', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* 40 */{ 'X', 'A', 'A', 'A', 'A', 'S', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* 50 */{ 'X', 'A', 'A', 'A', 'A', 'S', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* 60 */{ 'X', 'A', 'A', 'A', 'S', 'A', 'S', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* 70 */{ 'X', 'A', 'A', 'A', 'A', 'S', 'A', 'R', 'R', 'R', 'C', 'C', 'R', 'R', 'R', 'R', 'R' }, /* 80 */{ 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'C', 'R', 'R', 'R', 'R', 'R', 'R' }, /* 90 */{ 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* A0 */{ 'X', 'A', 'A', 'A', 'A', 'A', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* B0 */{ 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* C0 */{ 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* D0 */{ 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' }, /* E0 */{ 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'C', 'C', 'R', 'R', 'R', 'R', 'R' }, /* F0 */{ 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'C', 'R', 'R', 'R', 'R', 'R', 'R' }, { 'X', 'A', 'A', 'A', 'S', 'S', 'A', 'R', 'R', 'R', 'C', 'R', 'C', 'R', 'R', 'R', 'R' } }; sal_Bool _TAC_Composible[3][5] = { /* 'A', 'C', 'S', 'R', 'X' */ /* Mode 0 */ {sal_True, sal_True, sal_True, sal_True, sal_True}, // PASSTHROUGH = 0 /* Mode 1 */ {sal_True, sal_True, sal_True, sal_False, sal_True}, // BASIC = 1 /* Mode 2 */ {sal_True, sal_True, sal_False, sal_False, sal_True} // STRICT = 2 }; static sal_Bool SAL_CALL check(sal_Unicode ch1, sal_Unicode ch2, sal_Int16 inputCheckMode) { sal_Int16 composible_class; switch (_TAC_celltype_inputcheck[getCharType(ch1)][getCharType(ch2)]) { case 'A': composible_class = 0; break; case 'C': composible_class = 1; break; case 'S': composible_class = 2; break; case 'R': composible_class = 3; break; case 'X': composible_class = 4; break; default: composible_class = 0; } return (_TAC_Composible[inputCheckMode][composible_class]); } sal_Bool SAL_CALL InputSequenceChecker_th::checkInputSequence(const OUString& Text, sal_Int32 nStartPos, sal_Unicode inputChar, sal_Int16 inputCheckMode) throw(com::sun::star::uno::RuntimeException) { return check(Text[nStartPos], inputChar, inputCheckMode); } sal_Int32 SAL_CALL InputSequenceChecker_th::correctInputSequence(OUString& Text, sal_Int32 nStartPos, sal_Unicode inputChar, sal_Int16 inputCheckMode) throw(com::sun::star::uno::RuntimeException) { /* 9 rules for input sequence correction, see issue i42661 for detail, http://www.openoffice.org/issues/show_bug.cgi?id=42661 = |||| = | = 0E4C (karan) 1. _x + _y => _y (replace) 2. _x + _y => _y (replace) 3. _x + _y => _y (replace) 4. _x + _y => _y (replace, reorder) 5. + => (reorder) 6. + => (reorder) 7. _x + _y => _y (replace, reorder) 8. + => (reorder) 9. _x + _y => _y (reorder, replace) */ #define CT_ABV(t) ( (t>=CT_AV1 && t<=CT_AV3) || t==CT_BV1 || t==CT_BV2) #define CT_ABV1(t) (t==CT_AV1 || t==CT_BV1) if (check(Text[nStartPos], inputChar, inputCheckMode)) Text = Text.replaceAt(++nStartPos, 0, OUString(inputChar)); else if (nStartPos > 0 && getCharType(Text[nStartPos-1]) == CT_CONS) { sal_uInt16 t1=getCharType(Text[nStartPos]), t2=getCharType(inputChar); if ( (CT_ABV(t1) && CT_ABV(t2)) || // 1. (t1==CT_TONE && t2==CT_TONE) )// 2. Text = Text.replaceAt(nStartPos, 1, OUString(inputChar)); else if ( (t1==CT_TONE && CT_ABV(t2)) || // 5. (t1==CT_FV1 && t2==CT_TONE) || // 6. (Text[nStartPos]==0x0E4C && CT_ABV1(t2)) ) // 8. Text = Text.replaceAt(nStartPos++, 0, OUString(inputChar)); else nStartPos=Text.getLength(); } else if (nStartPos > 1 && getCharType(Text[nStartPos-2]) == CT_CONS) { sal_uInt16 t1=getCharType(Text[nStartPos-1]), t2=getCharType(Text[nStartPos]), t3=getCharType(inputChar); if (CT_ABV(t1) && t2==CT_TONE && t3==CT_TONE) // 3. Text = Text.replaceAt(nStartPos, 1, OUString(inputChar)); else if ( (CT_ABV(t1) && t2==CT_TONE && CT_ABV(t3)) || // 4. (t1==CT_TONE && t2==CT_FV1 && t3==CT_TONE) || // 7. (CT_ABV1(t1) && Text[nStartPos]==0x0E4C && CT_ABV1(t3)) ) // 9. Text = Text.replaceAt(nStartPos-1, 1, OUString(inputChar)); else nStartPos=Text.getLength(); } else nStartPos=Text.getLength(); return nStartPos; } } } } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */