#include "tkText.h"
#include <ctype.h>
#include <assert.h>
#ifndef MAX
# define MAX(a,b) (((int) a) < ((int) b) ? b : a)
#endif
typedef void (*ComputeBreakLocationsFunc)(
const unsigned char *text, size_t len, const char *lang, char *brks);
static void ComputeBreakLocations(
const unsigned char *text, size_t len, const char *lang, char *brks);
static ComputeBreakLocationsFunc libLinebreakFunc = ComputeBreakLocations;
#ifdef __UNIX__
static int
LoadFile(
Tcl_Interp *interp,
Tcl_Obj *pathPtr,
Tcl_LoadHandle *handle,
char const **symbols,
void **funcs)
{
# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 5
return Tcl_FSLoadFile(interp, pathPtr, symbols[0], symbols[1],
(void *) &funcs[0], (void *) &funcs[1], handle, NULL);
# else
return Tcl_LoadFile(interp, pathPtr, symbols, TCL_LOAD_GLOBAL, funcs, handle);
# endif
}
static void
LoadLibUnibreak(
Tcl_Interp *interp)
{
typedef void *VoidP;
typedef void (*InitFunc)();
static char const *Symbols[3] = {
"init_linebreak",
"set_linebreaks_utf8",
NULL
};
VoidP Funcs[sizeof(Symbols)/sizeof(Symbols[0])];
Tcl_LoadHandle handle;
Tcl_Obj *pathPtr = Tcl_NewStringObj("libunibreak.so.1", -1);
bool rc;
Tcl_IncrRefCount(pathPtr);
rc = LoadFile(interp, pathPtr, &handle, Symbols, Funcs);
if (rc != TCL_OK) {
Tcl_ResetResult(interp);
Tcl_DecrRefCount(pathPtr);
pathPtr = Tcl_NewStringObj("liblinebreak.so.2", -1);
rc = LoadFile(interp, pathPtr, &handle, Symbols, Funcs);
}
if (rc == TCL_OK) {
((InitFunc) Funcs[0])();
libLinebreakFunc = Funcs[1];
} else {
Tcl_ResetResult(interp);
}
Tcl_DecrRefCount(pathPtr);
}
#endif
static ComputeBreakLocationsFunc
GetLineBreakFunc(
Tcl_Interp *interp,
char const *lang)
{
#ifdef __UNIX__
if (lang) {
static bool loaded = false;
if (!loaded) {
LoadLibUnibreak(interp);
}
}
#endif
return libLinebreakFunc;
}
bool
TkTextComputeBreakLocations(
Tcl_Interp *interp,
const char *text,
unsigned len,
const char *lang,
char *brks)
{
ComputeBreakLocationsFunc func;
int lastBreakablePos = -1;
unsigned i;
assert(text);
assert(brks);
assert(text[len] == '\0');
assert(!lang || (isalpha(lang[0]) && isalpha(lang[1]) && !lang[2]));
func = GetLineBreakFunc(interp, lang);
len += 1;
(*func)((const unsigned char *) text, len, lang, brks);
len -= 1;
for (i = 0; i < len; ++i) {
switch (brks[i]) {
case LINEBREAK_MUSTBREAK:
break;
case LINEBREAK_ALLOWBREAK:
if (text[i] == '-') {
if (brks[i] == LINEBREAK_ALLOWBREAK) {
const char *r = text + i;
const char *p, *q, *s;
Tcl_UniChar uc;
bool allow = false;
q = Tcl_UtfPrev(r, text);
if (q != r) {
Tcl_UtfToUniChar(q, &uc);
if (Tcl_UniCharIsAlpha(uc)) {
p = Tcl_UtfPrev(q, text);
if (p != q) {
Tcl_UtfToUniChar(p, &uc);
if (Tcl_UniCharIsAlpha(uc)) {
s = r + 1;
s += Tcl_UtfToUniChar(s, &uc);
if (Tcl_UniCharIsAlpha(uc)) {
Tcl_UtfToUniChar(s, &uc);
if (Tcl_UniCharIsAlpha(uc)) {
allow = true;
}
}
}
}
}
}
if (!allow) {
brks[i] = LINEBREAK_NOBREAK;
}
}
} else if (text[i] == '/' && i > 8) {
if (lastBreakablePos >= i - 2
|| (i > 40 && lastBreakablePos >= i - 7 && text[i - 1] == '/')) {
continue;
}
if (i < len - 1 && text[i + 1] != ' ' && text[i - 1] == ' ') {
lastBreakablePos = i - 1;
continue;
}
}
lastBreakablePos = i;
break;
case LINEBREAK_INSIDEACHAR:
break;
}
}
return func != ComputeBreakLocations;
}
typedef enum {
AI, AL, B2, BA, BB, BK, CL, CP, EX, GL, HY, IN, IS, NS, NU, OP, PO, PR, QU, SP, SY, WJ, ZW
} LBClass;
#define __ AI
static const char Table_0000[256] = {
__, __, __, __, __, __, __, __, __, BA, BK, BK, BK, BK, BK, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
SP, EX, QU, IN, PR, PO, BB, QU, OP, CP, AL, PR, IS, HY, IS, SY,
NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, IS, IS, AL, GL, AL, EX,
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, AL, OP, PR, CP, 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, AL, AL, AL, OP, BA, CL, AL, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
GL, OP, PO, PR, PR, PR, AL, AL, AL, AL, __, QU, __, __, AL, AL,
PO, PR, AL, AL, BB, __, AL, AL, AL, AL, __, __, AL, AL, AL, OP,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E280[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
BA, BA, BA, BA, BA, BA, BA, GL, BA, __, __, ZW, __, __, __, __,
BA, AL, BA, BA, B2, AL, AL, AL, QU, QU, OP, QU, QU, QU, OP, QU,
AL, AL, AL, AL, IN, IN, IN, BA, BK, BK, __, __, __, __, __, GL,
PO, PO, PO, PO, PO, PO, PO, PO, AL, QU, QU, AL, NS, NS, AL, AL,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E281[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
AL, AL, AL, AL, IS, OP, CL, NS, NS, NS, AL, AL, AL, AL, AL, AL,
AL, AL, __, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, __,
WJ, AL, AL, AL, AL, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, OP, CL, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E282[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, CL, CL, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
PR, PR, PR, PR, PR, PR, PR, PO, PR, PR, PR, PR, PR, PR, PR, PR,
PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, PR, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E28C[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, OP, CL, OP, CL, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, OP, CL, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E29D[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, OP, CL, OP, CL, OP, CL, OP, CL,
OP, CL, OP, CL, OP, CL, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E29F[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, OP, CL, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, OP, CL, OP, CL, OP, CL, OP, CL, OP, CL,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E2A6[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, OP, CL, OP, CL, OP, CL, OP, CL, OP, CL, OP, CL, OP,
CL, OP, CL, OP, CL, OP, CL, OP, CL, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E2A7[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, OP, CL, OP, CL, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, OP, CL, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E2B8[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
AL, AL, QU, QU, QU, QU, AL, AL, AL, QU, QU, AL, QU, QU, AL, AL,
AL, AL, AL, AL, AL, AL, AL, AL, OP, AL, AL, AL, QU, QU, AL, AL,
QU, QU, OP, CL, OP, CL, OP, CL, OP, CL, AL, AL, AL, AL, AL, __,
AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, B2, B2, AL, AL, AL, AL,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_E380[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, CL, CL, AL, __, NS, __, __, OP, CL, OP, CL, OP, CL, OP, CL,
OP, CL, __, __, OP, CL, OP, CL, OP, CL, OP, CL, NS, OP, CL, CL,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
AL, __, __, __, __, __, __, __, __, __, __, NS, NS, AL, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_EFB8[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
IS, CL, CL, IS, IS, AL, AL, OP, CL, IN, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
AL, AL, AL, AL, AL, OP, CL, OP, CL, OP, CL, OP, CL, OP, CL, OP,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_EFB9[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
CL, OP, CL, OP, CL, AL, AL, OP, CL, AL, AL, AL, AL, AL, AL, AL,
CL, CL, CL, __, NS, NS, AL, AL, B2, OP, CL, OP, CL, OP, CL, AL,
AL, AL, __, B2, __, __, __, __, AL, PR, PO, AL, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_EFBC[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, AL,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, EX, AL, AL, PR, PO, AL, AL, OP, CL, AL, __, CL, B2, CL, AL,
NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NS, NS, __, __, __, EX,
AL, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, OP, AL, CL, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
static const char Table_EFBD[256] = {
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, OP, __, CL, __, OP,
CL, CL, OP, CL, CL, AL, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, WJ,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
};
#undef __
#define PROHIBITED LINEBREAK_NOBREAK
#define DIRECT LINEBREAK_ALLOWBREAK
#define INDIRECT ((char) (~LINEBREAK_NOBREAK & ~LINEBREAK_ALLOWBREAK & 0x7f))
#define X PROHIBITED
#define i INDIRECT
#define _ DIRECT
static const char BrkPairTable[23][23] = {
{ X, X, _, i, _, _, X, X, X, i, i, i, X, i, i, i, _, _, i, _, X, X, X },
{ i, i, _, i, _, _, X, X, X, i, i, i, X, i, i, i, _, _, i, _, X, X, X },
{ _, _, _, i, _, _, X, X, X, i, i, _, X, i, _, _, _, _, i, _, X, X, X },
{ _, _, _, i, _, _, X, X, X, i, i, _, X, i, _, _, _, _, i, _, X, X, X },
{ i, i, i, i, i, _, X, X, X, _, i, i, X, i, i, i, i, i, i, _, X, X, X },
{ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ },
{ _, _, _, i, _, _, X, X, X, i, i, _, X, X, _, _, i, i, i, _, X, X, X },
{ i, i, _, i, _, _, X, X, X, i, i, _, X, X, i, _, i, i, i, _, X, X, X },
{ _, _, _, i, _, _, X, X, X, i, i, _, X, i, _, _, _, _, i, _, X, X, X },
{ i, i, i, i, i, _, X, X, X, i, i, i, X, i, i, i, i, i, i, _, X, X, X },
{ _, _, _, i, _, _, X, X, X, _, i, _, X, i, i, _, _, _, i, _, X, X, X },
{ _, _, _, i, _, _, X, X, X, i, i, i, X, i, _, _, _, _, i, _, X, X, X },
{ i, i, _, i, _, _, X, X, X, i, i, _, X, i, i, _, _, _, i, _, X, X, X },
{ _, _, _, i, _, _, X, X, X, i, i, _, X, i, _, _, _, _, i, _, X, X, X },
{ i, i, _, i, _, _, X, X, X, i, i, i, X, i, i, i, i, i, i, _, X, X, X },
{ X, X, X, X, X, _, X, X, X, X, X, X, X, X, X, X, X, X, X, _, X, X, X },
{ i, i, _, i, _, _, X, X, X, i, i, _, X, i, i, i, _, _, i, _, X, X, X },
{ _, i, _, i, _, _, X, X, X, i, i, _, X, i, i, i, _, _, i, _, X, X, X },
{ i, i, i, i, i, _, X, X, X, i, i, i, X, i, i, X, i, i, i, _, X, X, X },
{ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ },
{ _, _, _, i, _, _, X, X, X, i, i, _, X, i, i, _, _, _, i, _, X, X, X },
{ i, i, i, i, i, _, X, X, X, i, i, i, X, i, i, i, i, i, i, _, X, X, X },
{ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, X },
};
#undef _
#undef i
#undef X
static void
ComputeBreakLocations(
const unsigned char *text,
size_t len,
const char *lang,
char *brks)
{
size_t i;
size_t nbytes;
size_t nletters;
size_t brkIndex;
LBClass cls;
LBClass prevCls;
if (len == 0) {
return;
}
i = 0;
nletters = 0;
brkIndex = 0;
cls = BK;
prevCls = WJ;
brks[len - 1] = LINEBREAK_MUSTBREAK;
while (i < len) {
unsigned char ch;
LBClass pcls;
ch = text[i];
if (ch < 0x80) {
pcls = Table_0000[ch];
nbytes = 1;
} else if ((ch & 0xe0) == 0xc0) {
pcls = AI;
switch (ch) {
case 0xc2:
switch (UCHAR(text[i + 1])) {
case 0x85: pcls = BK; break;
case 0xac: pcls = AL; break;
case 0xad: pcls = BA; break;
case 0xb1: pcls = AL; break;
case 0xbb: pcls = QU; break;
}
break;
case 0xc3:
case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
case 0xc8:
case 0xc9:
ch = text[i + 1];
if (0x80 <= ch && ch <= 0xbf) {
pcls = AL;
}
break;
case 0xca:
ch = text[i + 1];
if (0x80 <= ch && ch <= 0xaf) {
pcls = AL;
}
break;
case 0xcb:
switch (UCHAR(text[i + 1])) {
case 0x88:
case 0x8c:
case 0x9f: pcls = BB; break;
}
break;
case 0xcd:
if (UCHAR(text[i + 1]) == 0x8f) {
pcls = GL;
}
break;
case 0xd7:
if (UCHAR(text[i + 1]) == 0x86) {
pcls = EX;
}
break;
case 0xdf:
if (UCHAR(text[i + 1]) == 0xb8) {
pcls = IS;
}
break;
}
nbytes = 2;
brks[i] = LINEBREAK_INSIDEACHAR;
} else if ((ch & 0xf0) == 0xe0) {
pcls = AI;
switch (ch) {
case 0xe2:
switch (UCHAR(text[i + 1])) {
case 0x80: pcls = Table_E280[UCHAR(text[i + 2])]; break;
case 0x81: pcls = Table_E281[UCHAR(text[i + 2])]; break;
case 0x82: pcls = Table_E282[UCHAR(text[i + 2])]; break;
case 0x8c: pcls = Table_E28C[UCHAR(text[i + 2])]; break;
case 0x9d: pcls = Table_E29D[UCHAR(text[i + 2])]; break;
case 0x9f: pcls = Table_E29F[UCHAR(text[i + 2])]; break;
case 0xa6: pcls = Table_E2A6[UCHAR(text[i + 2])]; break;
case 0xa7: pcls = Table_E2A7[UCHAR(text[i + 2])]; break;
case 0xb8: pcls = Table_E2B8[UCHAR(text[i + 2])]; break;
case 0x84:
switch (UCHAR(text[i + 2])) {
case 0x83:
case 0x89: pcls = PO; break;
case 0x96: pcls = PR; break;
}
break;
case 0x88:
switch (UCHAR(text[i + 2])) {
case 0x92:
case 0x93: pcls = PR; break;
}
break;
case 0xb9:
switch (UCHAR(text[i + 2])) {
case 0x80: pcls = B2; break;
case 0x81: pcls = AL; break;
case 0x82: pcls = OP; break;
}
break;
}
break;
case 0xe3:
if (UCHAR(text[i + 1]) == 0x80) {
pcls = Table_E380[UCHAR(text[i + 2])];
}
break;
case 0xef:
switch (UCHAR(text[i + 1])) {
case 0xb8: pcls = Table_EFB8[UCHAR(text[i + 2])]; break;
case 0xb9: pcls = Table_EFB9[UCHAR(text[i + 2])]; break;
case 0xbc: pcls = Table_EFBC[UCHAR(text[i + 2])]; break;
case 0xbd: pcls = Table_EFBD[UCHAR(text[i + 2])]; break;
case 0xb4:
switch (UCHAR(text[i + 2])) {
case 0xbe: pcls = CL; break;
case 0xbf: pcls = OP; break;
}
break;
case 0xbb:
if (UCHAR(text[i + 2]) == 0xbf) {
pcls = WJ;
}
break;
case 0xbf:
switch (UCHAR(text[i + 2])) {
case 0xa0: pcls = PO; break;
case 0xa1:
case 0xa5:
case 0xa6: pcls = PR; break;
}
break;
}
break;
}
nbytes = 3;
brks[i + 0] = LINEBREAK_INSIDEACHAR;
brks[i + 1] = LINEBREAK_INSIDEACHAR;
} else if ((ch & 0xf8) == 0xf0) {
pcls = AI;
nbytes = 4;
brks[i + 0] = LINEBREAK_INSIDEACHAR;
brks[i + 1] = LINEBREAK_INSIDEACHAR;
brks[i + 2] = LINEBREAK_INSIDEACHAR;
#if TCL_UTF_MAX > 4
} else if ((ch & 0xf8) == 0xf8) {
pcls = AI;
nbytes = 5;
brks[i + 0] = LINEBREAK_INSIDEACHAR;
brks[i + 1] = LINEBREAK_INSIDEACHAR;
brks[i + 2] = LINEBREAK_INSIDEACHAR;
brks[i + 3] = LINEBREAK_INSIDEACHAR;
# if TCL_UTF_MAX > 5
} else if ((ch & 0xf8) == 0xfe) {
pcls = AI;
nbytes = 6;
brks[i + 0] = LINEBREAK_INSIDEACHAR;
brks[i + 1] = LINEBREAK_INSIDEACHAR;
brks[i + 2] = LINEBREAK_INSIDEACHAR;
brks[i + 3] = LINEBREAK_INSIDEACHAR;
brks[i + 4] = LINEBREAK_INSIDEACHAR;
# endif
#endif
} else {
int k;
const char *p = (const char *) text + i;
pcls = AI;
nbytes = Tcl_UtfNext(p) - p;
for (k = 0; k < nbytes; ++k) {
brks[i + k] = LINEBREAK_INSIDEACHAR;
}
}
if (i == 0) {
if ((cls = pcls) == SP) {
prevCls = cls = WJ;
}
} else {
switch (pcls) {
case BK:
brks[i - 1] = LINEBREAK_NOBREAK;
brks[i] = LINEBREAK_MUSTBREAK;
prevCls = WJ;
return;
case SP:
if (i > 0) {
brks[i - 1] = LINEBREAK_NOBREAK;
prevCls = SP;
} else {
prevCls = WJ;
}
nletters = 0;
break;
case HY: {
char brk = BrkPairTable[cls][HY];
brks[i - 1] = LINEBREAK_NOBREAK;
cls = pcls;
if (brk == INDIRECT) {
prevCls = pcls;
} else {
prevCls = WJ;
if (brk == LINEBREAK_ALLOWBREAK && nletters >= 2) {
brkIndex = i - 1;
}
}
nletters = 0;
break;
}
default: {
char brk = BrkPairTable[cls][pcls];
if (brk == INDIRECT) {
brk = (prevCls == SP) ? LINEBREAK_ALLOWBREAK : LINEBREAK_NOBREAK;
prevCls = pcls;
} else {
prevCls = WJ;
}
brks[i - 1] = brk;
cls = pcls;
if (pcls == AL) {
nletters += 1;
if (brkIndex && nletters >= 2) {
brks[brkIndex] = LINEBREAK_ALLOWBREAK;
brkIndex = 0;
}
} else {
nletters = 0;
}
break;
}
}
}
i += nbytes;
}
}