update some minor fixes

This commit is contained in:
saqib mir
2026-06-03 10:51:33 +05:30
parent dc6e538c81
commit 0862afa1ce
14 changed files with 1405 additions and 14 deletions
@@ -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;
};
+64 -3
View File
@@ -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);
}
+6
View File
@@ -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;
};
+1 -1
View File
@@ -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));