intl/lwbrk/src/nsSampleWordBreaker.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "nsSampleWordBreaker.h"
     9 nsSampleWordBreaker::nsSampleWordBreaker()
    10 {
    11 }
    12 nsSampleWordBreaker::~nsSampleWordBreaker()
    13 {
    14 }
    16 NS_IMPL_ISUPPORTS(nsSampleWordBreaker, nsIWordBreaker)
    18 bool nsSampleWordBreaker::BreakInBetween(
    19   const char16_t* aText1 , uint32_t aTextLen1,
    20   const char16_t* aText2 , uint32_t aTextLen2)
    21 {
    22   NS_PRECONDITION( nullptr != aText1, "null ptr");
    23   NS_PRECONDITION( nullptr != aText2, "null ptr");
    25   if(!aText1 || !aText2 || (0 == aTextLen1) || (0 == aTextLen2))
    26     return false;
    28   return (this->GetClass(aText1[aTextLen1-1]) != this->GetClass(aText2[0]));
    29 }
    32 #define IS_ASCII(c)            (0 == ( 0xFF80 & (c)))
    33 #define ASCII_IS_ALPHA(c)         ((( 'a' <= (c)) && ((c) <= 'z')) || (( 'A' <= (c)) && ((c) <= 'Z')))
    34 #define ASCII_IS_DIGIT(c)         (( '0' <= (c)) && ((c) <= '9'))
    35 #define ASCII_IS_SPACE(c)         (( ' ' == (c)) || ( '\t' == (c)) || ( '\r' == (c)) || ( '\n' == (c)))
    36 #define IS_ALPHABETICAL_SCRIPT(c) ((c) < 0x2E80) 
    38 // we change the beginning of IS_HAN from 0x4e00 to 0x3400 to relfect Unicode 3.0 
    39 #define IS_HAN(c)              (( 0x3400 <= (c)) && ((c) <= 0x9fff))||(( 0xf900 <= (c)) && ((c) <= 0xfaff))
    40 #define IS_KATAKANA(c)         (( 0x30A0 <= (c)) && ((c) <= 0x30FF))
    41 #define IS_HIRAGANA(c)         (( 0x3040 <= (c)) && ((c) <= 0x309F))
    42 #define IS_HALFWIDTHKATAKANA(c)         (( 0xFF60 <= (c)) && ((c) <= 0xFF9F))
    43 #define IS_THAI(c)         (0x0E00 == (0xFF80 & (c) )) // Look at the higest 9 bits
    45 uint8_t nsSampleWordBreaker::GetClass(char16_t c)
    46 {
    47   // begin of the hack
    49   if (IS_ALPHABETICAL_SCRIPT(c))  {
    50 	  if(IS_ASCII(c))  {
    51 		  if(ASCII_IS_SPACE(c)) {
    52 			  return kWbClassSpace;
    53 		  } else if(ASCII_IS_ALPHA(c) || ASCII_IS_DIGIT(c)) {
    54 			  return kWbClassAlphaLetter;
    55 		  } else {
    56 			  return kWbClassPunct;
    57 		  }
    58 	  } else if(IS_THAI(c))	{
    59 		  return kWbClassThaiLetter;
    60 	  } else if (c == 0x00A0/*NBSP*/) {
    61       return kWbClassSpace;
    62     } else {
    63 		  return kWbClassAlphaLetter;
    64 	  }
    65   }  else {
    66 	  if(IS_HAN(c)) {
    67 		  return kWbClassHanLetter;
    68 	  } else if(IS_KATAKANA(c))   {
    69 		  return kWbClassKatakanaLetter;
    70 	  } else if(IS_HIRAGANA(c))   {
    71 		  return kWbClassHiraganaLetter;
    72 	  } else if(IS_HALFWIDTHKATAKANA(c))  {
    73 		  return kWbClassHWKatakanaLetter;
    74 	  } else  {
    75 		  return kWbClassAlphaLetter;
    76 	  }
    77   }
    78   return 0;
    79 }
    81 nsWordRange nsSampleWordBreaker::FindWord(
    82   const char16_t* aText , uint32_t aTextLen,
    83   uint32_t aOffset)
    84 {
    85   nsWordRange range;
    86   NS_PRECONDITION( nullptr != aText, "null ptr");
    87   NS_PRECONDITION( 0 != aTextLen, "len = 0");
    88   NS_PRECONDITION( aOffset <= aTextLen, "aOffset > aTextLen");
    90   range.mBegin = aTextLen + 1;
    91   range.mEnd = aTextLen + 1;
    93   if(!aText || aOffset > aTextLen)
    94     return range;
    96   uint8_t c = this->GetClass(aText[aOffset]);
    97   uint32_t i;
    98   // Scan forward
    99   range.mEnd--;
   100   for(i = aOffset +1;i <= aTextLen; i++)
   101   {
   102      if( c != this->GetClass(aText[i]))
   103      {
   104        range.mEnd = i;
   105        break;
   106      }
   107   }
   109   // Scan backward
   110   range.mBegin = 0;
   111   for(i = aOffset ;i > 0; i--)
   112   {
   113      if( c != this->GetClass(aText[i-1]))
   114      {
   115        range.mBegin = i;
   116        break;
   117      }
   118   }
   119   if(kWbClassThaiLetter == c)
   120   {
   121 	// need to call Thai word breaker from here
   122 	// we should pass the whole Thai segment to the thai word breaker to find a shorter answer
   123   }
   124   return range;
   125 }
   127 int32_t nsSampleWordBreaker::NextWord( 
   128   const char16_t* aText, uint32_t aLen, uint32_t aPos) 
   129 {
   130   int8_t c1, c2;
   131   uint32_t cur = aPos;
   132   if (cur == aLen)
   133     return NS_WORDBREAKER_NEED_MORE_TEXT;
   134   c1 = this->GetClass(aText[cur]);
   136   for(cur++; cur <aLen; cur++)
   137   {
   138      c2 = this->GetClass(aText[cur]);
   139      if(c2 != c1) 
   140        break;
   141   }
   142   if(kWbClassThaiLetter == c1)
   143   {
   144 	// need to call Thai word breaker from here
   145 	// we should pass the whole Thai segment to the thai word breaker to find a shorter answer
   146   }
   147   if (cur == aLen)
   148     return NS_WORDBREAKER_NEED_MORE_TEXT;
   149   return cur;
   150 }

mercurial