1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:57:35 +00:00

LibPDF: In Type0Font, read metrics /DW2 and /W2 for vertical text

Not used for anything yet.
This commit is contained in:
Nico Weber 2024-03-01 09:04:54 -05:00 committed by Andreas Kling
parent ef5d7b685d
commit b9a4689af3
3 changed files with 59 additions and 0 deletions

View file

@ -52,6 +52,7 @@
X(D) \
X(DCTDecode) \
X(DW) \
X(DW2) \
X(DamagedRowsBeforeError) \
X(Decode) \
X(DecodeParms) \
@ -188,6 +189,7 @@
X(UserUnit) \
X(V) \
X(W) \
X(W2) \
X(WhitePoint) \
X(Width) \
X(Widths) \

View file

@ -306,9 +306,56 @@ PDFErrorOr<void> Type0Font::initialize(Document* document, NonnullRefPtr<DictObj
}
}
// "The default position vector and vertical displacement vector are specified by the DW2 entry in the CIDFont dictionary."
int default_position_vector_y = 880;
int default_displacement_vector_y = -1000;
if (descendant_font->contains(CommonNames::DW2)) {
auto widths_array = MUST(descendant_font->get_array(document, CommonNames::DW2));
VERIFY(widths_array->size() == 2);
default_position_vector_y = widths_array->at(0).to_int();
default_displacement_vector_y = widths_array->at(1).to_int();
}
// "The W2 array allows the definition of vertical metrics for individual CIDs."
HashMap<u16, VerticalMetric> vertical_metrics;
if (descendant_font->contains(CommonNames::W2)) {
auto widths_array = MUST(descendant_font->get_array(document, CommonNames::W2));
Optional<u16> pending_code;
for (size_t i = 0; i < widths_array->size(); i++) {
auto& value = widths_array->at(i);
if (!pending_code.has_value()) {
pending_code = value.to_int();
} else if (value.has_number()) {
auto first_code = pending_code.release_value();
auto last_code = value.to_int();
auto vertical_displacement_vector_y = widths_array->at(i + 1).to_int();
auto position_vector_x = widths_array->at(i + 2).to_int();
auto position_vector_y = widths_array->at(i + 3).to_int();
i += 3;
for (u16 code = first_code; code <= last_code; code++)
vertical_metrics.set(code, VerticalMetric { vertical_displacement_vector_y, position_vector_x, position_vector_y });
} else {
auto array = TRY(document->resolve_to<ArrayObject>(value));
VERIFY(array->size() % 3 == 0);
auto code = pending_code.release_value();
for (size_t j = 0; j < array->size(); j += 3) {
auto vertical_displacement_vector_y = array->at(j).to_int();
auto position_vector_x = array->at(j + 1).to_int();
auto position_vector_y = array->at(j + 2).to_int();
vertical_metrics.set(code++, VerticalMetric { vertical_displacement_vector_y, position_vector_x, position_vector_y });
}
}
}
}
m_system_info = move(system_info);
m_widths = move(widths);
m_missing_width = default_width;
m_default_position_vector_y = default_position_vector_y;
m_default_displacement_vector_y = default_displacement_vector_y;
m_vertical_metrics = move(vertical_metrics);
return {};
}

View file

@ -40,6 +40,16 @@ private:
CIDSystemInfo m_system_info;
HashMap<u16, u16> m_widths;
u16 m_missing_width;
int m_default_position_vector_y;
int m_default_displacement_vector_y;
struct VerticalMetric {
int vertical_displacement_vector_y;
int position_vector_x;
int position_vector_y;
};
HashMap<u16, VerticalMetric> m_vertical_metrics;
OwnPtr<CIDFontType> m_cid_font_type;
};