add is italic check for font file

This commit is contained in:
Filip Sykala 2022-01-06 11:29:16 +01:00
parent 82ee1c5e4a
commit b1b8eee3c9
4 changed files with 82 additions and 81 deletions
src/libslic3r

View file

@ -45,12 +45,12 @@ std::optional<stbtt_fontinfo> Private::load_font_info(const Emboss::Font &font)
{
int font_offset = stbtt_GetFontOffsetForIndex(font.buffer.data(), font.index);
if (font_offset < 0) {
std::cerr << "Font index("<<font.index<<") doesn't exist.";
std::cerr << "Font index("<<font.index<<") doesn't exist." << std::endl;
return {};
}
stbtt_fontinfo font_info;
if (stbtt_InitFont(&font_info, font.buffer.data(), font_offset) == 0) {
std::cerr << "Can't initialize font.";
std::cerr << "Can't initialize font." << std::endl;
return {};
}
return font_info;
@ -437,7 +437,7 @@ std::optional<Emboss::Font> Emboss::load_font(std::vector<unsigned char> data)
--index; // last one is bad
// at least one font must be inside collection
if (index < 1) {
std::cerr << "There is no font collection inside data.";
std::cerr << "There is no font collection inside data." << std::endl;
return {};
}
// select default font on index 0
@ -457,18 +457,18 @@ std::optional<Emboss::Font> Emboss::load_font(const char *file_path)
{
FILE *file = fopen(file_path, "rb");
if (file == nullptr) {
std::cerr << "Couldn't open " << file_path << " for reading.";
std::cerr << "Couldn't open " << file_path << " for reading." << std::endl;
return {};
}
// find size of file
if (fseek(file, 0L, SEEK_END) != 0) {
std::cerr << "Couldn't fseek file " << file_path << " for size measure.";
std::cerr << "Couldn't fseek file " << file_path << " for size measure." << std::endl;
return {};
}
size_t size = ftell(file);
if (size == 0) {
std::cerr << "Size of font file is zero. Can't read.";
std::cerr << "Size of font file is zero. Can't read." << std::endl;
return {};
}
rewind(file);
@ -476,7 +476,7 @@ std::optional<Emboss::Font> Emboss::load_font(const char *file_path)
std::vector<unsigned char> buffer(size);
size_t count_loaded_bytes = fread((void *) &buffer.front(), 1, size, file);
if (count_loaded_bytes != size) {
std::cerr << "Different loaded(from file) data size.";
std::cerr << "Different loaded(from file) data size." << std::endl;
return {};
}
return load_font(std::move(buffer));
@ -488,7 +488,7 @@ std::optional<Emboss::Font> Emboss::load_font(HFONT hfont)
{
HDC hdc = ::CreateCompatibleDC(NULL);
if (hdc == NULL) {
std::cerr << "Can't create HDC by CreateCompatibleDC(NULL).";
std::cerr << "Can't create HDC by CreateCompatibleDC(NULL)." << std::endl;
return {};
}
@ -506,7 +506,7 @@ std::optional<Emboss::Font> Emboss::load_font(HFONT hfont)
}
if (size == 0 || size == GDI_ERROR) {
std::cerr << "HFONT doesn't have size.";
std::cerr << "HFONT doesn't have size." << std::endl;
::DeleteDC(hdc);
return {};
}
@ -515,7 +515,7 @@ std::optional<Emboss::Font> Emboss::load_font(HFONT hfont)
size_t loaded_size = ::GetFontData(hdc, dwTable, dwOffset, buffer.data(), size);
::DeleteDC(hdc);
if (size != loaded_size) {
std::cerr << "Different loaded(from HFONT) data size.";
std::cerr << "Different loaded(from HFONT) data size." << std::endl;
return {};
}
@ -601,6 +601,43 @@ ExPolygons Emboss::text2shapes(Font & font,
return Private::dilate_to_unique_points(result);
}
bool Emboss::is_italic(Font &font) {
std::optional<stbtt_fontinfo> font_info_opt =
Private::load_font_info(font);
if (!font_info_opt.has_value()) return false;
stbtt_fontinfo *info = &(*font_info_opt);
// https://docs.microsoft.com/cs-cz/typography/opentype/spec/name
// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html
// 2 ==> Style / Subfamily name
int name_id = 2;
int length;
const char* value = stbtt_GetFontNameString(info, &length,
STBTT_PLATFORM_ID_MICROSOFT,
STBTT_MS_EID_UNICODE_BMP,
STBTT_MS_LANG_ENGLISH,
name_id);
// value is big endian utf-16 i need extract only normal chars
std::string value_str;
value_str.reserve(length / 2);
for (int i = 1; i < length; i += 2)
value_str.push_back(value[i]);
// lower case
std::transform(value_str.begin(), value_str.end(), value_str.begin(),
[](unsigned char c) { return std::tolower(c); });
const std::vector<std::string> italics({"italic", "oblique"});
for (const std::string &it : italics) {
if (value_str.find(it) != std::string::npos) {
return true;
}
}
return false;
}
indexed_triangle_set Emboss::polygons2model(const ExPolygons &shape2d,
const IProject &projection)
{