From e4bf309835782cfed2a82905053c151344e71a53 Mon Sep 17 00:00:00 2001 From: asac Date: Tue, 13 Mar 2007 20:10:08 +0100 Subject: [PATCH] bz7969-a-thai-patch * updated to latest on Mar 7 2006, received from Theppitak Karoonboonyanan --- Makefile.in | 4 + allmakefiles.sh | 2 + config/autoconf.mk.in | 3 + configure.in | 18 ++ intl/lwbrk/components/Makefile.in | 48 +++++ intl/lwbrk/components/libthai/Makefile.in | 74 +++++++ .../components/libthai/nsLibThaiLineBreaker.cpp | 221 ++++++++++++++++++++ .../components/libthai/nsLibThaiLineBreaker.h | 148 +++++++++++++ intl/lwbrk/components/libthai/nsLibThaiModule.cpp | 52 +++++ intl/lwbrk/idl/Makefile.in | 1 + intl/lwbrk/idl/nsIThaiLineBreaker.idl | 61 ++++++ intl/lwbrk/src/nsJISx4501LineBreaker.cpp | 68 +++++-- intl/lwbrk/src/nsJISx4501LineBreaker.h | 7 + 13 files changed, 694 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index eefd575..14a6763 100644 --- a/Makefile.in +++ b/Makefile.in @@ -289,6 +289,10 @@ endif endif endif +ifdef MOZ_ENABLE_LIBTHAI_COMPONENT +tier_50_dirs += intl/lwbrk/components/libthai +endif + ifdef MOZ_LEAKY tier_50_dirs += tools/leaky endif diff --git a/allmakefiles.sh b/allmakefiles.sh index 2813d83..2673dcf 100755 --- a/allmakefiles.sh +++ b/allmakefiles.sh @@ -225,6 +225,8 @@ intl/locale/src/os2/Makefile intl/locale/src/windows/Makefile intl/locale/tests/Makefile intl/lwbrk/Makefile +intl/lwbrk/components/Makefile +intl/lwbrk/components/libthai/Makefile intl/lwbrk/src/Makefile intl/lwbrk/public/Makefile intl/lwbrk/tests/Makefile diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in index 584353e..c749fd4 100644 --- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -116,6 +116,9 @@ MOZ_ENABLE_LIBXUL = @MOZ_ENABLE_LIBXUL@ ENABLE_TESTS = @ENABLE_TESTS@ IBMBIDI = @IBMBIDI@ SUNCTL = @SUNCTL@ +MOZ_ENABLE_LIBTHAI_COMPONENT = @MOZ_ENABLE_LIBTHAI_COMPONENT@ +MOZ_LIBTHAI_CFLAGS = @MOZ_LIBTHAI_CFLAGS@ +MOZ_LIBTHAI_LIBS = @MOZ_LIBTHAI_LIBS@ ACCESSIBILITY = @ACCESSIBILITY@ MOZ_VIEW_SOURCE = @MOZ_VIEW_SOURCE@ MOZ_XPINSTALL = @MOZ_XPINSTALL@ diff --git a/configure.in b/configure.in index c5cffcd..fbe6d96 100644 --- a/configure.in +++ b/configure.in @@ -4910,6 +4910,23 @@ MOZ_ARG_ENABLE_BOOL(ctl, SUNCTL= ) dnl ======================================================== +dnl mozlibthai word break component, +dnl built on libthai existence +dnl ======================================================== +MOZ_ENABLE_LIBTHAI_COMPONENT= +MOZ_ARG_DISABLE_BOOL(libthai, +[ --disable-libthai Disable Thai word break support with libthai], + MOZ_ENABLE_LIBTHAI_COMPONENT=, + MOZ_ENABLE_LIBTHAI_COMPONENT=1) +if test "$MOZ_ENABLE_LIBTHAI_COMPONENT"; then + PKG_CHECK_MODULES(MOZ_LIBTHAI, libthai,[ + MOZ_ENABLE_LIBTHAI_COMPONENT=1 + ],[ + MOZ_ENABLE_LIBTHAI_COMPONENT= + ]) +fi + +dnl ======================================================== dnl view source support on by default dnl ======================================================== MOZ_ARG_DISABLE_BOOL(view-source, @@ -7147,6 +7164,7 @@ AC_SUBST(MOZ_ENABLE_LIBXUL) AC_SUBST(ENABLE_TESTS) AC_SUBST(IBMBIDI) AC_SUBST(SUNCTL) +AC_SUBST(MOZ_ENABLE_LIBTHAI_COMPONENT) AC_SUBST(ACCESSIBILITY) AC_SUBST(MOZ_XPINSTALL) AC_SUBST(MOZ_VIEW_SOURCE) diff --git a/intl/lwbrk/components/Makefile.in b/intl/lwbrk/components/Makefile.in new file mode 100644 index 0000000..fe7ca87 --- /dev/null +++ b/intl/lwbrk/components/Makefile.in @@ -0,0 +1,48 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = libthai + +include $(topsrcdir)/config/rules.mk + diff --git a/intl/lwbrk/components/libthai/Makefile.in b/intl/lwbrk/components/libthai/Makefile.in new file mode 100644 index 0000000..ed39985 --- /dev/null +++ b/intl/lwbrk/components/libthai/Makefile.in @@ -0,0 +1,74 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the Mozilla GNOME integration code. +# +# The Initial Developer of the Original Code is +# IBM Corporation. +# Portions created by the Initial Developer are Copyright (C) 2004 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = mozlibthai +MOZILLA_INTERNAL_API = 1 + +ifeq ($(MOZ_ENABLE_LIBTHAI_COMPONENT), 1) + +LIBRARY_NAME = mozlibthai +FORCE_SHARED_LIB = 1 +IS_COMPONENT = 1 + +REQUIRES = \ + xpcom \ + unicharutil \ + lwbrk \ + $(NULL) + +CPPSRCS = \ + nsLibThaiLineBreaker.cpp \ + nsLibThaiModule.cpp \ + $(NULL) + +CXXFLAGS += $(MOZ_LIBTHAI_CFLAGS) +EXTRA_DSO_LDOPTS += \ + $(MOZ_COMPONENT_LIBS) \ + $(NSPR_LIBS) \ + $(MOZ_LIBTHAI_LIBS) \ + $(NULL) + +endif + +include $(topsrcdir)/config/rules.mk + diff --git a/intl/lwbrk/components/libthai/nsLibThaiLineBreaker.cpp b/intl/lwbrk/components/libthai/nsLibThaiLineBreaker.cpp new file mode 100644 index 0000000..8e70306 --- /dev/null +++ b/intl/lwbrk/components/libthai/nsLibThaiLineBreaker.cpp @@ -0,0 +1,221 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * - Theppitak Karoonboonyanan + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include + +#include "nsLibThaiLineBreaker.h" + + +//// class BreakEntry implementation //// + +void BreakEntry::Set (const PRUnichar* pText, PRUint32 textLen, + int* pvPos, int posLen) +{ + Clear(); + + mText = new PRUnichar [textLen+1]; + for (PRUnichar i = 0; i < textLen; i++) + mText[i] = pText[i]; + mText[textLen] = 0; + mTextLen = textLen; + + mPos = new int [posLen]; + for (int j = 0; j < posLen; j++) + mPos[j] = pvPos[j]; + mPosLen = posLen; +} + +//// class BreakCache implementation //// + +static PRUint16 StringHash (const PRUnichar* pText, PRUint32 textLen) +{ + PRUint16 h = 0; + for (PRUint32 i = 0; i < textLen; i++) { + h = (h >> 12) ^ (h << 4) ^ pText[i]; + } + return h; +} + +BreakEntry& BreakCache::LookUp (const PRUnichar* pText, PRUint32 textLen) +{ + return mvBucket [StringHash (pText, textLen) % N_BUCKETS]; +} + + +//// class nsLibThaiLineBreaker implementation //// + +static thchar_t* GetTISText (const PRUnichar* pText, PRUint32 textLen) +{ + thchar_t* pTISText = new thchar_t [textLen + 1]; + PRUint32 i; + for (i = 0; i < textLen; i++) + pTISText[i] = th_uni2tis (pText[i]); + pTISText[i] = '\0'; + + return pTISText; +} + +static void FreeTISText (thchar_t* pTISText) +{ + delete pTISText; +} + +static PRBool IsStrEqual (const PRUnichar* pText1, PRUint32 len1, + const PRUnichar* pText2, PRUint32 len2) +{ + if (len1 != len2) + return PR_FALSE; + + for (PRUint32 i = 0; i < len1; ++i) + if (pText1[i] != pText2[i]) + return PR_FALSE; + + return PR_TRUE; +} + +int nsLibThaiLineBreaker::GetBreaks ( + const PRUnichar* pText, PRUint32 textLen, int vPos[], int nPos) +{ + // Call the expensive th_brk() only if uncached + BreakEntry& breakEntry = mBreakCache.LookUp (pText, textLen); + if (!IsStrEqual (breakEntry.Text(), breakEntry.TextLength(), pText, textLen)) + { + thchar_t* pTISText = GetTISText (pText, textLen); + int* pBreaks = new int [nPos]; + int nBreaks = th_brk (pTISText, pBreaks, nPos); + FreeTISText (pTISText); + + breakEntry.Set (pText, textLen, pBreaks, nBreaks); + delete pBreaks; + } + + for (int i = 0; i < breakEntry.PosLength(); ++i) + vPos [i] = breakEntry.Pos (i); + return breakEntry.PosLength(); +} + +NS_IMPL_ISUPPORTS1 (nsLibThaiLineBreaker, nsIThaiLineBreaker) + + +NS_IMETHODIMP nsLibThaiLineBreaker::BreakInBetween( + const PRUnichar* aText1 , PRUint32 aTextLen1, + const PRUnichar* aText2 , PRUint32 aTextLen2, + PRBool* oCanBreak) +{ + if (!aText1 || !aText2 || (0 == aTextLen1) || (0 == aTextLen2)) + { + *oCanBreak = PR_FALSE; + return NS_OK; + } + + PRBool result = PR_FALSE; + + PRUnichar *pConcat = new PRUnichar [aTextLen1 + aTextLen2]; + for (PRUint32 i = 0; i < aTextLen1; i++) + pConcat[i] = aText1[i]; + for (PRUint32 i = 0; i < aTextLen2; i++) + pConcat[aTextLen1 + i] = aText2[i]; + + int* pBreaks = new int [aTextLen1 + aTextLen2 + 1]; + int nBreaks = GetBreaks (pConcat, aTextLen1 + aTextLen2, + pBreaks, int (aTextLen1 + aTextLen2 + 1)); + for (int i = 0; i < nBreaks; i++) { + if (PRUint32 (pBreaks[i]) == aTextLen1) { + result = PR_TRUE; + break; + } + } + delete pBreaks; + + delete pConcat; + + *oCanBreak = result; + return NS_OK; +} + + +NS_IMETHODIMP nsLibThaiLineBreaker::Next( + const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos, + PRUint32* oNext, PRBool* oNeedMoreText) +{ + NS_ASSERTION(aText, "aText shouldn't be null"); + NS_ASSERTION(aLen > aPos, "Illegal value (length > position)"); + + *oNeedMoreText = PR_TRUE; + *oNext = aLen; + + int* pBreaks = new int [aLen + 1]; + int nBreaks = GetBreaks (aText, aLen, pBreaks, int (aLen + 1)); + for (int i = 0; i < nBreaks; i++) { + if (PRUint32 (pBreaks[i]) > aPos) { + *oNext = pBreaks[i]; + *oNeedMoreText = PR_FALSE; + break; + } + } + delete pBreaks; + + return NS_OK; +} + + +NS_IMETHODIMP nsLibThaiLineBreaker::Prev( + const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos, + PRUint32* oPrev, PRBool* oNeedMoreText) +{ + NS_ASSERTION(aText, "aText shouldn't be null"); + NS_ASSERTION(aLen > aPos, "Illegal value (length > position)"); + + *oNeedMoreText = PR_TRUE; + *oPrev = 0; + + int* pBreaks = new int [aLen + 1]; + int nBreaks = GetBreaks (aText, aLen, pBreaks, int (aLen + 1)); + for (int i = nBreaks - 1; i >= 0; i--) { + if (PRUint32 (pBreaks[i]) < aPos) { + *oPrev = pBreaks[i]; + *oNeedMoreText = PR_FALSE; + break; + } + } + delete pBreaks; + + return NS_OK; +} + diff --git a/intl/lwbrk/components/libthai/nsLibThaiLineBreaker.h b/intl/lwbrk/components/libthai/nsLibThaiLineBreaker.h new file mode 100644 index 0000000..23d272f --- /dev/null +++ b/intl/lwbrk/components/libthai/nsLibThaiLineBreaker.h @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * - Theppitak Karoonboonyanan + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsLibThaiLineBreaker_h__ +#define nsLibThaiLineBreaker_h__ + +#include "nsIThaiLineBreaker.h" + +/* + * Break Positions Info Entry + */ +class BreakEntry { +public: + BreakEntry(); + ~BreakEntry(); + + void Set (const PRUnichar* pText, PRUint32 textLen, int* pvPos, int posLen); + + const PRUnichar* Text() const; + PRUint32 TextLength() const; + int Pos(int index) const; + int PosLength() const; + +private: + void Clear(); + +private: + PRUnichar* mText; + PRUint32 mTextLen; + int* mPos; + int mPosLen; +}; + +inline BreakEntry::BreakEntry() + : mText (nsnull), mTextLen (0), mPos (nsnull), mPosLen (0) +{ +} + +inline BreakEntry::~BreakEntry() +{ + Clear(); +} + +inline void BreakEntry::Clear() +{ + if (mText) + delete mText; + if (mPos) + delete mPos; +} + +inline const PRUnichar* BreakEntry::Text() const +{ + return mText; +} + +inline PRUint32 BreakEntry::TextLength() const +{ + return mTextLen; +} + +inline int BreakEntry::Pos (int index) const +{ + return (mPos && index < mPosLen) ? mPos[index] : -1; +} + +inline int BreakEntry::PosLength() const +{ + return mPosLen; +} + + +/* + * Break Positions Info Cache + */ +class BreakCache +{ +public: + BreakEntry& LookUp (const PRUnichar* pText, PRUint32 textLen); + +private: + enum { N_BUCKETS = 19 }; + BreakEntry mvBucket[N_BUCKETS]; +}; + + +/* + * Thai Line Breaker using LibThai + */ +class nsLibThaiLineBreaker : public nsIThaiLineBreaker +{ + NS_DECL_ISUPPORTS + +public: + NS_IMETHOD BreakInBetween (const PRUnichar* aText1 , PRUint32 aTextLen1, + const PRUnichar* aText2 , PRUint32 aTextLen2, + PRBool* oCanBreak); + + NS_IMETHOD Next (const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos, + PRUint32* oNext, PRBool* oNeedMoreText); + + NS_IMETHOD Prev (const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos, + PRUint32* oPrev, PRBool* oNeedMoreText); + +protected: + int GetBreaks (const PRUnichar* pText, PRUint32 textLen, + int vPos[], int nPos); + +private: + BreakCache mBreakCache; +}; + +#endif /* nsLibThaiLineBreaker_h__ */ diff --git a/intl/lwbrk/components/libthai/nsLibThaiModule.cpp b/intl/lwbrk/components/libthai/nsLibThaiModule.cpp new file mode 100644 index 0000000..ba5a27e --- /dev/null +++ b/intl/lwbrk/components/libthai/nsLibThaiModule.cpp @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla GNOME integration code. + * + * The Initial Developer of the Original Code is + * IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Theppitak Karoonboonyanan + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsLibThaiLineBreaker.h" +#include "nsIGenericFactory.h" + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsLibThaiLineBreaker) + +static const nsModuleComponentInfo components[] = { + { "LibThai Line Breaker", + NS_THAILINEBREAKER_CID, + NS_THAILINEBREAKER_CONTRACTID, + nsLibThaiLineBreakerConstructor } +}; + +NS_IMPL_NSGETMODULE(mozlibthai, components) + diff --git a/intl/lwbrk/idl/Makefile.in b/intl/lwbrk/idl/Makefile.in index 67ee68e..9bbb194 100644 --- a/intl/lwbrk/idl/Makefile.in +++ b/intl/lwbrk/idl/Makefile.in @@ -46,6 +46,7 @@ MODULE = lwbrk XPIDLSRCS = \ nsISemanticUnitScanner.idl \ + nsIThaiLineBreaker.idl \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/intl/lwbrk/idl/nsIThaiLineBreaker.idl b/intl/lwbrk/idl/nsIThaiLineBreaker.idl new file mode 100644 index 0000000..8826111 --- /dev/null +++ b/intl/lwbrk/idl/nsIThaiLineBreaker.idl @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Theppitak Karoonboonyanan + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +%{C++ +// {5E1CD5F3-C757-45A5-BDA2-60D530236473} +#define NS_THAILINEBREAKER_CID { 0x5e1cd5f3, 0xc757, 0x45a5, { 0xbd, 0xa2, 0x60, 0xd5, 0x30, 0x23, 0x64, 0x73}} +#define NS_THAILINEBREAKER_CONTRACTID "@mozilla.org/intl/thailinebreaker;1" +%} + +/** + * Provides Thai line breaker + */ +[scriptable, uuid(5e1cd5f3-c757-45a5-bda2-60d530236473)] +interface nsIThaiLineBreaker : nsISupports { + boolean breakInBetween (in wstring aText1, in unsigned long aTextLen1, + in wstring aText2, in unsigned long aTextLen2); + + void next (in wstring aText, in unsigned long aLen, in unsigned long aPos, + out unsigned long pos, out boolean needMoreText); + + void prev (in wstring aText, in unsigned long aLen, in unsigned long aPos, + out unsigned long pos, out boolean needMoreText); +}; + diff --git a/intl/lwbrk/src/nsJISx4501LineBreaker.cpp b/intl/lwbrk/src/nsJISx4501LineBreaker.cpp index 5d11bbb..c683244 100644 --- a/intl/lwbrk/src/nsJISx4501LineBreaker.cpp +++ b/intl/lwbrk/src/nsJISx4501LineBreaker.cpp @@ -49,6 +49,7 @@ #include "rulebrk.h" #include "nsUnicharUtils.h" +#include "nsIServiceManager.h" /* @@ -238,6 +239,12 @@ IS_CJK_CHAR(PRUnichar u) } static inline int +IS_THAI(PRUnichar u) +{ + return (0x0e01 <= (u) && (u) <= 0x0e5b); +} + +static inline int IS_SPACE(PRUnichar u) { return ((u) == 0x0020 || (u) == 0x0009 || (u) == 0x000a || (u) == 0x000d || (u)==0x200b); @@ -254,7 +261,7 @@ PRInt8 nsJISx4051LineBreaker::GetClass(PRUnichar u) { c = GETCLASSFROMTABLE(gLBClass00, l); } - else if(th_isthai(u)) + else if(IS_THAI(u)) { c = CLASS_THAI; } @@ -342,11 +349,17 @@ PRBool nsJISx4051LineBreaker::GetPair(PRInt8 c1, PRInt8 c2) return (0 == ((gPair[c1] >> c2 ) & 0x0001)); } +nsCOMPtr nsJISx4051LineBreaker::GetThaiLineBreaker() +{ + if (!mThaiLineBreaker) + mThaiLineBreaker = do_GetService (NS_THAILINEBREAKER_CONTRACTID); + return mThaiLineBreaker; +} nsJISx4051LineBreaker::nsJISx4051LineBreaker( const PRUnichar* aNoBegin, PRInt32 aNoBeginLen, const PRUnichar* aNoEnd, PRInt32 aNoEndLen -) +) : mThaiLineBreaker(nsnull) { } @@ -427,7 +440,7 @@ NS_IMETHODIMP nsJISx4051LineBreaker::BreakInBetween( { if (IS_SPACE(aText1[cur])) break; - if (IS_CJK_CHAR(aText1[cur])) + if (IS_CJK_CHAR(aText1[cur]) || IS_THAI(aText1[cur])) goto ROUTE_CJK_BETWEEN; } @@ -435,7 +448,7 @@ NS_IMETHODIMP nsJISx4051LineBreaker::BreakInBetween( { if (IS_SPACE(aText2[cur])) break; - if (IS_CJK_CHAR(aText2[cur])) + if (IS_CJK_CHAR(aText2[cur]) || IS_THAI(aText2[cur])) goto ROUTE_CJK_BETWEEN; } @@ -463,7 +476,12 @@ ROUTE_CJK_BETWEEN: /* Handle cases for THAI */ if((CLASS_THAI == c1) && (CLASS_THAI == c2)) { - *oCanBreak = (0 == TrbWordBreakPos(aText1, aTextLen1, aText2, aTextLen2)); + nsCOMPtr pThaiLineBreaker = GetThaiLineBreaker(); + if (pThaiLineBreaker) + return pThaiLineBreaker->BreakInBetween(aText1, aTextLen1, + aText2, aTextLen2, oCanBreak); + else + *oCanBreak = (0 == TrbWordBreakPos(aText1, aTextLen1, aText2, aTextLen2)); } else { @@ -493,6 +511,9 @@ NS_IMETHODIMP nsJISx4051LineBreaker::Next( *oNeedMoreText = PR_FALSE; return NS_OK; } + // [thep's version]: + // if (IS_CJK_CHAR(&aText[cur]) || IS_THAI(&aText[cur])) + // [with RISC unichar fix]: if (IS_CJK_CHAR(GetUnichar(&aText[cur])) || IS_THAI(GetUnichar(&aText[cur]))) goto ROUTE_CJK_NEXT; } @@ -514,9 +535,14 @@ ROUTE_CJK_NEXT: if(CLASS_THAI == c1) { - *oNext = PRUint32(TrbFollowing(aText, aLen, aPos)); - *oNeedMoreText = PR_FALSE; - return NS_OK; + nsCOMPtr pThaiLineBreaker = GetThaiLineBreaker(); + if (pThaiLineBreaker) { + return pThaiLineBreaker->Next(aText, aLen, aPos, oNext, oNeedMoreText); + } else { + *oNext = PRUint32(TrbFollowing(aText, aLen, aPos)); + *oNeedMoreText = PR_FALSE; + return NS_OK; + } } for(cur++; cur GetClass(aText[cur-1]); } - // To Do: - // - // Should handle CLASS_THAI here - // + + if(CLASS_THAI == c2) + { + nsCOMPtr pThaiLineBreaker = GetThaiLineBreaker(); + if (pThaiLineBreaker) { + return pThaiLineBreaker->Prev(aText, aLen, aPos, oPrev, oNeedMoreText); + } else { + // TODO: do some fallback analysis instead + for (aPos--; aPos > 0; aPos--) { + if (!IS_THAI(aText[aPos])) { + *oPrev = aPos; + *oNeedMoreText = PR_FALSE; + return NS_OK; + } + } + *oNeedMoreText = PR_TRUE; + return NS_OK; + } + } + for(cur--; cur > 0; cur--) { if(NEED_CONTEXTUAL_ANALYSIS(aText[cur-1])) diff --git a/intl/lwbrk/src/nsJISx4501LineBreaker.h b/intl/lwbrk/src/nsJISx4501LineBreaker.h index cc1a7e1..280a051 100644 --- a/intl/lwbrk/src/nsJISx4501LineBreaker.h +++ b/intl/lwbrk/src/nsJISx4501LineBreaker.h @@ -40,6 +40,9 @@ #include "nsILineBreaker.h" +#include "nsCOMPtr.h" +#include "nsIThaiLineBreaker.h" + class nsJISx4051LineBreaker : public nsILineBreaker { NS_DECL_ISUPPORTS @@ -66,6 +69,10 @@ protected: PRInt8 ContextualAnalysis(PRUnichar prev, PRUnichar cur, PRUnichar next ); PRBool GetPair(PRInt8 c1, PRInt8 c2); + nsCOMPtr GetThaiLineBreaker(); + +protected: + nsCOMPtr mThaiLineBreaker; }; #endif /* nsJISx4501LineBreaker_h__ */ -- 1.4.4.4