update some minor fixes
This commit is contained in:
@@ -93,6 +93,8 @@ public:
|
||||
[[nodiscard]] virtual std::expected<std::vector<FontInfo>, EngineError> getFonts() const = 0;
|
||||
[[nodiscard]] virtual std::expected<std::vector<std::string>, EngineError> extractAnnotationsText() const = 0;
|
||||
|
||||
[[nodiscard]] virtual std::expected<double, EngineError> getGlyphWidth(const std::string& fontName, uint32_t charcode, double fontSize) const = 0;
|
||||
|
||||
[[nodiscard]] virtual DevicePoint pageToDevice(const Point2D& pagePoint, int deviceWidth, int deviceHeight, int rotate = 0) const noexcept = 0;
|
||||
[[nodiscard]] virtual Point2D deviceToPage(const DevicePoint& devicePoint, int deviceWidth, int deviceHeight, int rotate = 0) const noexcept = 0;
|
||||
};
|
||||
|
||||
@@ -399,8 +399,13 @@ void deduceFontMetadata(pdfengine::FontInfo& f) {
|
||||
}
|
||||
|
||||
// 7. Stable Internal Font Identifier
|
||||
// For subset fonts, fontName already contains the subset prefix (e.g. "ABCDEF+Arial").
|
||||
// Use the full fontName directly — it already encodes both the subset tag and
|
||||
// the base font name, separated by '+'. Concatenating subsetTag + "_" + fontName
|
||||
// would duplicate the prefix ("ABCDEF_ABCDEF+Arial").
|
||||
if (f.isSubset && !f.subsetTag.empty()) {
|
||||
f.internalFontId = f.subsetTag + "_" + f.fontName;
|
||||
// fontName is "ABCDEF+Arial"; use it as-is for the stable ID.
|
||||
f.internalFontId = f.fontName;
|
||||
} else {
|
||||
f.internalFontId = f.fontName + "_" + f.type + "_" + std::to_string(f.flags);
|
||||
}
|
||||
@@ -777,7 +782,7 @@ std::expected<std::vector<GlyphBounds>, EngineError> PdfiumPage::extractTextWith
|
||||
}
|
||||
|
||||
std::string utf8_char = code_point_to_utf8(cp);
|
||||
if (utf8_char.empty()) {
|
||||
if (utf8_char.empty() || cp == '\r' || cp == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -859,6 +864,60 @@ Point2D PdfiumPage::deviceToPage(const DevicePoint& devicePoint, int deviceWidth
|
||||
#endif
|
||||
}
|
||||
|
||||
std::expected<double, EngineError> PdfiumPage::getGlyphWidth(const std::string& fontName, uint32_t charcode, double fontSize) const {
|
||||
#ifdef PDFENGINE_WITH_PDFIUM
|
||||
if (!page_) {
|
||||
return std::unexpected(EngineError::Unknown);
|
||||
}
|
||||
|
||||
FPDF_FONT font = nullptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(textMutex_);
|
||||
|
||||
auto cached = fontHandleCache_.find(fontName);
|
||||
if (cached != fontHandleCache_.end()) {
|
||||
font = cached->second;
|
||||
} else {
|
||||
int objectCount = FPDFPage_CountObjects(page_);
|
||||
for (int i = 0; i < objectCount; ++i) {
|
||||
FPDF_PAGEOBJECT obj = FPDFPage_GetObject(page_, i);
|
||||
if (!obj || FPDFPageObj_GetType(obj) != FPDF_PAGEOBJ_TEXT) continue;
|
||||
|
||||
FPDF_FONT pageFont = FPDFTextObj_GetFont(obj);
|
||||
if (!pageFont) continue;
|
||||
|
||||
size_t nameLen = FPDFFont_GetBaseFontName(pageFont, nullptr, 0);
|
||||
if (nameLen > 0) {
|
||||
std::vector<char> nameBuf(nameLen);
|
||||
if (FPDFFont_GetBaseFontName(pageFont, nameBuf.data(), nameLen) > 0) {
|
||||
std::string currentName(nameBuf.data());
|
||||
if (currentName == fontName) {
|
||||
font = pageFont;
|
||||
fontHandleCache_[fontName] = font;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!font) {
|
||||
return std::unexpected(EngineError::Unknown);
|
||||
}
|
||||
|
||||
float width = 0.0f;
|
||||
if (!FPDFFont_GetGlyphWidth(font, charcode, static_cast<float>(fontSize), &width)) {
|
||||
return std::unexpected(EngineError::Unknown);
|
||||
}
|
||||
|
||||
return static_cast<double>(width);
|
||||
#else
|
||||
(void)fontName; (void)charcode; (void)fontSize;
|
||||
return std::unexpected(EngineError::Unknown);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PdfiumPage::ensureTextPageLoaded() const {
|
||||
#ifdef PDFENGINE_WITH_PDFIUM
|
||||
std::lock_guard<std::mutex> lock(textMutex_);
|
||||
@@ -1314,8 +1373,10 @@ std::expected<std::vector<FontInfo>, EngineError> PdfiumPage::getFonts() const {
|
||||
// deduceFontMetadata() (SystemFallback or Substituted).
|
||||
|
||||
// --- Recalculate stable identifier with corrected data ---
|
||||
// fontName already includes the subset prefix (e.g. "ABCDEF+Arial");
|
||||
// using it directly avoids the duplicate-prefix bug.
|
||||
if (f.isSubset && !f.subsetTag.empty()) {
|
||||
f.internalFontId = f.subsetTag + "_" + f.fontName;
|
||||
f.internalFontId = f.fontName;
|
||||
} else {
|
||||
f.internalFontId = f.fontName + "_" + f.type + "_" + std::to_string(f.flags);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace pdfengine::parser {
|
||||
|
||||
@@ -43,6 +44,8 @@ public:
|
||||
std::expected<std::vector<FontInfo>, EngineError> getFonts() const override;
|
||||
std::expected<std::vector<std::string>, EngineError> extractAnnotationsText() const override;
|
||||
|
||||
std::expected<double, EngineError> getGlyphWidth(const std::string& fontName, uint32_t charcode, double fontSize) const override;
|
||||
|
||||
DevicePoint pageToDevice(const Point2D& pagePoint, int deviceWidth, int deviceHeight, int rotate = 0) const noexcept override;
|
||||
Point2D deviceToPage(const DevicePoint& devicePoint, int deviceWidth, int deviceHeight, int rotate = 0) const noexcept override;
|
||||
|
||||
@@ -51,6 +54,9 @@ private:
|
||||
mutable NativeTextHandle textPage_ = nullptr;
|
||||
int pageIndex_ = 0;
|
||||
mutable std::mutex textMutex_;
|
||||
#ifdef PDFENGINE_WITH_PDFIUM
|
||||
mutable std::unordered_map<std::string, FPDF_FONT> fontHandleCache_;
|
||||
#endif
|
||||
|
||||
void ensureTextPageLoaded() const;
|
||||
};
|
||||
|
||||
@@ -593,7 +593,7 @@ TEST(FontDiagnosticsTest, DeepIntrospectionAndFontSizeVerification) {
|
||||
}
|
||||
EXPECT_EQ(f.sourceType, "Embedded");
|
||||
EXPECT_TRUE(f.isEmbedded);
|
||||
EXPECT_EQ(f.internalFontId, f.subsetTag + "_" + f.fontName);
|
||||
EXPECT_EQ(f.internalFontId, f.fontName);
|
||||
} else {
|
||||
EXPECT_TRUE(f.subsetTag.empty());
|
||||
EXPECT_EQ(f.internalFontId, f.fontName + "_" + f.type + "_" + std::to_string(f.flags));
|
||||
|
||||
Reference in New Issue
Block a user