mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-25 23:57:53 +03:00
Fixes in Color::isColorString, added some functions to String, refactored a few things in LuaPattern. Fixed a crash while rendering text with only spaces. Improved FunctionString performance.
This commit is contained in:
@@ -117,6 +117,12 @@ table, td {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
hr {
|
||||
min-height: 1dp;
|
||||
background-color: gray;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,15 @@ class EE_API String {
|
||||
return hash;
|
||||
}
|
||||
|
||||
static constexpr String::HashType hashToLower( const char* str, Int64 len ) {
|
||||
String::HashType hash = 5381;
|
||||
while ( --len >= 0 ) {
|
||||
int c = *str++;
|
||||
hash = ( ( hash << 5 ) + hash ) + ( c >= 'A' && c <= 'Z' ? c + 32 : c );
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/** Escape string sequence */
|
||||
static String escape( const String& str );
|
||||
|
||||
@@ -104,6 +113,18 @@ class EE_API String {
|
||||
* String( "text" ) ) */
|
||||
static String::HashType hash( const String& str );
|
||||
|
||||
/** @return string hash to lower. Assumes ASCII */
|
||||
static String::HashType hashToLower( const std::string& str );
|
||||
|
||||
/** @return string hash to lower. Assumes ASCII */
|
||||
static String::HashType hashToLower( const std::string_view& str );
|
||||
|
||||
/** @return string hash to lower. Assumes ASCII */
|
||||
static String::HashType hashToLower( const String::View& str );
|
||||
|
||||
/** @return string hash to lower. Assumes ASCII */
|
||||
static String::HashType hashToLower( const String& str );
|
||||
|
||||
/** @return If the value passed is a character */
|
||||
static bool isCharacter( const int& value );
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <eepp/core/containers.hpp>
|
||||
#include <eepp/core/string.hpp>
|
||||
#include <eepp/system/bitop.hpp>
|
||||
#include <eepp/system/functionstring.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
@@ -220,7 +221,7 @@ class EE_API Color : public tColor<Uint8> {
|
||||
|
||||
static Color fromString( std::string str );
|
||||
|
||||
static bool isColorString( std::string str, bool searchColorNames = true );
|
||||
static bool isColorString( std::string_view str, bool searchColorNames = true );
|
||||
|
||||
static bool isColorString( String::View str, bool searchColorNames = true );
|
||||
|
||||
@@ -400,9 +401,13 @@ class EE_API Color : public tColor<Uint8> {
|
||||
|
||||
private:
|
||||
static UnorderedMap<std::string, Color> sColors;
|
||||
static UnorderedMap<String::HashType, Color> sColorHash;
|
||||
static UnorderedMap<String::HashType, Color> sColorMap;
|
||||
|
||||
static void initColorMap();
|
||||
|
||||
template <AllowedFunctionString StringType>
|
||||
static bool isColorStringT( StringType str, bool searchColorNames );
|
||||
};
|
||||
|
||||
typedef Color ColorA;
|
||||
|
||||
@@ -2,21 +2,36 @@
|
||||
#define EE_SYSTEM_FUNCTIONSTRING_HPP
|
||||
|
||||
#include <eepp/config.hpp>
|
||||
#include <eepp/core/small_vector.hpp>
|
||||
#include <eepp/core/string.hpp>
|
||||
|
||||
#include <concepts>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
template <typename T>
|
||||
concept AllowedFunctionString =
|
||||
std::same_as<T, std::string_view> || std::same_as<T, EE::String::View>;
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
class EE_API FunctionString {
|
||||
public:
|
||||
static FunctionString parse( const std::string& function );
|
||||
using Parameters = SmallVector<std::string, 4>;
|
||||
using TypeStringVector = SmallVector<bool, 4>;
|
||||
|
||||
FunctionString( const std::string& name, const std::vector<std::string>& parameters,
|
||||
const std::vector<bool>& typeStringData );
|
||||
static FunctionString parse( std::string_view function );
|
||||
|
||||
static FunctionString parse( String::View function );
|
||||
|
||||
FunctionString( const std::string& name, const Parameters& parameters,
|
||||
const TypeStringVector& typeStringData );
|
||||
|
||||
FunctionString( const std::string& name, Parameters&& parameters,
|
||||
TypeStringVector&& typeStringData );
|
||||
|
||||
const std::string& getName() const;
|
||||
|
||||
const std::vector<std::string>& getParameters() const;
|
||||
const Parameters& getParameters() const;
|
||||
|
||||
bool parameterWasString( Uint32 index ) const;
|
||||
|
||||
@@ -24,8 +39,10 @@ class EE_API FunctionString {
|
||||
|
||||
protected:
|
||||
std::string name;
|
||||
std::vector<std::string> parameters;
|
||||
std::vector<bool> typeStringData;
|
||||
Parameters parameters;
|
||||
TypeStringVector typeStringData;
|
||||
|
||||
template <AllowedFunctionString StringType> static FunctionString parse( StringType function );
|
||||
};
|
||||
|
||||
}} // namespace EE::System
|
||||
|
||||
@@ -15,13 +15,13 @@ class EE_API LuaPattern : public PatternMatcher {
|
||||
static std::string_view getURIPattern();
|
||||
|
||||
static std::string matchesAny( const std::vector<std::string>& stringvec,
|
||||
const std::string_view& pattern );
|
||||
std::string_view pattern );
|
||||
|
||||
static std::string match( const std::string& string, const std::string_view& pattern );
|
||||
static std::string match( std::string_view string, std::string_view pattern );
|
||||
|
||||
static Range firstMatch( const std::string& string, const std::string_view& pattern );
|
||||
static Range firstMatch( std::string_view string, std::string_view pattern );
|
||||
|
||||
static bool hasMatches( const std::string& string, const std::string_view& pattern );
|
||||
static bool hasMatches( std::string_view string, std::string_view pattern );
|
||||
|
||||
LuaPattern( std::string_view pattern, Uint32 options = Options::None );
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ class EE_API UIRichText : public UILayout {
|
||||
|
||||
static UIRichText* NewBr();
|
||||
|
||||
static UIRichText* NewHr();
|
||||
|
||||
static UIRichText* NewDiv() { return UIRichText::NewWithTag( "div" ); };
|
||||
|
||||
static UIRichText* NewPre() { return UIRichText::NewWithTag( "pre" ); };
|
||||
|
||||
@@ -658,6 +658,27 @@ String::HashType String::hash( const String& str ) {
|
||||
str.size() * sizeof( String::StringBaseType ) );
|
||||
}
|
||||
|
||||
String::HashType String::hashToLower( const std::string& str ) {
|
||||
return String::hashToLower( str.c_str(), str.length() );
|
||||
}
|
||||
|
||||
String::HashType String::hashToLower( const std::string_view& str ) {
|
||||
return String::hashToLower( str.data(), str.length() );
|
||||
}
|
||||
|
||||
String::HashType String::hashToLower( const String::View& str ) {
|
||||
String::HashType hash = 5381;
|
||||
for ( size_t i = 0; i < str.size(); ++i ) {
|
||||
int c = str[i];
|
||||
hash = ( ( hash << 5 ) + hash ) + ( c >= 'A' && c <= 'Z' ? c + 32 : c );
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
String::HashType String::hashToLower( const String& str ) {
|
||||
return String::hashToLower( str.view() );
|
||||
}
|
||||
|
||||
bool String::isCharacter( const int& value ) {
|
||||
return ( value >= 32 && value <= 126 ) || ( value >= 161 && value <= 255 ) || ( value == 9 );
|
||||
}
|
||||
@@ -1332,7 +1353,8 @@ bool String::istartsWith( String::View haystack, String::View needle ) {
|
||||
|
||||
bool String::istartsWith( const char* haystack, const char* needle ) {
|
||||
size_t needleLen = strlen( needle );
|
||||
if ( needleLen > strlen( haystack ) ) return false;
|
||||
if ( needleLen > strlen( haystack ) )
|
||||
return false;
|
||||
return std::equal( needle, needle + needleLen, haystack, []( char c1, char c2 ) {
|
||||
return std::tolower( c1 ) == std::tolower( c2 );
|
||||
} );
|
||||
|
||||
@@ -1703,6 +1703,9 @@ void Text::draw( const Float& X, const Float& Y, const Vector2f& scale, const Fl
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mColors.empty() )
|
||||
return;
|
||||
|
||||
Texture* texture = mFontStyleConfig.Font->getTexture( mFontStyleConfig.CharacterSize );
|
||||
if ( !texture )
|
||||
return;
|
||||
|
||||
+84
-66
@@ -1,5 +1,6 @@
|
||||
#include <eepp/system/color.hpp>
|
||||
#include <eepp/system/functionstring.hpp>
|
||||
#include <eepp/system/luapattern.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
@@ -18,6 +19,7 @@ template <typename T> inline T _round( T r ) {
|
||||
} // namespace
|
||||
|
||||
UnorderedMap<std::string, Color> Color::sColors;
|
||||
UnorderedMap<String::HashType, Color> Color::sColorHash;
|
||||
UnorderedMap<String::HashType, Color> Color::sColorMap;
|
||||
|
||||
// Keep the old defined colors
|
||||
@@ -686,10 +688,10 @@ Color Color::fromString( std::string str ) {
|
||||
return Color::Transparent;
|
||||
}
|
||||
} else if ( String::startsWith( str, "@color/" ) ) {
|
||||
std::string colorName( String::toLower( str.substr( 7 ) ) );
|
||||
const auto& it = sColors.find( colorName );
|
||||
std::string_view colorName( std::string_view( str ).substr( 7 ) );
|
||||
const auto& it = sColorHash.find( String::hashToLower( colorName ) );
|
||||
|
||||
if ( it != sColors.end() ) {
|
||||
if ( it != sColorHash.end() ) {
|
||||
return it->second;
|
||||
} else {
|
||||
return Color::Transparent;
|
||||
@@ -701,10 +703,9 @@ Color Color::fromString( std::string str ) {
|
||||
if ( it != sColorMap.end() )
|
||||
return it->second;
|
||||
} else {
|
||||
String::toLowerInPlace( str );
|
||||
const auto& it = sColors.find( str );
|
||||
const auto& it = sColorHash.find( String::hashToLower( str ) );
|
||||
|
||||
if ( it != sColors.end() ) {
|
||||
if ( it != sColorHash.end() ) {
|
||||
return it->second;
|
||||
} else {
|
||||
return Color::Transparent;
|
||||
@@ -714,42 +715,8 @@ Color Color::fromString( std::string str ) {
|
||||
return Color::Transparent;
|
||||
}
|
||||
|
||||
bool Color::isColorString( std::string str, bool searchColorNames ) {
|
||||
if ( str.empty() )
|
||||
return false;
|
||||
|
||||
if ( str[0] == '#' )
|
||||
return validHexColorString( str );
|
||||
|
||||
if ( searchColorNames ) {
|
||||
String::toLowerInPlace( str );
|
||||
initColorMap();
|
||||
auto it = sColorMap.find( String::hash( str ) );
|
||||
if ( it != sColorMap.end() )
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( String::istartsWith( str, "rgb(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "rgba(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "hsl(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "hsla(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "hsv(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "hsva(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "@color/" ) )
|
||||
return true;
|
||||
else if ( sColors.find( str ) != sColors.end() )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Color::isColorString( String::View str, bool searchColorNames ) {
|
||||
template <AllowedFunctionString StringType>
|
||||
bool Color::isColorStringT( StringType str, bool searchColorNames ) {
|
||||
if ( str.empty() )
|
||||
return false;
|
||||
|
||||
@@ -759,43 +726,94 @@ bool Color::isColorString( String::View str, bool searchColorNames ) {
|
||||
if ( searchColorNames && str.size() <= 32 ) {
|
||||
initColorMap();
|
||||
|
||||
String::HashType hash = 5381;
|
||||
for ( size_t i = 0; i < str.size(); ++i )
|
||||
hash = ( ( hash << 5 ) + hash ) + std::tolower( str[i] );
|
||||
auto it = sColorMap.find( hash );
|
||||
if ( it != sColorMap.end() )
|
||||
String::HashType hash = String::hashToLower( str );
|
||||
if ( sColorMap.find( hash ) != sColorMap.end() )
|
||||
return true;
|
||||
|
||||
std::string lowerStr( String( str ).toUtf8() );
|
||||
String::toLowerInPlace( lowerStr );
|
||||
if ( sColors.find( lowerStr ) != sColors.end() )
|
||||
if ( sColorHash.find( hash ) != sColorHash.end() )
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( String::istartsWith( str, "rgb(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "rgba(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "hsl(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "hsla(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "hsv(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "hsva(" ) )
|
||||
return true;
|
||||
else if ( String::istartsWith( str, "@color/" ) )
|
||||
return true;
|
||||
if ( String::istartsWith( str, "@color/" ) ) {
|
||||
std::string utf8Str;
|
||||
if constexpr ( std::is_same_v<StringType, String::View> ) {
|
||||
if ( LuaPattern::hasMatches( String( str ).toUtf8(), "@color/[%w_][%w_-]+" ) ) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ( LuaPattern::hasMatches( str, "@color/[%w_][%w_-]+" ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( str.back() == ')' ) {
|
||||
FunctionString func = FunctionString::parse( str );
|
||||
|
||||
if ( !func.isEmpty() ) {
|
||||
std::string name = func.getName();
|
||||
String::toLowerInPlace( name );
|
||||
|
||||
if ( name == "rgb" || name == "rgba" || name == "hsl" || name == "hsla" ||
|
||||
name == "hsv" || name == "hsva" ) {
|
||||
|
||||
const auto& params = func.getParameters();
|
||||
if ( params.empty() || params.size() > 4 )
|
||||
return false;
|
||||
|
||||
for ( const auto& param : params ) {
|
||||
if ( param.empty() )
|
||||
return false;
|
||||
|
||||
bool hasFunc = false;
|
||||
static const char* allowedFuncs[] = {
|
||||
"var(", "calc(", "min(", "max(", "clamp(", "env(", "color-mix(", "color(" };
|
||||
|
||||
for ( const char* f : allowedFuncs ) {
|
||||
if ( param.find( f ) != std::string::npos ) {
|
||||
hasFunc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hasFunc )
|
||||
continue;
|
||||
|
||||
for ( auto c : param ) {
|
||||
if ( !( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ||
|
||||
( c >= '0' && c <= '9' ) || c == '.' || c == '%' || c == '-' ||
|
||||
c == '+' || c == ' ' || c == '/' ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Color::isColorString( std::string_view str, bool searchColorNames ) {
|
||||
return isColorStringT<std::string_view>( str, searchColorNames );
|
||||
}
|
||||
|
||||
bool Color::isColorString( String::View str, bool searchColorNames ) {
|
||||
return isColorStringT<String::View>( str, searchColorNames );
|
||||
}
|
||||
|
||||
void Color::registerColor( const std::string& name, const Color& color ) {
|
||||
sColors[String::toLower( name )] = color;
|
||||
std::string lowerName( String::toLower( name ) );
|
||||
sColors[lowerName] = color;
|
||||
sColorHash[String::hash( lowerName )] = color;
|
||||
}
|
||||
|
||||
bool Color::unregisterColor( const std::string& name ) {
|
||||
return sColors.erase( String::toLower( name ) ) > 0;
|
||||
std::string lowerName( String::toLower( name ) );
|
||||
sColorHash.erase( String::hash( lowerName ) );
|
||||
return sColors.erase( lowerName ) > 0;
|
||||
}
|
||||
|
||||
bool Color::validHexColorString( String::View hexColor ) {
|
||||
|
||||
@@ -4,32 +4,54 @@
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
FunctionString FunctionString::parse( const std::string& function ) {
|
||||
#include <concepts>
|
||||
#include <string>
|
||||
|
||||
template <AllowedFunctionString StringType>
|
||||
FunctionString FunctionString::parse( StringType function ) {
|
||||
using CharType = typename StringType::value_type;
|
||||
|
||||
size_t funcSep = function.find( '(' );
|
||||
if ( funcSep == std::string::npos )
|
||||
if ( funcSep == StringType::npos )
|
||||
return FunctionString( "", {}, {} );
|
||||
|
||||
std::string funcName = function.substr( 0, funcSep );
|
||||
String::trimInPlace( funcName );
|
||||
auto funcName = String::trim( function.substr( 0, funcSep ) );
|
||||
Parameters funcParameters;
|
||||
TypeStringVector typeStringData;
|
||||
|
||||
std::vector<std::string> funcParameters;
|
||||
std::vector<bool> typeStringData;
|
||||
|
||||
std::string parametersString = function.substr( funcSep + 1 );
|
||||
auto parametersString = function.substr( funcSep + 1 );
|
||||
size_t paramClose = parametersString.find_last_of( ')' );
|
||||
if ( paramClose == std::string::npos )
|
||||
if ( paramClose == StringType::npos )
|
||||
return FunctionString( "", {}, {} );
|
||||
|
||||
parametersString = parametersString.substr( 0, paramClose );
|
||||
|
||||
bool stateParsingString = false;
|
||||
std::string buffer = "";
|
||||
char prevChar = 0;
|
||||
std::basic_string<CharType> buffer;
|
||||
CharType prevChar = 0;
|
||||
|
||||
bool currentParamIsString = false;
|
||||
int parenDepth = 0;
|
||||
|
||||
auto pushBufferToParams = [&]() {
|
||||
if constexpr ( std::same_as<CharType, char> ) {
|
||||
if ( !currentParamIsString )
|
||||
String::trimInPlace( buffer );
|
||||
funcParameters.push_back( buffer );
|
||||
} else {
|
||||
std::string utf8Buffer = String( buffer ).toUtf8();
|
||||
if ( !currentParamIsString )
|
||||
String::trimInPlace( utf8Buffer );
|
||||
funcParameters.push_back( utf8Buffer );
|
||||
}
|
||||
typeStringData.push_back( currentParamIsString );
|
||||
buffer.clear();
|
||||
currentParamIsString = false;
|
||||
};
|
||||
|
||||
for ( size_t i = 0; i < parametersString.length(); ++i ) {
|
||||
char c = parametersString[i];
|
||||
|
||||
CharType c = parametersString[i];
|
||||
|
||||
if ( !stateParsingString ) {
|
||||
if ( c == '(' ) {
|
||||
@@ -37,19 +59,14 @@ FunctionString FunctionString::parse( const std::string& function ) {
|
||||
buffer += c;
|
||||
} else if ( c == ')' ) {
|
||||
if ( parenDepth == 0 )
|
||||
break; // early exit, last ) wasn't the function closure
|
||||
break;
|
||||
if ( parenDepth > 0 )
|
||||
parenDepth--;
|
||||
buffer += c;
|
||||
} else if ( c == ',' ) {
|
||||
if ( parenDepth == 0 ) {
|
||||
if ( !buffer.empty() ) {
|
||||
if ( !currentParamIsString )
|
||||
String::trimInPlace( buffer );
|
||||
funcParameters.push_back( buffer );
|
||||
typeStringData.push_back( currentParamIsString );
|
||||
buffer = "";
|
||||
currentParamIsString = false;
|
||||
pushBufferToParams();
|
||||
}
|
||||
} else {
|
||||
buffer += c;
|
||||
@@ -84,25 +101,39 @@ FunctionString FunctionString::parse( const std::string& function ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( !buffer.empty() ) {
|
||||
if ( !currentParamIsString )
|
||||
String::trimInPlace( buffer );
|
||||
funcParameters.push_back( buffer );
|
||||
typeStringData.push_back( currentParamIsString );
|
||||
}
|
||||
if ( !buffer.empty() )
|
||||
pushBufferToParams();
|
||||
|
||||
return FunctionString( funcName, funcParameters, typeStringData );
|
||||
if constexpr ( std::same_as<StringType, std::string> ) {
|
||||
return FunctionString( std::string{ funcName }, funcParameters, typeStringData );
|
||||
} else {
|
||||
return FunctionString( String( funcName ).toUtf8(), funcParameters, typeStringData );
|
||||
}
|
||||
}
|
||||
|
||||
FunctionString::FunctionString( const std::string& name, const std::vector<std::string>& parameters,
|
||||
const std::vector<bool>& typeStringData ) :
|
||||
FunctionString FunctionString::parse( std::string_view function ) {
|
||||
return parse<std::string_view>( function );
|
||||
}
|
||||
|
||||
FunctionString FunctionString::parse( String::View function ) {
|
||||
return parse<String::View>( function );
|
||||
}
|
||||
|
||||
FunctionString::FunctionString( const std::string& name, const Parameters& parameters,
|
||||
const TypeStringVector& typeStringData ) :
|
||||
name( name ), parameters( parameters ), typeStringData( typeStringData ) {}
|
||||
|
||||
FunctionString::FunctionString( const std::string& name, Parameters&& parameters,
|
||||
TypeStringVector&& typeStringData ) :
|
||||
name( name ),
|
||||
parameters( std::move( parameters ) ),
|
||||
typeStringData( std::move( typeStringData ) ) {}
|
||||
|
||||
const std::string& FunctionString::getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& FunctionString::getParameters() const {
|
||||
const FunctionString::Parameters& FunctionString::getParameters() const {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,16 +35,16 @@ std::string_view LuaPattern::getURIPattern() {
|
||||
return "%w+://[%w_.~!*:@&+$/?%%#-]-%w[-.%w]*%.%w%w%w?%w?:?%d*/?[%w_.~!*:@&+$/?%%#=-]*"sv;
|
||||
}
|
||||
|
||||
std::string LuaPattern::match( const std::string& string, const std::string_view& pattern ) {
|
||||
std::string LuaPattern::match( std::string_view string, std::string_view pattern ) {
|
||||
LuaPattern matcher( pattern );
|
||||
int start = 0, end = 0;
|
||||
if ( matcher.find( string, start, end ) )
|
||||
return string.substr( start, end - start );
|
||||
if ( matcher.find( string.data(), start, end, 0, string.size() ) )
|
||||
return std::string{ string.substr( start, end - start ) };
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string LuaPattern::matchesAny( const std::vector<std::string>& stringvec,
|
||||
const std::string_view& pattern ) {
|
||||
std::string_view pattern ) {
|
||||
LuaPattern matcher( pattern );
|
||||
int start = 0, end = 0;
|
||||
for ( const auto& str : stringvec ) {
|
||||
@@ -55,16 +55,15 @@ std::string LuaPattern::matchesAny( const std::vector<std::string>& stringvec,
|
||||
return "";
|
||||
}
|
||||
|
||||
PatternMatcher::Range LuaPattern::firstMatch( const std::string& string,
|
||||
const std::string_view& pattern ) {
|
||||
PatternMatcher::Range LuaPattern::firstMatch( std::string_view string, std::string_view pattern ) {
|
||||
LuaPattern matcher( pattern );
|
||||
int start = 0, end = 0;
|
||||
if ( matcher.find( string, start, end ) )
|
||||
if ( matcher.find( string.data(), start, end, 0, string.size() ) )
|
||||
return { start, end };
|
||||
return { -1, -1 };
|
||||
}
|
||||
|
||||
bool LuaPattern::hasMatches( const std::string& string, const std::string_view& pattern ) {
|
||||
bool LuaPattern::hasMatches( std::string_view string, std::string_view pattern ) {
|
||||
return LuaPattern::firstMatch( string, pattern ).isValid();
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
|
||||
RectangleDrawable* drawable = RectangleDrawable::New();
|
||||
RectColors rectColors;
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
const auto& params( functionType.getParameters() );
|
||||
|
||||
if ( Color::isColorString( params.at( 0 ) ) && params.size() >= 2 ) {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 0 ) );
|
||||
@@ -112,7 +112,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
|
||||
CircleDrawable* drawable = CircleDrawable::New();
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
const auto& params( functionType.getParameters() );
|
||||
|
||||
CSS::StyleSheetLength length( params[0] );
|
||||
drawable->setRadius( node->convertLength( length, size.getWidth() / 2.f ) );
|
||||
@@ -145,7 +145,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
RectColors rectColors;
|
||||
std::vector<Color> colors;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
const auto& params( functionType.getParameters() );
|
||||
|
||||
for ( size_t i = 0; i < params.size(); i++ ) {
|
||||
std::string param( String::toLower( params[i] ) );
|
||||
@@ -207,7 +207,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
std::vector<Color> colors;
|
||||
std::vector<Vector2f> vertices;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
const auto& params( functionType.getParameters() );
|
||||
Float lineWidth = PixelDensity::dpToPx( 1.f );
|
||||
|
||||
for ( size_t i = 0; i < params.size(); i++ ) {
|
||||
@@ -277,7 +277,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
std::vector<Color> colors;
|
||||
std::vector<Vector2f> vertices;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
const auto& params( functionType.getParameters() );
|
||||
Float lineWidth = PixelDensity::dpToPx( 1.f );
|
||||
|
||||
for ( size_t i = 0; i < params.size(); i++ ) {
|
||||
|
||||
@@ -662,14 +662,14 @@ void TextDocument::guessIndentType() {
|
||||
int guessCountdown = 10;
|
||||
for ( size_t i = start; i < end; i++ ) {
|
||||
const String& text = mLines[i].getText();
|
||||
std::string match =
|
||||
LuaPattern::match( text.size() > 128 ? text.substr( 0, 12 ) : text, "^ +" );
|
||||
std::string match = LuaPattern::match(
|
||||
text.size() > 128 ? text.substr( 0, 128 ).toUtf8() : text.toUtf8(), "^ +" );
|
||||
if ( !match.empty() ) {
|
||||
guessSpaces++;
|
||||
guessWidth[match.size()]++;
|
||||
guessCountdown--;
|
||||
} else {
|
||||
match = LuaPattern::match( mLines[i].getText(), "^\t+" );
|
||||
match = LuaPattern::match( mLines[i].getText().toUtf8(), "^\t+" );
|
||||
if ( !match.empty() ) {
|
||||
guessTabs++;
|
||||
guessCountdown--;
|
||||
|
||||
@@ -312,6 +312,10 @@ void UINode::setMaxSizeEq( const std::string& maxWidthEq, const std::string& max
|
||||
if ( mMaxWidthEq != maxWidthEq || mMaxHeightEq != maxHeightEq ) {
|
||||
mMaxWidthEq = maxWidthEq;
|
||||
mMaxHeightEq = maxHeightEq;
|
||||
if ( mMaxWidthEq == "none" )
|
||||
mMaxWidthEq.clear();
|
||||
if ( mMaxHeightEq == "none" )
|
||||
mMaxHeightEq.clear();
|
||||
setSize( mDpSize );
|
||||
}
|
||||
}
|
||||
@@ -319,6 +323,8 @@ void UINode::setMaxSizeEq( const std::string& maxWidthEq, const std::string& max
|
||||
void UINode::setMaxWidthEq( const std::string& maxWidthEq ) {
|
||||
if ( mMaxWidthEq != maxWidthEq ) {
|
||||
mMaxWidthEq = maxWidthEq;
|
||||
if ( mMaxWidthEq == "none" )
|
||||
mMaxWidthEq.clear();
|
||||
onSizeChange();
|
||||
}
|
||||
}
|
||||
@@ -330,6 +336,8 @@ const std::string& UINode::getMaxHeightEq() const {
|
||||
void UINode::setMaxHeightEq( const std::string& maxHeightEq ) {
|
||||
if ( mMaxHeightEq != maxHeightEq ) {
|
||||
mMaxHeightEq = maxHeightEq;
|
||||
if ( mMaxHeightEq == "none" )
|
||||
mMaxHeightEq.clear();
|
||||
onSizeChange();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ namespace EE { namespace UI {
|
||||
|
||||
class UILineBreak : public UIRichText {
|
||||
public:
|
||||
static UILineBreak* New() { return eeNew( UILineBreak, () ); }
|
||||
static UILineBreak* New( const std::string& tag = "" ) { return eeNew( UILineBreak, ( tag ) ); }
|
||||
|
||||
UILineBreak() : UIRichText( "br " ) {}
|
||||
UILineBreak( const std::string& tag = "br" ) : UIRichText( tag ) {}
|
||||
|
||||
virtual Uint32 getType() const { return UI_TYPE_BR; }
|
||||
|
||||
@@ -32,6 +32,10 @@ UIRichText* UIRichText::NewBr() {
|
||||
return UILineBreak::New();
|
||||
};
|
||||
|
||||
UIRichText* UIRichText::NewHr() {
|
||||
return UILineBreak::New( "hr" );
|
||||
};
|
||||
|
||||
UIRichText* UIRichText::New() {
|
||||
return eeNew( UIRichText, () );
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ void UIWidgetCreator::createBaseWidgetList() {
|
||||
registeredWidget["h5"] = UIRichText::NewH5;
|
||||
registeredWidget["h6"] = UIRichText::NewH6;
|
||||
registeredWidget["br"] = UIRichText::NewBr;
|
||||
registeredWidget["hr"] = UIRichText::NewHr;
|
||||
registeredWidget["ul"] = [] { return UILinearLayout::NewVerticalWidthMatchParent( "ul" ); };
|
||||
registeredWidget["ol"] = [] { return UILinearLayout::NewVerticalWidthMatchParent( "ol" ); };
|
||||
registeredWidget["li"] = UIRichText::NewListItem;
|
||||
|
||||
@@ -14,6 +14,9 @@ EE_MAIN_FUNC int main( int argc, char** argv ) {
|
||||
{ 'c', "prefers-color-scheme" } );
|
||||
args::Flag hnDark( parser, "hn-dark",
|
||||
"Force a custom CSS style for Hacker News site to be dark.", { "hn-dark" } );
|
||||
args::Flag benchmarkMode( parser, "benchmark-mode",
|
||||
"Render as much as possible to measure the rendering performance.",
|
||||
{ "benchmark-mode" } );
|
||||
|
||||
try {
|
||||
parser.ParseCLI( Sys::parseArguments( argc, argv ) );
|
||||
@@ -30,7 +33,10 @@ EE_MAIN_FUNC int main( int argc, char** argv ) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
UIApplication app( { 1280, 720, "eepp - UI HTML Example" } );
|
||||
UIApplication app(
|
||||
{ 1280, 720, "eepp - UI HTML Example" }, UIApplication::Settings(),
|
||||
ContextSettings(
|
||||
false, benchmarkMode.Get() ? 0 : ContextSettings::FrameRateLimitScreenRefreshRate ) );
|
||||
|
||||
Log::instance()->setLogLevelThreshold( LogLevel::Debug );
|
||||
Log::instance()->setLogToStdOut( true );
|
||||
@@ -223,5 +229,20 @@ EE_MAIN_FUNC int main( int argc, char** argv ) {
|
||||
}
|
||||
} );
|
||||
|
||||
if ( benchmarkMode.Get() ) {
|
||||
app.getWindow()->runMainLoop( [&app]() {
|
||||
app.getWindow()->getInput()->update();
|
||||
SceneManager::instance()->update();
|
||||
app.getWindow()->clear();
|
||||
SceneManager::instance()->draw();
|
||||
auto tm = app.getUI()->getUIThemeManager();
|
||||
String fps( String::format( "FPS: %d", app.getWindow()->getFPS() ) );
|
||||
Text::draw( fps, Vector2f::Zero, tm->getDefaultFont(), tm->getDefaultFontSize(),
|
||||
Color::magenta, 0, 0, Color::Black, Color::Black, Vector2f{ 1, 1 }, 4,
|
||||
TextHints::AllAscii );
|
||||
app.getWindow()->display();
|
||||
} );
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
return app.run();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user