Skip to content

Commit 38ddbb5

Browse files
authored
fix: Use FontMatrix to scale Type3 font metrics (#113)
Signed-off-by: David Huggins-Daines <[email protected]>
1 parent 514b6fe commit 38ddbb5

File tree

8 files changed

+328126
-51
lines changed

8 files changed

+328126
-51
lines changed

src/v2/pdf_resources/page_font.h

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ namespace pdflib
2323

2424
nlohmann::json get();
2525

26-
double get_unit();
27-
2826
std::string get_encoding_name();
2927
font_encoding_name get_encoding();
3028

@@ -63,6 +61,7 @@ namespace pdflib
6361
void init_base_font();
6462
void init_font_name();
6563
void init_font_bbox();
64+
void init_font_matrix();
6665

6766
//void init_fontfile3();
6867

@@ -111,7 +110,10 @@ namespace pdflib
111110
std::string font_name;
112111
std::string base_font;
113112

114-
std::array<double, 4> font_bbox;
113+
std::array<double, 4> font_bbox {0, 0, 0, 0};
114+
std::array<double, 6> font_matrix {0.001, 0, 0, 0.001, 0, 0};
115+
double type3_xscale = 1.0;
116+
double type3_yscale = 1.0;
115117

116118
double ascent;
117119
double descent;
@@ -237,19 +239,6 @@ namespace pdflib
237239
return json_font;
238240
}
239241

240-
double pdf_resource<PAGE_FONT>::get_unit()
241-
{
242-
if(subtype==TYPE_3)
243-
{
244-
double unit = 1.0; // 1000.0
245-
LOG_S(WARNING) << "font-scale of the unit for TYPE_3: " << unit;
246-
247-
return unit;
248-
}
249-
250-
return 1.0;
251-
}
252-
253242
std::string pdf_resource<PAGE_FONT>::get_encoding_name()
254243
{
255244
return encoding_name;
@@ -611,6 +600,7 @@ namespace pdflib
611600

612601
init_font_name();
613602
init_font_bbox();
603+
init_font_matrix();
614604

615605
//init_fontfile3();
616606

@@ -831,46 +821,27 @@ namespace pdflib
831821

832822
std::vector<std::string> keys_0 = {"/FontDescriptor", "/FontBBox"};
833823
std::vector<std::string> keys_1 = {"/FontBBox"};
824+
nlohmann::json json_bbox;
834825

835826
if(utils::json::has(keys_0, json_font))
836827
{
837-
auto result = utils::json::get(keys_0, json_font);
838-
839-
for(int d=0; d<4; d++)
840-
{
841-
font_bbox[d] = result[d].get<double>();
842-
}
828+
json_bbox = utils::json::get(keys_0, json_font);
843829
}
844830
else if(utils::json::has(keys_0, desc_font))
845831
{
846-
auto result = utils::json::get(keys_0, desc_font);
847-
848-
for(int d=0; d<4; d++)
849-
{
850-
font_bbox[d] = result[d].get<double>();
851-
}
832+
json_bbox = utils::json::get(keys_0, desc_font);
852833
}
853834
else if(utils::json::has(keys_1, json_font))
854835
{
855836
//assert(subtype==TYPE_3);
856837

857-
auto result = utils::json::get(keys_1, json_font);
858-
859-
for(int d=0; d<4; d++)
860-
{
861-
font_bbox[d] = result[d].get<double>();
862-
}
838+
json_bbox = utils::json::get(keys_1, json_font);
863839
}
864840
else if(utils::json::has(keys_1, desc_font))
865841
{
866842
//assert(subtype==TYPE_3);
867843

868-
auto result = utils::json::get(keys_1, desc_font);
869-
870-
for(int d=0; d<4; d++)
871-
{
872-
font_bbox[d] = result[d].get<double>();
873-
}
844+
json_bbox = utils::json::get(keys_1, desc_font);
874845
}
875846
else if(bfonts.has(base_font)==1)
876847
{
@@ -880,7 +851,21 @@ namespace pdflib
880851
else
881852
{
882853
LOG_S(ERROR) << "could not find font-bbox";
883-
font_bbox = {0, 0, 0, 0};
854+
}
855+
856+
if (json_bbox != nullptr)
857+
{
858+
if (json_bbox.is_array() and json_bbox.size() == 4)
859+
{
860+
for(int d=0; d<4; d++)
861+
{
862+
font_bbox[d] = json_bbox[d].get<double>();
863+
}
864+
}
865+
else
866+
{
867+
LOG_S(ERROR) << "expected 4 elements in font-bbox, got: " << json_bbox;
868+
}
884869
}
885870

886871
LOG_S(INFO) << " -> font-bbox: ["
@@ -891,6 +876,45 @@ namespace pdflib
891876
}
892877

893878

879+
void pdf_resource<PAGE_FONT>::init_font_matrix()
880+
{
881+
LOG_S(INFO) << __FUNCTION__;// << "\t" << json_font.dump(2);
882+
883+
std::vector<std::string> keys_0 = {"/FontMatrix"};
884+
885+
if(utils::json::has(keys_0, json_font))
886+
{
887+
//assert(subtype==TYPE_3);
888+
auto json_matrix = utils::json::get(keys_0, json_font);
889+
890+
if (json_matrix.is_array() and json_matrix.size() == 6)
891+
{
892+
for(int d=0; d<6; d++)
893+
{
894+
font_matrix[d] = json_matrix[d].get<double>();
895+
}
896+
type3_xscale = font_matrix[0] * 1000.0;
897+
type3_yscale = font_matrix[3] * 1000.0;
898+
}
899+
else
900+
{
901+
LOG_S(ERROR) << "expected 6 elements in font-matrix, got: " << json_matrix;
902+
}
903+
}
904+
else
905+
{
906+
LOG_S(INFO) << "using default font-matrix";
907+
}
908+
909+
LOG_S(INFO) << " -> font-matrix: ["
910+
<< font_matrix[0] << ", "
911+
<< font_matrix[1] << ", "
912+
<< font_matrix[2] << ", "
913+
<< font_matrix[3] << ", "
914+
<< font_matrix[4] << ", "
915+
<< font_matrix[5] << "]";
916+
}
917+
894918

895919
/*
896920
void pdf_resource<PAGE_FONT>::init_fontfile3()
@@ -1166,7 +1190,12 @@ namespace pdflib
11661190
{
11671191
LOG_S(WARNING) << "'xheight' was not explicitely defined ...";
11681192
}
1169-
}
1193+
}
1194+
1195+
ascent *= type3_yscale;
1196+
descent *= type3_yscale;
1197+
capheight *= type3_yscale;
1198+
xheight *= type3_yscale;
11701199
}
11711200

11721201
void pdf_resource<PAGE_FONT>::init_default_width()
@@ -1304,8 +1333,8 @@ namespace pdflib
13041333
continue;
13051334
}
13061335

1307-
numb_to_widths[ind] = values[cnt++];
1308-
//LOG_S(INFO) << "index: " << ind << " -> width: " << numb_to_widths.at(ind);
1336+
numb_to_widths[ind] = values[cnt++] * type3_xscale;
1337+
//LOG_S(INFO) << "index: " << ind << " -> width: " << numb_to_widths.at(ind);
13091338
}
13101339
}
13111340

@@ -1382,7 +1411,7 @@ namespace pdflib
13821411
for(int id=beg; id<=end; id++)
13831412
{
13841413
//LOG_S(WARNING) << "\t" << id << " -> " << w;
1385-
numb_to_widths[id] = w;
1414+
numb_to_widths[id] = w * type3_xscale;
13861415
}
13871416
}
13881417
else if(ws[l].is_array())
@@ -1403,7 +1432,7 @@ namespace pdflib
14031432
{
14041433
//LOG_S(WARNING) << "\t" << beg+k << " -> " << w[k];
14051434

1406-
numb_to_widths[beg+k] = w[k];
1435+
numb_to_widths[beg+k] = w[k] * type3_xscale;
14071436
}
14081437
}
14091438
else if(ws[l].is_null())

src/v2/pdf_states/text.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,7 @@ namespace pdflib
262262
font_name = instructions[0].to_utf8_string();
263263
font_size = instructions[1].to_double();
264264

265-
if(page_fonts.count(font_name)>0)
266-
{
267-
font_size *= page_fonts[font_name].get_unit();
268-
}
269-
else
265+
if(page_fonts.count(font_name) == 0)
270266
{
271267
LOG_S(ERROR) << "unknown page-font: '" << font_name << "'";
272268

0 commit comments

Comments
 (0)