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