Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit04d26b2

Browse files
committed
Simplify/improve error reporting from ft2font.
Provide a simple macro to call a FreeType function and throwan exception if an error is returned, while also including thesource file and line location for the error. For example, trying`FT2Font(open("pyproject.toml", "rb"))` now raises "FT_Open_Face(ft2font.cpp line 220) failed with error 0x2: unknown file format"instead of "Can not load face (unknown file format; error code 0x2)"
1 parentdef8fa4 commit04d26b2

File tree

2 files changed

+55
-84
lines changed

2 files changed

+55
-84
lines changed

‎src/ft2font.cpp

Lines changed: 27 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,6 @@
4343

4444
FT_Library _ft2Library;
4545

46-
// FreeType error codes; loaded as per fterror.h.
47-
staticcharconst*ft_error_string(FT_Error error) {
48-
#undef __FTERRORS_H__
49-
#defineFT_ERROR_START_LISTswitch (error) {
50-
#defineFT_ERRORDEF( e, v, s)case v:return s;
51-
#defineFT_ERROR_END_LISTdefault:returnNULL; }
52-
#include FT_ERRORS_H
53-
}
54-
55-
voidthrow_ft_error(std::string message, FT_Error error) {
56-
charconst* s =ft_error_string(error);
57-
std::ostringstreamos("");
58-
if (s) {
59-
os << message <<" (" << s <<"; error code 0x" << std::hex << error <<")";
60-
}else {// Should not occur, but don't add another error from failed lookup.
61-
os << message <<" (error code 0x" << std::hex << error <<")";
62-
}
63-
throwstd::runtime_error(os.str());
64-
}
65-
6646
FT2Image::FT2Image(unsignedlong width,unsignedlong height)
6747
: m_buffer((unsignedchar *)calloc(width * height,1)), m_width(width), m_height(height)
6848
{
@@ -237,26 +217,16 @@ FT2Font::FT2Font(FT_Open_Args &open_args,
237217
kerning_factor(0)
238218
{
239219
clear();
240-
241-
FT_Error error =FT_Open_Face(_ft2Library, &open_args,0, &face);
242-
if (error) {
243-
throw_ft_error("Can not load face", error);
244-
}
245-
246-
// set a default fontsize 12 pt at 72dpi
247-
error =FT_Set_Char_Size(face,12 *64,0,72 * (unsignedint)hinting_factor,72);
248-
if (error) {
249-
FT_Done_Face(face);
250-
throw_ft_error("Could not set the fontsize", error);
251-
}
252-
220+
FT_CHECK(FT_Open_Face, _ft2Library, &open_args,0, &face);
253221
if (open_args.stream !=nullptr) {
254222
face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
255223
}
256-
257-
FT_Matrix transform = {65536 / hinting_factor,0,0,65536 };
258-
FT_Set_Transform(face, &transform,nullptr);
259-
224+
try {
225+
set_size(12.,72.);// Set a default fontsize 12 pt at 72dpi.
226+
}catch (...) {
227+
FT_Done_Face(face);
228+
throw;
229+
}
260230
// Set fallbacks
261231
std::copy(fallback_list.begin(), fallback_list.end(),std::back_inserter(fallbacks));
262232
}
@@ -293,11 +263,9 @@ void FT2Font::clear()
293263

294264
voidFT2Font::set_size(double ptsize,double dpi)
295265
{
296-
FT_Error error =FT_Set_Char_Size(
266+
FT_CHECK(
267+
FT_Set_Char_Size,
297268
face, (FT_F26Dot6)(ptsize *64),0, (FT_UInt)(dpi * hinting_factor), (FT_UInt)dpi);
298-
if (error) {
299-
throw_ft_error("Could not set the fontsize", error);
300-
}
301269
FT_Matrix transform = {65536 / hinting_factor,0,0,65536 };
302270
FT_Set_Transform(face, &transform,nullptr);
303271

@@ -311,17 +279,12 @@ void FT2Font::set_charmap(int i)
311279
if (i >= face->num_charmaps) {
312280
throwstd::runtime_error("i exceeds the available number of char maps");
313281
}
314-
FT_CharMap charmap = face->charmaps[i];
315-
if (FT_Error error =FT_Set_Charmap(face, charmap)) {
316-
throw_ft_error("Could not set the charmap", error);
317-
}
282+
FT_CHECK(FT_Set_Charmap, face, face->charmaps[i]);
318283
}
319284

320285
voidFT2Font::select_charmap(unsignedlong i)
321286
{
322-
if (FT_Error error =FT_Select_Charmap(face, (FT_Encoding)i)) {
323-
throw_ft_error("Could not set the charmap", error);
324-
}
287+
FT_CHECK(FT_Select_Charmap, face, (FT_Encoding)i);
325288
}
326289

327290
intFT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_Kerning_Mode mode,
@@ -477,10 +440,10 @@ void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool
477440
if (!was_found) {
478441
ft_glyph_warn(charcode, glyph_seen_fonts);
479442
if (charcode_error) {
480-
throw_ft_error("Could not loadcharcode", charcode_error);
443+
THROW_FT_ERROR("charcode loading", charcode_error);
481444
}
482445
elseif (glyph_error) {
483-
throw_ft_error("Could not loadcharcode", glyph_error);
446+
THROW_FT_ERROR("charcode loading", glyph_error);
484447
}
485448
}elseif (ft_object_with_glyph->warn_if_used) {
486449
ft_glyph_warn(charcode, glyph_seen_fonts);
@@ -494,13 +457,9 @@ void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool
494457
glyph_seen_fonts.insert((face !=nullptr)?face->family_name:nullptr);
495458
ft_glyph_warn((FT_ULong)charcode, glyph_seen_fonts);
496459
}
497-
if (FT_Error error =FT_Load_Glyph(face, glyph_index, flags)) {
498-
throw_ft_error("Could not load charcode", error);
499-
}
460+
FT_CHECK(FT_Load_Glyph, face, glyph_index, flags);
500461
FT_Glyph thisGlyph;
501-
if (FT_Error error =FT_Get_Glyph(face->glyph, &thisGlyph)) {
502-
throw_ft_error("Could not get glyph", error);
503-
}
462+
FT_CHECK(FT_Get_Glyph, face->glyph, &thisGlyph);
504463
glyphs.push_back(thisGlyph);
505464
}
506465
}
@@ -600,13 +559,9 @@ void FT2Font::load_glyph(FT_UInt glyph_index,
600559

601560
voidFT2Font::load_glyph(FT_UInt glyph_index, FT_Int32 flags)
602561
{
603-
if (FT_Error error =FT_Load_Glyph(face, glyph_index, flags)) {
604-
throw_ft_error("Could not load glyph", error);
605-
}
562+
FT_CHECK(FT_Load_Glyph, face, glyph_index, flags);
606563
FT_Glyph thisGlyph;
607-
if (FT_Error error =FT_Get_Glyph(face->glyph, &thisGlyph)) {
608-
throw_ft_error("Could not get glyph", error);
609-
}
564+
FT_CHECK(FT_Get_Glyph, face->glyph, &thisGlyph);
610565
glyphs.push_back(thisGlyph);
611566
}
612567

@@ -651,13 +606,10 @@ void FT2Font::draw_glyphs_to_bitmap(bool antialiased)
651606
image = py::array_t<uint8_t>{{height, width}};
652607
std::memset(image.mutable_data(0),0, image.nbytes());
653608

654-
for (auto & glyph : glyphs) {
655-
FT_Error error =FT_Glyph_To_Bitmap(
609+
for (auto & glyph: glyphs) {
610+
FT_CHECK(
611+
FT_Glyph_To_Bitmap,
656612
&glyph, antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,nullptr,1);
657-
if (error) {
658-
throw_ft_error("Could not convert glyph to bitmap", error);
659-
}
660-
661613
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
662614
// now, draw to our target surface (convert position)
663615

@@ -681,16 +633,12 @@ void FT2Font::draw_glyph_to_bitmap(
681633
throwstd::runtime_error("glyph num is out of range");
682634
}
683635

684-
FT_Error error =FT_Glyph_To_Bitmap(
685-
&glyphs[glyphInd],
686-
antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
687-
&sub_offset,// additional translation
688-
1// destroy image
689-
);
690-
if (error) {
691-
throw_ft_error("Could not convert glyph to bitmap", error);
692-
}
693-
636+
FT_CHECK(
637+
FT_Glyph_To_Bitmap,
638+
&glyphs[glyphInd],
639+
antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
640+
&sub_offset,// additional translation
641+
1);// destroy image
694642
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[glyphInd];
695643

696644
draw_bitmap(im, &bitmap->bitmap, x + bitmap->left, y);
@@ -715,9 +663,7 @@ void FT2Font::get_glyph_name(unsigned int glyph_number, std::string &buffer,
715663
throwstd::runtime_error("Failed to convert glyph to standard name");
716664
}
717665
}else {
718-
if (FT_Error error =FT_Get_Glyph_Name(face, glyph_number, buffer.data(), buffer.size())) {
719-
throw_ft_error("Could not get glyph names", error);
720-
}
666+
FT_CHECK(FT_Get_Glyph_Name, face, glyph_number, buffer.data(), buffer.size());
721667
auto len = buffer.find('\0');
722668
if (len != buffer.npos) {
723669
buffer.resize(len);

‎src/ft2font.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef MPL_FT2FONT_H
77
#defineMPL_FT2FONT_H
88

9+
#include<filesystem>
910
#include<set>
1011
#include<string>
1112
#include<string_view>
@@ -26,12 +27,36 @@ extern "C" {
2627
#include<pybind11/numpy.h>
2728
namespacepy= pybind11;
2829

29-
/*
30-
By definition, FT_FIXED as 2 16bit values stored in a single long.
31-
*/
30+
// By definition, FT_FIXED as 2 16bit values stored in a single long.
3231
#defineFIXED_MAJOR(val) (signedshort)((val &0xffff0000) >>16)
3332
#defineFIXED_MINOR(val) (unsignedshort)(val &0xffff)
3433

34+
// Error handling (error codes are loaded as described in fterror.h).
35+
inlinecharconst*ft_error_string(FT_Error error) {
36+
#undef __FTERRORS_H__
37+
#defineFT_ERROR_START_LISTswitch (error) {
38+
#defineFT_ERRORDEF( e, v, s)case v:return s;
39+
#defineFT_ERROR_END_LISTdefault:returnNULL; }
40+
#include FT_ERRORS_H
41+
}
42+
43+
// No more than 16 hex digits + "0x" + null byte for a 64-bit int error.
44+
#defineTHROW_FT_ERROR(name, err) { \
45+
char buf[20] = {0}; \
46+
sprintf(buf,"%#04x", err); \
47+
throw std::runtime_error{ \
48+
name" (" \
49+
+std::filesystem::path(__FILE__).filename().string() \
50+
+" line" +std::to_string(__LINE__) +") failed with error" \
51+
+ std::string{buf} +":" + std::string{ft_error_string(err)}}; \
52+
} (void)0
53+
54+
#defineFT_CHECK(func, ...) { \
55+
if (autoconst& error_ =func(__VA_ARGS__)) { \
56+
THROW_FT_ERROR(#func, error_); \
57+
} \
58+
} (void)0
59+
3560
// the FreeType string rendered into a width, height buffer
3661
classFT2Image
3762
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp