Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ The release run heads these entries with the version and opens a fresh

## Unreleased

- **Fix**: a pdf CFF font with no glyph but `.notdef` is no longer embedded,
because browsers reject it. Its text uses a substitute font.

- **Fix**: a pdf whose zlib streams declare a smaller window than they use
failed to open with "Inflator: error in compressed block". It opens now.

Expand Down
4 changes: 4 additions & 0 deletions src/odr/internal/font/cff_transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ namespace odr::internal::font {
std::string cff::wrap_to_otf(const CffFont &font,
const std::map<char32_t, std::uint16_t> &extra) {
const std::uint16_t glyphs = font.glyph_count();
if (glyphs < 2) {
// OTS rejects a `CFF ` table whose CharStrings hold only `.notdef`.
throw std::runtime_error("cff: no glyph besides .notdef");
}

// Glyphs past the 6400-slot BMP PUA overflow into Supplementary PUA-A, which
// serialize_cmap covers with a format-12 subtable.
Expand Down
2 changes: 1 addition & 1 deletion src/odr/internal/font/cff_transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class CffFont;
///
/// The `cmap` is `pua_cmap(glyph_count, extra)`, so the font renders every
/// glyph — including charset-unreachable ones — at the PUA code points the PDF
/// HTML layer emits.
/// HTML layer emits. Throws for a font with no glyph besides `.notdef`.
[[nodiscard]] std::string
wrap_to_otf(const CffFont &font,
const std::map<char32_t, std::uint16_t> &extra = {});
Expand Down
4 changes: 2 additions & 2 deletions test/data.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ odr_test_data(
odr_test_data(
PATH "reference-output/odr-public"
URL "https://github.com/opendocument-app/OpenDocument.test.output.git"
REVISION "542037eec472235ed0ada025fb41de76f082ea6e")
REVISION "055e7ec00193112b0759c1189463ef17ca892201")

odr_test_data(
PATH "reference-output/odr-private"
URL "https://github.com/opendocument-app/OpenDocument.test-private.output.git"
REVISION "78502f22a1c2631825476daa3351843f9f6c60ae")
REVISION "509b8191ac4ef3be1d5e14c0f69647d586dbe6c5")
11 changes: 11 additions & 0 deletions test/src/internal/font/cff_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <gtest/gtest.h>

#include <cstdint>
#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>
Expand Down Expand Up @@ -491,6 +492,16 @@ TEST(CffFontTest, WrapSanitizesTheFontName) {
EXPECT_EQ(patched.advance_width(1), cff.advance_width(1));
}

TEST(CffFontTest, WrapRejectsAFontOfOnlyNotdef) {
using namespace odr::internal::font;
const std::vector<cff::BuilderGlyph> glyphs = {
{".notdef", std::string("\x0e", 1)}};
const cff::CffFont font{
cff::build_cff("Hidden", glyphs, 0, 0, FontBBox{0, 0, 1000, 1000})};
ASSERT_EQ(font.glyph_count(), 1);
EXPECT_THROW((void)cff::wrap_to_otf(font), std::runtime_error);
}

TEST(CffFontTest, WrapDropsExtraEntriesPastGlyphCount) {
using namespace odr::internal::font;
const CffFont cff{build_cff()}; // 2 glyphs: valid ids 0..1
Expand Down
Loading