Fix font pattern matching and add ListFontsWithInfo
This commit is contained in:
parent
ccb2507ac3
commit
7018e1e17d
|
|
@ -2333,6 +2333,9 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
case X_ListFonts:
|
case X_ListFonts:
|
||||||
TRY(list_fonts(client_info, packet));
|
TRY(list_fonts(client_info, packet));
|
||||||
break;
|
break;
|
||||||
|
case X_ListFontsWithInfo:
|
||||||
|
TRY(list_fonts_with_info(client_info, packet));
|
||||||
|
break;
|
||||||
case X_GetInputFocus:
|
case X_GetInputFocus:
|
||||||
{
|
{
|
||||||
dprintln("GetInputFocus");
|
dprintln("GetInputFocus");
|
||||||
|
|
|
||||||
109
xbanan/Font.cpp
109
xbanan/Font.cpp
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -465,40 +466,38 @@ static void initialize_fonts()
|
||||||
printf("found %zu fonts and aliases\n", s_available_fonts.size());
|
printf("found %zu fonts and aliases\n", s_available_fonts.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool matches_pattern(const char* pattern, const char* string)
|
static bool matches_pattern(BAN::StringView pattern, BAN::StringView string)
|
||||||
{
|
{
|
||||||
while (*pattern)
|
while (!pattern.empty())
|
||||||
{
|
{
|
||||||
switch (*pattern)
|
switch (pattern.front())
|
||||||
{
|
{
|
||||||
case '*':
|
case '*':
|
||||||
{
|
{
|
||||||
const char* ptr = string + strlen(string);
|
ssize_t len = string.size();
|
||||||
while (ptr >= string)
|
while (len >= 0)
|
||||||
if (matches_pattern(pattern + 1, ptr--) == 0)
|
if (matches_pattern(pattern.substring(1), string.substring(len--)))
|
||||||
return 0;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case '?':
|
case '?':
|
||||||
{
|
{
|
||||||
if (*string == '\0')
|
if (string.empty())
|
||||||
return false;
|
return false;
|
||||||
pattern++;
|
pattern = pattern.substring(1);
|
||||||
string++;
|
string = string.substring(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*pattern == '\0')
|
if (string.empty() || tolower(pattern.front()) != tolower(string.front()))
|
||||||
break;
|
|
||||||
|
|
||||||
if (*pattern != *string)
|
|
||||||
return false;
|
return false;
|
||||||
pattern++;
|
|
||||||
string++;
|
pattern = pattern.substring(1);
|
||||||
|
string = string.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *string ? false : true;
|
return string.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static BAN::ErrorOr<BAN::RefPtr<PCFFont>> get_fontable(Client& client_info, CARD32 fid, BYTE opcode)
|
static BAN::ErrorOr<BAN::RefPtr<PCFFont>> get_fontable(Client& client_info, CARD32 fid, BYTE opcode)
|
||||||
|
|
@ -535,7 +534,7 @@ BAN::ErrorOr<void> open_font(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
for (const auto& [name, path] : s_available_fonts)
|
for (const auto& [name, path] : s_available_fonts)
|
||||||
{
|
{
|
||||||
if (!matches_pattern(pattern.data(), name.data()))
|
if (!matches_pattern(pattern, name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BAN::RefPtr<PCFFont> font;
|
BAN::RefPtr<PCFFont> font;
|
||||||
|
|
@ -640,7 +639,7 @@ BAN::ErrorOr<void> list_fonts(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
{
|
{
|
||||||
if (nfonts == request.maxNames)
|
if (nfonts == request.maxNames)
|
||||||
break;
|
break;
|
||||||
if (!matches_pattern(pattern.data(), name.data()))
|
if (!matches_pattern(pattern, name))
|
||||||
continue;
|
continue;
|
||||||
TRY(encode<BYTE>(result, name.size()));
|
TRY(encode<BYTE>(result, name.size()));
|
||||||
TRY(encode(result, name));
|
TRY(encode(result, name));
|
||||||
|
|
@ -654,7 +653,79 @@ BAN::ErrorOr<void> list_fonts(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
.nFonts = nfonts,
|
.nFonts = nfonts,
|
||||||
};
|
};
|
||||||
TRY(encode(client_info.output_buffer, reply));
|
TRY(encode(client_info.output_buffer, reply));
|
||||||
|
|
||||||
TRY(encode(client_info.output_buffer, result));
|
TRY(encode(client_info.output_buffer, result));
|
||||||
|
for (size_t i = 0; (result.size() + i) % 4; i++)
|
||||||
|
TRY(encode(client_info.output_buffer, '\0'));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> list_fonts_with_info(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
{
|
||||||
|
auto request = decode<xListFontsWithInfoReq>(packet).value();
|
||||||
|
|
||||||
|
BAN::String pattern = BAN::StringView((char*)packet.data(), request.nbytes);
|
||||||
|
|
||||||
|
dprintln("ListFontsWithInfo");
|
||||||
|
dprintln(" maxNames: {}", request.maxNames);
|
||||||
|
dprintln(" pattern: {}", pattern);
|
||||||
|
|
||||||
|
size_t nfonts = 0;
|
||||||
|
for (const auto& [name, path] : s_available_fonts)
|
||||||
|
{
|
||||||
|
if (nfonts == request.maxNames)
|
||||||
|
break;
|
||||||
|
if (!matches_pattern(pattern, name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BAN::RefPtr<PCFFont> font;
|
||||||
|
if (auto it = s_loaded_fonts.find(path); it != s_loaded_fonts.end())
|
||||||
|
font = it->value.lock();
|
||||||
|
|
||||||
|
if (!font)
|
||||||
|
{
|
||||||
|
auto font_or_error = parse_font(path);
|
||||||
|
if (font_or_error.is_error())
|
||||||
|
continue;
|
||||||
|
font = font_or_error.release_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
xListFontsWithInfoReply reply {
|
||||||
|
.type = X_Reply,
|
||||||
|
.nameLength = static_cast<BYTE>(name.size()),
|
||||||
|
.sequenceNumber = client_info.sequence,
|
||||||
|
.length = static_cast<CARD32>(7 + (name.size() + 3) / 4),
|
||||||
|
.minBounds = font->min_bounds,
|
||||||
|
.maxBounds = font->max_bounds,
|
||||||
|
.minCharOrByte2 = font->min_char_or_byte2,
|
||||||
|
.maxCharOrByte2 = font->max_char_or_byte2,
|
||||||
|
.defaultChar = font->default_char,
|
||||||
|
.nFontProps = 0, // TODO
|
||||||
|
.drawDirection = FontLeftToRight,
|
||||||
|
.minByte1 = font->min_byte1,
|
||||||
|
.maxByte1 = font->max_byte1,
|
||||||
|
.allCharsExist = font->all_chars_exist,
|
||||||
|
.fontAscent = font->font_ascent,
|
||||||
|
.fontDescent = font->font_descent,
|
||||||
|
.nReplies = 1,
|
||||||
|
};
|
||||||
|
TRY(encode(client_info.output_buffer, reply));
|
||||||
|
|
||||||
|
TRY(encode(client_info.output_buffer, name));
|
||||||
|
for (size_t i = 0; (name.size() + i) % 4; i++)
|
||||||
|
TRY(encode(client_info.output_buffer, '\0'));
|
||||||
|
|
||||||
|
nfonts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
xListFontsWithInfoReply reply {
|
||||||
|
.type = X_Reply,
|
||||||
|
.nameLength = 0,
|
||||||
|
.sequenceNumber = client_info.sequence,
|
||||||
|
.length = 7,
|
||||||
|
};
|
||||||
|
TRY(encode(client_info.output_buffer, reply));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ BAN::ErrorOr<void> open_font(Client& client_info, BAN::ConstByteSpan packet);
|
||||||
BAN::ErrorOr<void> close_font(Client& client_info, BAN::ConstByteSpan packet);
|
BAN::ErrorOr<void> close_font(Client& client_info, BAN::ConstByteSpan packet);
|
||||||
BAN::ErrorOr<void> query_font(Client& client_info, BAN::ConstByteSpan packet);
|
BAN::ErrorOr<void> query_font(Client& client_info, BAN::ConstByteSpan packet);
|
||||||
BAN::ErrorOr<void> list_fonts(Client& client_info, BAN::ConstByteSpan packet);
|
BAN::ErrorOr<void> list_fonts(Client& client_info, BAN::ConstByteSpan packet);
|
||||||
|
BAN::ErrorOr<void> list_fonts_with_info(Client& client_info, BAN::ConstByteSpan packet);
|
||||||
BAN::ErrorOr<void> poly_text(Client& client_info, BAN::ConstByteSpan packet, bool wide);
|
BAN::ErrorOr<void> poly_text(Client& client_info, BAN::ConstByteSpan packet, bool wide);
|
||||||
BAN::ErrorOr<void> image_text(Client& client_info, BAN::ConstByteSpan packet, bool wide);
|
BAN::ErrorOr<void> image_text(Client& client_info, BAN::ConstByteSpan packet, bool wide);
|
||||||
BAN::ErrorOr<void> create_glyph_cursor(Client& client_info, BAN::ConstByteSpan packet);
|
BAN::ErrorOr<void> create_glyph_cursor(Client& client_info, BAN::ConstByteSpan packet);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue