mirror of https://github.com/buggins/dlangui.git
ascii-unicode improvements
This commit is contained in:
parent
f4d26fa758
commit
3ba090d4cb
|
@ -5,10 +5,11 @@ import std.conv : to;
|
|||
import std.string;
|
||||
import std.array : empty;
|
||||
import std.algorithm : equal;
|
||||
import std.ascii : isAlpha;
|
||||
import std.ascii : isAlpha, isWhite;
|
||||
|
||||
import dlangui.core.dom;
|
||||
import dlangui.core.css;
|
||||
import dlangui.core.types : parseHexDigit;
|
||||
|
||||
/// skip specified count of chars of string, returns next available character, or 0 if end of string reached
|
||||
private char skip(ref string src, int count = 1) {
|
||||
|
@ -33,7 +34,7 @@ private char skipSpaces(ref string str)
|
|||
char ch = str.peek;
|
||||
if (!ch)
|
||||
return 0;
|
||||
while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
|
||||
while (isWhite(ch))
|
||||
ch = str.skip;
|
||||
if (str.peek == '/' && str.peek(1) == '*') {
|
||||
// comment found
|
||||
|
@ -44,7 +45,7 @@ private char skipSpaces(ref string str)
|
|||
str.skip(2);
|
||||
}
|
||||
ch = str.peek;
|
||||
while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
|
||||
while (isWhite(ch))
|
||||
ch = str.skip;
|
||||
if (oldpos.ptr is str.ptr)
|
||||
break;
|
||||
|
@ -57,7 +58,7 @@ private char skipSpaces(ref string str)
|
|||
|
||||
|
||||
private bool isIdentChar(char ch) {
|
||||
return (ch >= 'A' && ch <='Z') || (ch >= 'a' && ch <='z') || (ch == '-') || (ch == '_');
|
||||
return isAlpha(ch) || (ch == '-') || (ch == '_');
|
||||
}
|
||||
|
||||
/// parse css identifier
|
||||
|
@ -143,17 +144,6 @@ private bool nextProperty(ref string str) {
|
|||
}
|
||||
|
||||
|
||||
private int hexDigit( char c )
|
||||
{
|
||||
if ( c >= '0' && c <= '9' )
|
||||
return c-'0';
|
||||
if ( c >= 'A' && c <= 'F' )
|
||||
return c - 'A' + 10;
|
||||
if ( c >= 'a' && c <= 'f' )
|
||||
return c - 'a' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int parseStandardColor(string ident) {
|
||||
switch(ident) {
|
||||
case "black": return 0x000000;
|
||||
|
@ -205,23 +195,23 @@ private bool parseColor(ref string src, ref CssValue value)
|
|||
// #rgb or #rrggbb colors
|
||||
ch = src.skip;
|
||||
int nDigits = 0;
|
||||
for ( ; nDigits < src.length && hexDigit(src[nDigits])>=0; nDigits++ ) {
|
||||
for ( ; nDigits < src.length && parseHexDigit(src[nDigits])>=0; nDigits++ ) {
|
||||
}
|
||||
if ( nDigits==3 ) {
|
||||
int r = hexDigit( src[0] );
|
||||
int g = hexDigit( src[1] );
|
||||
int b = hexDigit( src[2] );
|
||||
int r = parseHexDigit( src[0] );
|
||||
int g = parseHexDigit( src[1] );
|
||||
int b = parseHexDigit( src[2] );
|
||||
value.type = CssValueType.color;
|
||||
value.value = (((r + r*16) * 256) | (g + g*16)) * 256 | (b + b*16);
|
||||
src.skip(3);
|
||||
return true;
|
||||
} else if ( nDigits==6 ) {
|
||||
int r = hexDigit( src[0] ) * 16;
|
||||
r += hexDigit( src[1] );
|
||||
int g = hexDigit( src[2] ) * 16;
|
||||
g += hexDigit( src[3] );
|
||||
int b = hexDigit( src[4] ) * 16;
|
||||
b += hexDigit( src[5] );
|
||||
int r = parseHexDigit( src[0] ) * 16;
|
||||
r += parseHexDigit( src[1] );
|
||||
int g = parseHexDigit( src[2] ) * 16;
|
||||
g += parseHexDigit( src[3] );
|
||||
int b = parseHexDigit( src[4] ) * 16;
|
||||
b += parseHexDigit( src[5] );
|
||||
value.type = CssValueType.color;
|
||||
value.value = ((r * 256) | g) * 256 | b;
|
||||
src.skip(6);
|
||||
|
|
|
@ -626,9 +626,7 @@ class EditableContent {
|
|||
performOperation(op, this);
|
||||
}
|
||||
|
||||
static bool isAlphaForWordSelection(dchar ch) {
|
||||
return ch == '_' || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||
}
|
||||
static alias isAlphaForWordSelection = isAlNum;
|
||||
|
||||
/// get word bounds by position
|
||||
TextRange wordBounds(TextPosition pos) {
|
||||
|
@ -1133,21 +1131,18 @@ class EditableContent {
|
|||
}
|
||||
}
|
||||
|
||||
static bool isDigit(dchar ch) pure nothrow {
|
||||
return ch >= '0' && ch <= '9';
|
||||
}
|
||||
|
||||
static alias isDigit = std.uni.isNumber;
|
||||
static bool isAlpha(dchar ch) pure nothrow {
|
||||
return isLowerAlpha(ch) || isUpperAlpha(ch);
|
||||
return std.uni.isAlpha(ch) || ch == '_';
|
||||
}
|
||||
static bool isAlNum(dchar ch) pure nothrow {
|
||||
return isDigit(ch) || isAlpha(ch);
|
||||
}
|
||||
static bool isLowerAlpha(dchar ch) pure nothrow {
|
||||
return (ch >= 'a' && ch <= 'z') || (ch == '_');
|
||||
}
|
||||
static bool isUpperAlpha(dchar ch) pure nothrow {
|
||||
return (ch >= 'A' && ch <= 'Z');
|
||||
return std.uni.isLower(ch) || ch == '_';
|
||||
}
|
||||
static alias isUpperAlpha = std.uni.isUpper;
|
||||
static bool isPunct(dchar ch) pure nothrow {
|
||||
switch(ch) {
|
||||
case '.':
|
||||
|
|
|
@ -27,6 +27,7 @@ Authors: Vadim Lopatin, coolreader.org@gmail.com
|
|||
module dlangui.core.settings;
|
||||
|
||||
import dlangui.core.logger;
|
||||
import dlangui.core.types : parseHexDigit;
|
||||
import std.range;
|
||||
import std.algorithm : equal;
|
||||
import std.conv : to;
|
||||
|
@ -1623,42 +1624,28 @@ final class Setting {
|
|||
context = "near `" ~ json[contextStart .. contextEnd] ~ "` ";
|
||||
throw new Exception("JSON parsing error in (" ~ to!string(line) ~ ":" ~ to!string(col) ~ ") " ~ context ~ ": " ~ msg);
|
||||
}
|
||||
static bool isSpace(char ch) {
|
||||
return ch== ' ' || ch == '\t' || ch == '\r' || ch == '\n';
|
||||
}
|
||||
static bool isAlpha(char ch) {
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_';
|
||||
return std.ascii.isAlpha(ch) || ch == '_';
|
||||
}
|
||||
static bool isAlNum(char ch) {
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_';
|
||||
}
|
||||
static bool isDigit(char ch) {
|
||||
return (ch >= '0' && ch <= '9');
|
||||
return std.ascii.isAlphaNum(ch) || ch == '_';
|
||||
}
|
||||
@property char skipSpaces() {
|
||||
for(;pos < json.length;pos++) {
|
||||
char ch = json[pos];
|
||||
if (!isSpace(ch))
|
||||
if (!std.ascii.isWhite(ch))
|
||||
break;
|
||||
}
|
||||
return peek;
|
||||
}
|
||||
static int parseHexDigit(char ch) {
|
||||
if (ch >= '0' && ch <='9')
|
||||
return ch - '0';
|
||||
if (ch >= 'a' && ch <='f')
|
||||
return ch - 'a' + 10;
|
||||
if (ch >= 'A' && ch <='F')
|
||||
return ch - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
string parseUnicodeChar() {
|
||||
if (pos >= json.length - 3)
|
||||
error("unexpected end of file while parsing unicode character entity inside string");
|
||||
dchar ch = 0;
|
||||
foreach(i; 0 .. 4) {
|
||||
int d = parseHexDigit(nextChar);
|
||||
if (d < 0)
|
||||
uint d = parseHexDigit(nextChar);
|
||||
if (d == uint.max)
|
||||
error("error while parsing unicode character entity inside string");
|
||||
ch = (ch << 4) | d;
|
||||
}
|
||||
|
@ -1756,6 +1743,7 @@ final class Setting {
|
|||
|
||||
// parse long, ulong or double
|
||||
void parseNumber(Setting res) {
|
||||
import std.ascii : isDigit;
|
||||
char ch = peek;
|
||||
int sign = 1;
|
||||
if (ch == '-') {
|
||||
|
@ -1886,7 +1874,7 @@ final class Setting {
|
|||
this = true;
|
||||
} else if (parser.parseKeyword("false")) {
|
||||
this = false;
|
||||
} else if (ch == '-' || JsonParser.isDigit(ch)) {
|
||||
} else if (ch == '-' || std.ascii.isDigit(ch)) {
|
||||
parser.parseNumber(this);
|
||||
} else {
|
||||
parser.error("cannot parse JSON value");
|
||||
|
|
|
@ -45,19 +45,13 @@ public import dlangui.core.config;
|
|||
|
||||
import std.algorithm;
|
||||
|
||||
/** 2D point */
|
||||
/// 2D point
|
||||
struct Point {
|
||||
/// x coordinate
|
||||
int x;
|
||||
/// y coordinate
|
||||
int y;
|
||||
this(int x0, int y0) {
|
||||
x = x0;
|
||||
y = y0;
|
||||
}
|
||||
}
|
||||
|
||||
/** 2D rectangle */
|
||||
/// 2D rectangle
|
||||
struct Rect {
|
||||
/// x coordinate of top left corner
|
||||
int left;
|
||||
|
@ -427,26 +421,6 @@ struct Ref(T) { // if (T is RefCountedObject)
|
|||
//================================================================================
|
||||
// some utility functions
|
||||
|
||||
/*
|
||||
string fromStringz(const(char[]) s) {
|
||||
if (s is null)
|
||||
return null;
|
||||
int i = 0;
|
||||
while(s[i])
|
||||
i++;
|
||||
return cast(string)(s[0..i].dup);
|
||||
}
|
||||
|
||||
string fromStringz(const(char*) s) {
|
||||
if (s is null)
|
||||
return null;
|
||||
int i = 0;
|
||||
while(s[i])
|
||||
i++;
|
||||
return cast(string)(s[0..i].dup);
|
||||
}
|
||||
*/
|
||||
|
||||
/** conversion from wchar z-string */
|
||||
wstring fromWStringz(const(wchar[]) s) {
|
||||
if (s is null)
|
||||
|
@ -497,15 +471,20 @@ enum State : uint {
|
|||
Parent = 0x10000, // use parent's state
|
||||
}
|
||||
|
||||
/**
|
||||
/** Deprecated: use std.uni.toUpper instead.
|
||||
Uppercase unicode character.
|
||||
|
||||
TODO: support non-ascii.
|
||||
*/
|
||||
dchar dcharToUpper(dchar ch) {
|
||||
// TODO: support non-ascii letters
|
||||
if (ch >= 'a' && ch <= 'z')
|
||||
return ch - 'a' + 'A';
|
||||
return ch;
|
||||
deprecated dchar dcharToUpper(dchar ch) {
|
||||
return std.uni.toUpper(ch);
|
||||
}
|
||||
|
||||
/// decodes hex digit (0..9, a..f, A..F), returns uint.max if invalid
|
||||
uint parseHexDigit(T)(T ch) pure nothrow {
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
return ch - 'a' + 10;
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
return ch - 'A' + 10;
|
||||
return uint.max;
|
||||
}
|
||||
|
|
|
@ -347,13 +347,13 @@ class Tokenizer {
|
|||
foreach(i; 0 .. prefixLen)
|
||||
ch = skipChar();
|
||||
|
||||
uint n = decodeHexDigit(ch);
|
||||
uint n = parseHexDigit(ch);
|
||||
if (n == uint.max)
|
||||
return parseError();
|
||||
|
||||
for(;;) {
|
||||
ch = skipChar();
|
||||
uint digit = decodeHexDigit(ch);
|
||||
uint digit = parseHexDigit(ch);
|
||||
if (digit == uint.max)
|
||||
break;
|
||||
n = (n << 4) + digit;
|
||||
|
|
|
@ -163,17 +163,6 @@ bool isFullyTransparentColor(uint color) pure nothrow {
|
|||
return (color >> 24) == 0xFF;
|
||||
}
|
||||
|
||||
/// decodes hex digit (0..9, a..f, A..F), returns uint.max if invalid
|
||||
uint decodeHexDigit(T)(T ch) pure nothrow {
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
return ch - 'a' + 10;
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
return ch - 'A' + 10;
|
||||
return uint.max;
|
||||
}
|
||||
|
||||
/// decode color string supported formats: #RGB #ARGB #RRGGBB #AARRGGBB
|
||||
uint decodeHexColor(string s, uint defValue = 0) pure {
|
||||
s = strip(s);
|
||||
|
@ -205,7 +194,7 @@ uint decodeHexColor(string s, uint defValue = 0) pure {
|
|||
return defValue;
|
||||
uint value = 0;
|
||||
foreach(i; 1 .. s.length) {
|
||||
uint digit = decodeHexDigit(s[i]);
|
||||
uint digit = parseHexDigit(s[i]);
|
||||
if (digit == uint.max)
|
||||
return defValue;
|
||||
value = (value << 4) | digit;
|
||||
|
|
|
@ -7,7 +7,7 @@ Layouts are similar to the same in Android.
|
|||
|
||||
LinearLayout - either VerticalLayout or HorizontalLayout.
|
||||
VerticalLayout - just LinearLayout with orientation=Orientation.Vertical
|
||||
HorizontalLayout - just LinearLayout with orientation=Orientation.Vertical
|
||||
HorizontalLayout - just LinearLayout with orientation=Orientation.Horizontal
|
||||
FrameLayout - children occupy the same place, usually one one is visible at a time
|
||||
TableLayout - children aligned into rows and columns
|
||||
ResizerWidget - widget to resize sibling widgets
|
||||
|
|
|
@ -155,14 +155,14 @@ class MenuItem {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return dcharToUpper(ch);
|
||||
return std.uni.toUpper(ch);
|
||||
}
|
||||
|
||||
/// find subitem by hotkey character, returns subitem index, -1 if not found
|
||||
int findSubitemByHotkey(dchar ch) {
|
||||
if (!ch)
|
||||
return -1;
|
||||
ch = dcharToUpper(ch);
|
||||
ch = std.uni.toUpper(ch);
|
||||
for (int i = 0; i < _subitems.length; i++) {
|
||||
if (_subitems[i].getHotkey() == ch)
|
||||
return i;
|
||||
|
|
Loading…
Reference in New Issue