15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005, 2007, 2010 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google Inc. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/break_lines.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/TextBreakIterator.h"
3102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/ASCIICType.h"
3202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/StdLibExtras.h"
3302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/unicode/CharacterNames.h"
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<bool treatNoBreakSpaceAsBreak>
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isBreakableSpace(UChar ch)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (ch) {
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case ' ':
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case '\n':
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case '\t':
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case noBreakSpace:
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return treatNoBreakSpaceAsBreak;
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const UChar asciiLineBreakTableFirstChar = '!';
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const UChar asciiLineBreakTableLastChar = 127;
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Pack 8 bits into one byte
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define B(a, b, c, d, e, f, g, h) \
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ((a) | ((b) << 1) | ((c) << 2) | ((d) << 3) | ((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7))
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Line breaking table row for each digit (0-9)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define DI { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Line breaking table row for ascii letters (a-z A-Z)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define AL { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define F 0xFF
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Line breaking table for printable ASCII characters. Line breaking opportunities in this table are as below:
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// - before opening punctuations such as '(', '<', '[', '{' after certain characters (compatible with Firefox 3.6);
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// - after '-' and '?' (backward-compatible, and compatible with Internet Explorer).
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Please refer to <https://bugs.webkit.org/show_bug.cgi?id=37698> for line breaking matrixes of different browsers
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// and the ICU standard.
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const unsigned char asciiLineBreakTable[][(asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar) / 8 + 1] = {
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //  !  "  #  $  %  &  '  (     )  *  +  ,  -  .  /  0  1-8   9  :  ;  <  =  >  ?  @     A-X      Y  Z  [  \  ]  ^  _  `     a-x      y  z  {  |  }  ~  DEL
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // !
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // "
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // #
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // $
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // %
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // &
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // '
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // (
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // )
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // *
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // +
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // ,
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(1, 1, 1, 1, 1, 1, 1, 1), B(1, 1, 1, 1, 1, 0, 1, 0), 0, B(0, 1, 1, 1, 1, 1, 1, 1), F, F, F, B(1, 1, 1, 1, 1, 1, 1, 1), F, F, F, B(1, 1, 1, 1, 1, 1, 1, 1) }, // - Note: breaking before '0'-'9' is handled hard-coded in shouldBreakAfter().
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // .
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // /
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DI,  DI,  DI,  DI,  DI,  DI,  DI,  DI,  DI,  DI, // 0-9
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // :
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // ;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // <
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // =
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // >
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 1, 1, 1, 1, 0, 1), B(0, 1, 1, 0, 1, 0, 0, 1), F, B(1, 0, 0, 1, 1, 1, 0, 1), F, F, F, B(1, 1, 1, 1, 0, 1, 1, 1), F, F, F, B(1, 1, 1, 1, 0, 1, 1, 0) }, // ?
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // @
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL, // A-Z
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // [
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // '\'
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // ]
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // ^
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // _
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // `
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL,  AL, // a-z
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // {
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // |
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // }
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // ~
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    { B(0, 0, 0, 0, 0, 0, 0, 0), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 0, 0, 0, 0, 0, 0) }, // DEL
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#undef B
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#undef F
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#undef DI
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#undef AL
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)COMPILE_ASSERT(WTF_ARRAY_LENGTH(asciiLineBreakTable) == asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar + 1, TestLineBreakTableConsistency);
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool shouldBreakAfter(UChar lastCh, UChar ch, UChar nextCh)
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Don't allow line breaking between '-' and a digit if the '-' may mean a minus sign in the context,
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // while allow breaking in 'ABCD-1234' and '1234-5678' which may be in long URLs.
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (ch == '-' && isASCIIDigit(nextCh))
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return isASCIIAlphanumeric(lastCh);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // with other browsers (see comments for asciiLineBreakTable for details).
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) {
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar];
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int nextChIndex = nextCh - asciiLineBreakTableFirstChar;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8));
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Otherwise defer to the Unicode algorithm by returning false.
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<bool treatNoBreakSpaceAsBreak>
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool needsLineBreakIterator(UChar ch)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (treatNoBreakSpaceAsBreak)
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return ch > asciiLineBreakTableLastChar;
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ch > asciiLineBreakTableLastChar && ch != noBreakSpace;
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename CharacterType, bool treatNoBreakSpaceAsBreak>
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int len = static_cast<int>(length);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int nextBreak = -1;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    CharacterType lastLastCh = pos > 1 ? str[pos - 2] : static_cast<CharacterType>(lazyBreakIterator.secondToLastCharacter());
153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    CharacterType lastCh = pos > 0 ? str[pos - 1] : static_cast<CharacterType>(lazyBreakIterator.lastCharacter());
154521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    unsigned priorContextLength = lazyBreakIterator.priorContextLength();
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int i = pos; i < len; i++) {
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        CharacterType ch = str[i];
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch))
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return i;
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (needsLineBreakIterator<treatNoBreakSpaceAsBreak>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak>(lastCh)) {
162521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            if (nextBreak < i) {
163521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                // Don't break if positioned at start of primary context and there is no prior context.
164521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                if (i || priorContextLength) {
165521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                    TextBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength);
166521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                    if (breakIterator) {
1671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                        nextBreak = breakIterator->following(i - 1 + priorContextLength);
168521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                        if (nextBreak >= 0) {
169521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                            nextBreak -= priorContextLength;
170521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                        }
171521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                    }
172521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                }
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (i == nextBreak && !isBreakableSpace<treatNoBreakSpaceAsBreak>(lastCh))
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return i;
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lastLastCh = lastCh;
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lastCh = ch;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return len;
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos)
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String string = lazyBreakIterator.string();
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (string.is8Bit())
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return nextBreakablePosition<LChar, false>(lazyBreakIterator, string.characters8(), string.length(), pos);
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return nextBreakablePosition<UChar, false>(lazyBreakIterator, string.characters16(), string.length(), pos);
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
194