Reviewed by Maciej.
[WebKit-https.git] / WebCore / khtml / rendering / break_lines.cpp
1 #include <break_lines.h>
2
3 #ifdef HAVE_THAI_BREAKS
4 #include "ThBreakIterator.h"
5
6 static const QChar *cached = 0;
7 static QCString *cachedString = 0;
8 static ThBreakIterator *thaiIt = 0;
9 #endif
10
11 #if APPLE_CHANGES
12 #include <CoreServices/CoreServices.h>
13 #endif
14
15 void cleanupLineBreaker()
16 {
17 #ifdef HAVE_THAI_BREAKS
18     if ( cachedString )
19         delete cachedString;
20     if ( thaiIt )
21         delete thaiIt;
22     cached = 0;
23 #endif
24 }
25
26 namespace khtml {
27 /*
28   This function returns true, if the string can bre broken before the 
29   character at position pos in the string s with length len
30 */
31 bool isBreakable( const QChar *s, int pos, int len)
32 {
33 #if !APPLE_CHANGES
34     const QChar *c = s+pos;
35     unsigned short ch = c->unicode();
36     if ( ch > 0xff ) {
37         // not latin1, need to do more sophisticated checks for asian fonts
38         unsigned char row = c->row();
39         if ( row == 0x0e ) {
40             // 0e00 - 0e7f == Thai
41             if ( c->cell() < 0x80 ) {
42 #ifdef HAVE_THAI_BREAKS
43                 // check for thai
44                 if( s != cached ) {
45                     // build up string of thai chars
46                     QTextCodec *thaiCodec = QTextCodec::codecForMib(2259);
47                     if ( !cachedString )
48                         cachedString = new QCString;
49                     if ( !thaiIt )
50                         thaiIt = ThBreakIterator::createWordInstance(); 
51                     *cachedString = thaiCodec->fromUnicode( QConstString( (QChar *)s, len ).string() );
52                 }
53                 thaiIt->setText((tchar *)cachedString->data());
54                 for(int i = thaiIt->first(); i != thaiIt->DONE; i = thaiIt->next() ) {
55                     if( i == pos )
56                         return true;
57                     if( i > pos )
58                         return false;
59                 }
60                 return false;
61 #else
62                 // if we don't have a thai line breaking lib, allow
63                 // breaks everywhere except directly before punctuation.
64                 return true;
65 #endif
66             } else 
67                 return false;
68         }
69         if ( row > 0x2d && row < 0xfb || row == 0x11 )
70             // asian line breaking. Everywhere allowed except directly
71             // in front of a punctuation character.
72             return true;
73         else // no asian font
74             return c->isSpace();
75     } else {
76         if ( ch == ' ' || ch == '\n' )
77             return true;
78     }
79     return false;
80 #else
81     OSStatus status = 0, findStatus = 0;
82     static TextBreakLocatorRef breakLocator = 0;
83     UniCharArrayOffset end;
84     const QChar *c = s+pos;
85     unsigned short ch = c->unicode();
86
87     // Newlines are always breakable.
88     if (ch == '\n')
89         return true;
90
91     // If current character, or the previous character aren't simple latin1 then
92     // use the UC line break locator.  UCFindTextBreak will report false if we
93     // have a sequence of 0xa0 0x20 (nbsp, sp), so we explicity check for that
94     // case.
95     unsigned short lastCh = pos > 0 ? (s+pos-1)->unicode() : 0;
96     if ((ch > 0x7f && ch != 0xa0) || (lastCh > 0x7f && lastCh != 0xa0)) {
97         if (!breakLocator)
98             status = UCCreateTextBreakLocator(NULL, 0, kUCTextBreakLineMask, &breakLocator);
99         if (status == 0)
100             findStatus = UCFindTextBreak(breakLocator, kUCTextBreakLineMask, 0, (const UniChar *)s, len, pos, &end);
101
102         // If carbon fails, fail back on simple white space detection.
103         if (findStatus == 0)
104             return ((int)end == pos) ? true : false;
105     }
106     // What about hypenation?
107     return c->direction() == QChar::DirWS;
108 #endif    
109 }
110
111 };