Skip to content
Permalink
Browse files

Support -bb-keep-all-if-korean

This is a custom extension so that the "keep-all" behavior is used
automatically if the text is Korean (based on the unicode char points), and
"normal" behavior is used in all other cases.
  • Loading branch information
bulldy80 committed Jun 6, 2013
1 parent e4e1df2 commit 8730bd6b3bf300fd0ab1640cf1636971ca8eda26
@@ -969,8 +969,8 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int
if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap)
return true;
break;
case CSSPropertyWordBreak: // normal | break-all | keep-all | break-word (this is a custom extension)
if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueKeepAll || valueID == CSSValueBreakWord)
case CSSPropertyWordBreak: // normal | break-all | keep-all || -bb-keep-all-if-korean | break-word (this is a custom extension)
if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueKeepAll || valueID == CSSValueBbKeepAllIfKorean || valueID == CSSValueBreakWord)
return true;
break;
default:
@@ -2744,6 +2744,9 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EWordBreak e)
case KeepAllWordBreak:
m_value.ident = CSSValueKeepAll;
break;
case KeepAllIfKoreanWordBreak:
m_value.ident = CSSValueBbKeepAllIfKorean;
break;
case BreakWordBreak:
m_value.ident = CSSValueBreakWord;
break;
@@ -2757,6 +2760,8 @@ template<> inline CSSPrimitiveValue::operator EWordBreak() const
return BreakAllWordBreak;
case CSSValueKeepAll:
return KeepAllWordBreak;
case CSSValueBbKeepAllIfKorean:
return KeepAllIfKoreanWordBreak;
case CSSValueBreakWord:
return BreakWordBreak;
case CSSValueNormal:
@@ -608,6 +608,7 @@ skip-white-space
//
break-all
keep-all
-bb-keep-all-if-korean

//
// CSS_PROP_WORD_WRAP
@@ -491,7 +491,7 @@ WebInspector.CSSMetadata._propertyDataMap = {
"auto"
] },
"word-break": { values: [
"normal", "break-all", "keep-all", "break-word"
"normal", "break-all", "keep-all", "-bb-keep-all-if-korean", "break-word"
] },
"word-spacing": { values: [
"normal"
@@ -2773,7 +2773,7 @@ InlineIterator RenderBlock::LineBreaker::nextSegmentBreak(InlineBidiResolver& re
bool breakWords = currentStyle->breakWords() && ((autoWrap && !width.committedWidth()) || currWS == PRE);
bool midWordBreak = false;
bool breakAll = currentStyle->wordBreak() == BreakAllWordBreak && autoWrap;
bool keepAll = currentStyle->wordBreak() == KeepAllWordBreak && autoWrap;
EWordBreak effectiveWordBreak = currentStyle->autoWrap() ? currentStyle->wordBreak() : NormalWordBreak;
float hyphenWidth = 0;

if (t->isWordBreak()) {
@@ -2824,7 +2824,7 @@ InlineIterator RenderBlock::LineBreaker::nextSegmentBreak(InlineBidiResolver& re
midWordBreak = width.committedWidth() + wrapW + charWidth > width.availableWidth();
}

bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(renderTextInfo.m_lineBreakIterator, current.m_pos, current.m_nextBreakablePosition, breakNBSP, keepAll)
bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(renderTextInfo.m_lineBreakIterator, current.m_pos, current.m_nextBreakablePosition, breakNBSP, effectiveWordBreak)
&& (style->hyphens() != HyphensNone || (current.previousInSameNode() != softHyphen)));

if (betweenWords || midWordBreak) {
@@ -994,7 +994,7 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si

bool breakNBSP = styleToUse->autoWrap() && styleToUse->nbspMode() == SPACE;
bool breakAll = (styleToUse->wordBreak() == BreakAllWordBreak || styleToUse->wordBreak() == BreakWordBreak) && styleToUse->autoWrap();
bool keepAll = styleToUse->wordBreak() == KeepAllWordBreak && styleToUse->autoWrap();
EWordBreak effectiveWordBreak = styleToUse->autoWrap() ? styleToUse->wordBreak() : NormalWordBreak;

for (int i = 0; i < len; i++) {
UChar c = characterAt(i);
@@ -1042,15 +1042,15 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
continue;
}

bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP, keepAll);
bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP, effectiveWordBreak);
bool betweenWords = true;
int j = i;
while (c != '\n' && !isSpaceAccordingToStyle(c, styleToUse) && c != '\t' && (c != softHyphen || styleToUse->hyphens() == HyphensNone)) {
j++;
if (j == len)
break;
c = characterAt(j);
if (isBreakable(breakIterator, j, nextBreakable, breakNBSP, keepAll) && characterAt(j - 1) != softHyphen)
if (isBreakable(breakIterator, j, nextBreakable, breakNBSP, effectiveWordBreak) && characterAt(j - 1) != softHyphen)
break;
if (breakAll) {
betweenWords = false;
@@ -38,6 +38,12 @@

namespace WebCore {

enum WordBreakSwitch {
Default,
KeepAll,
KeepAllIfKorean,
};

template<bool treatNoBreakSpaceAsBreak>
static inline bool isBreakableSpace(UChar ch)
{
@@ -139,15 +145,31 @@ static inline bool shouldBreakAfter(UChar lastCh, UChar ch, UChar nextCh)
return false;
}

template<bool treatNoBreakSpaceAsBreak>
inline bool isKorean(UChar ch)
{
return ch > asciiLineBreakTableLastChar
&& ((0xAC00 <= ch && ch <= 0xD7AF) ||
(0x1100 <= ch && ch <= 0x11FF) ||
(0x3130 <= ch && ch <= 0x318F) ||
(0x3200 <= ch && ch <= 0x32FF) ||
(0xA960 <= ch && ch <= 0xA97F) ||
(0xD7B0 <= ch && ch <= 0xD7FF) ||
(0xFF00 <= ch && ch <= 0xFFEF));
}

template<bool treatNoBreakSpaceAsBreak, WordBreakSwitch wordBreakSwitch>
inline bool needsLineBreakIterator(UChar ch)
{
if (wordBreakSwitch == KeepAll)
return false;
if (wordBreakSwitch == KeepAllIfKorean && isKorean(ch))
return false;
if (treatNoBreakSpaceAsBreak)
return ch > asciiLineBreakTableLastChar;
return ch > asciiLineBreakTableLastChar && ch != noBreakSpace;
}

template<typename CharacterType, bool treatNoBreakSpaceAsBreak, bool keepAll>
template<typename CharacterType, bool treatNoBreakSpaceAsBreak, WordBreakSwitch wordBreakSwitch>
static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos)
{
int len = static_cast<int>(length);
@@ -161,7 +183,7 @@ static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator
if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch))
return i;

if (!keepAll && (needsLineBreakIterator<treatNoBreakSpaceAsBreak>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak>(lastCh))) {
if (needsLineBreakIterator<treatNoBreakSpaceAsBreak, wordBreakSwitch>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak, wordBreakSwitch>(lastCh)) {
if (nextBreak < i && i) {
TextBreakIterator* breakIterator = lazyBreakIterator.get();
if (breakIterator)
@@ -178,33 +200,41 @@ static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator
return len;
}

int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos, bool keepAll)
int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos, EWordBreak wordBreak)
{
String string = lazyBreakIterator.string();
if (keepAll) {
switch (wordBreak) {
case KeepAllWordBreak:
if (string.is8Bit())
return nextBreakablePosition<LChar, false, true>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, false, true>(lazyBreakIterator, string.characters16(), string.length(), pos);
}
else {
return nextBreakablePosition<LChar, false, KeepAll>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, false, KeepAll>(lazyBreakIterator, string.characters16(), string.length(), pos);
case KeepAllIfKoreanWordBreak:
if (string.is8Bit())
return nextBreakablePosition<LChar, false, KeepAllIfKorean>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, false, KeepAllIfKorean>(lazyBreakIterator, string.characters16(), string.length(), pos);
default:
if (string.is8Bit())
return nextBreakablePosition<LChar, false, false>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, false, false>(lazyBreakIterator, string.characters16(), string.length(), pos);
return nextBreakablePosition<LChar, false, Default>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, false, Default>(lazyBreakIterator, string.characters16(), string.length(), pos);
}
}

int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos, bool keepAll)
int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos, EWordBreak wordBreak)
{
String string = lazyBreakIterator.string();
if (keepAll) {
switch (wordBreak) {
case KeepAllWordBreak:
if (string.is8Bit())
return nextBreakablePosition<LChar, true, true>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, true, true>(lazyBreakIterator, string.characters16(), string.length(), pos);
}
else {
return nextBreakablePosition<LChar, true, KeepAll>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, true, KeepAll>(lazyBreakIterator, string.characters16(), string.length(), pos);
case KeepAllIfKoreanWordBreak:
if (string.is8Bit())
return nextBreakablePosition<LChar, true, KeepAllIfKorean>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, true, KeepAllIfKorean>(lazyBreakIterator, string.characters16(), string.length(), pos);
default:
if (string.is8Bit())
return nextBreakablePosition<LChar, true, false>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, true, false>(lazyBreakIterator, string.characters16(), string.length(), pos);
return nextBreakablePosition<LChar, true, Default>(lazyBreakIterator, string.characters8(), string.length(), pos);
return nextBreakablePosition<UChar, true, Default>(lazyBreakIterator, string.characters16(), string.length(), pos);
}
}

@@ -22,21 +22,22 @@
#define break_lines_h

#include <wtf/unicode/Unicode.h>
#include "RenderStyleConstants.h"

namespace WebCore {

class LazyLineBreakIterator;

int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator&, int pos, bool keepAll);
int nextBreakablePosition(LazyLineBreakIterator&, int pos, bool keepAll);
int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator&, int pos, EWordBreak wordBreak);
int nextBreakablePosition(LazyLineBreakIterator&, int pos, EWordBreak wordBreak);

inline bool isBreakable(LazyLineBreakIterator& lazyBreakIterator, int pos, int& nextBreakable, bool breakNBSP, bool keepAll)
inline bool isBreakable(LazyLineBreakIterator& lazyBreakIterator, int pos, int& nextBreakable, bool breakNBSP, EWordBreak wordBreak)
{
if (pos > nextBreakable) {
if (breakNBSP)
nextBreakable = nextBreakablePosition(lazyBreakIterator, pos, keepAll);
nextBreakable = nextBreakablePosition(lazyBreakIterator, pos, wordBreak);
else
nextBreakable = nextBreakablePositionIgnoringNBSP(lazyBreakIterator, pos, keepAll);
nextBreakable = nextBreakablePositionIgnoringNBSP(lazyBreakIterator, pos, wordBreak);
}
return pos == nextBreakable;
}
@@ -207,7 +207,7 @@ enum EUserSelect {
// Word Break Values. Matches WinIE, rather than CSS3

enum EWordBreak {
NormalWordBreak, BreakAllWordBreak, KeepAllWordBreak, BreakWordBreak
NormalWordBreak, BreakAllWordBreak, KeepAllWordBreak, KeepAllIfKoreanWordBreak, BreakWordBreak
};

enum EOverflowWrap {

0 comments on commit 8730bd6

Please sign in to comment.
You can’t perform that action at this time.