summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
authorNicolas Pena <npm@chromium.org>2017-06-19 17:07:40 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-06-19 21:35:03 +0000
commit4db9046e56c884a350fa2c5087f8d5b8110463c4 (patch)
treea423eb6dfe89dd9e7aa5ffc8c728c9bfec938f1b /core/fpdfapi
parentb73ce7bcd72a97c780176d9f63681a5415c06422 (diff)
downloadpdfium-4db9046e56c884a350fa2c5087f8d5b8110463c4.tar.xz
Add heuristic for improving text rendering in CPDF_CharPosList::Load
This CL uses the following algorithm for improving substitute font spacing (we are assuming the text layout is horizontal): * Calculate PDFWidth, the width that the PDF says the glyph should have. * Calculate FTWidth, the width calculated by freetype for the glyph, using the substitute font that we'll use to render it. Note that some embedded fonts have PDFWidth == FTWidth + 1, so we consider that to be matching widths. * If PDFWidth > FTWidth + 1 , move the x coordinate by the difference / 2 so that the glyph is rendered in a more centered spot and the text looks better. * If PDFWidth < FTWidth, transform the glyph horizontally by PDFWidth / FTWidth so that the glyph gets compressed and does not overlap with surrounding glyphs. Bug: chromium:431507 Change-Id: Ia378344253fabe44d93af4daab98bb3b7bca22de Reviewed-on: https://pdfium-review.googlesource.com/6630 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Nicolás Peña <npm@chromium.org>
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/font/cpdf_font.cpp4
-rw-r--r--core/fpdfapi/font/cpdf_font.h1
-rw-r--r--core/fpdfapi/font/cpdf_simplefont.cpp4
-rw-r--r--core/fpdfapi/font/cpdf_simplefont.h2
-rw-r--r--core/fpdfapi/render/cpdf_charposlist.cpp32
5 files changed, 41 insertions, 2 deletions
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index 1faa4ec4be..bdd3464ed2 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -159,6 +159,10 @@ uint32_t CPDF_Font::CharCodeFromUnicode(wchar_t unicode) const {
return m_pToUnicodeMap ? m_pToUnicodeMap->ReverseLookup(unicode) : 0;
}
+bool CPDF_Font::HasFontWidths() const {
+ return true;
+}
+
void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
m_Flags = pFontDesc->GetIntegerFor("Flags", FXFONT_NONSYMBOLIC);
int ItalicAngle = 0;
diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h
index 1fef77b322..f70542223c 100644
--- a/core/fpdfapi/font/cpdf_font.h
+++ b/core/fpdfapi/font/cpdf_font.h
@@ -61,6 +61,7 @@ class CPDF_Font {
virtual int GlyphFromCharCodeExt(uint32_t charcode);
virtual CFX_WideString UnicodeFromCharCode(uint32_t charcode) const;
virtual uint32_t CharCodeFromUnicode(wchar_t Unicode) const;
+ virtual bool HasFontWidths() const;
const CFX_ByteString& GetBaseFont() const { return m_BaseFont; }
CFX_SubstFont* GetSubstFont() const { return m_Font.GetSubstFont(); }
diff --git a/core/fpdfapi/font/cpdf_simplefont.cpp b/core/fpdfapi/font/cpdf_simplefont.cpp
index ebf2cb65c7..a6c3ba0547 100644
--- a/core/fpdfapi/font/cpdf_simplefont.cpp
+++ b/core/fpdfapi/font/cpdf_simplefont.cpp
@@ -212,3 +212,7 @@ uint32_t CPDF_SimpleFont::CharCodeFromUnicode(wchar_t unicode) const {
return ret;
return m_Encoding.CharCodeFromUnicode(unicode);
}
+
+bool CPDF_SimpleFont::HasFontWidths() const {
+ return !m_bUseFontWidth;
+}
diff --git a/core/fpdfapi/font/cpdf_simplefont.h b/core/fpdfapi/font/cpdf_simplefont.h
index 3e414fa788..6a22f46966 100644
--- a/core/fpdfapi/font/cpdf_simplefont.h
+++ b/core/fpdfapi/font/cpdf_simplefont.h
@@ -29,6 +29,8 @@ class CPDF_SimpleFont : public CPDF_Font {
CPDF_FontEncoding* GetEncoding() { return &m_Encoding; }
+ bool HasFontWidths() const override;
+
protected:
virtual void LoadGlyphMap() = 0;
diff --git a/core/fpdfapi/render/cpdf_charposlist.cpp b/core/fpdfapi/render/cpdf_charposlist.cpp
index d4c6b3b5f9..68df46bdad 100644
--- a/core/fpdfapi/render/cpdf_charposlist.cpp
+++ b/core/fpdfapi/render/cpdf_charposlist.cpp
@@ -44,13 +44,16 @@ void CPDF_CharPosList::Load(const std::vector<uint32_t>& charCodes,
charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode);
GlyphID = charpos.m_ExtGID;
#endif
+ CFX_Font* pCurrentFont;
if (GlyphID != static_cast<uint32_t>(-1)) {
charpos.m_FallbackFontPosition = -1;
+ pCurrentFont = pFont->GetFont();
} else {
charpos.m_FallbackFontPosition =
pFont->FallbackFontFromCharcode(CharCode);
charpos.m_GlyphIndex = pFont->FallbackGlyphFromCharcode(
charpos.m_FallbackFontPosition, CharCode);
+ pCurrentFont = pFont->GetFontFallback(charpos.m_FallbackFontPosition);
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
charpos.m_ExtGID = charpos.m_GlyphIndex;
#endif
@@ -63,6 +66,29 @@ void CPDF_CharPosList::Load(const std::vector<uint32_t>& charCodes,
charpos.m_Origin = CFX_PointF(iChar ? charPos[iChar - 1] : 0, 0);
charpos.m_bGlyphAdjust = false;
+
+ float scalingFactor = 1.0f;
+ if (!pFont->IsEmbedded() && pFont->HasFontWidths() && !bVertWriting &&
+ !(pCurrentFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_MM)) {
+ int pdfGlyphWidth = pFont->GetCharWidthF(CharCode);
+ int ftGlyphWidth =
+ pCurrentFont ? pCurrentFont->GetGlyphWidth(charpos.m_GlyphIndex) : 0;
+ if (ftGlyphWidth && pdfGlyphWidth > ftGlyphWidth + 1) {
+ // Move the initial x position by half of the excess (transformed to
+ // text space coordinates).
+ charpos.m_Origin.x +=
+ (pdfGlyphWidth - ftGlyphWidth) * FontSize / 2000.0f;
+ } else if (pdfGlyphWidth && ftGlyphWidth &&
+ pdfGlyphWidth < ftGlyphWidth) {
+ scalingFactor = static_cast<float>(pdfGlyphWidth) / ftGlyphWidth;
+ ASSERT(scalingFactor >= 0.0f);
+ charpos.m_AdjustMatrix[0] = scalingFactor;
+ charpos.m_AdjustMatrix[1] = 0.0f;
+ charpos.m_AdjustMatrix[2] = 0.0f;
+ charpos.m_AdjustMatrix[3] = 1.0f;
+ charpos.m_bGlyphAdjust = true;
+ }
+ }
if (!pCIDFont)
continue;
@@ -79,9 +105,11 @@ void CPDF_CharPosList::Load(const std::vector<uint32_t>& charCodes,
const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID);
if (pTransform && !bVert) {
- charpos.m_AdjustMatrix[0] = pCIDFont->CIDTransformToFloat(pTransform[0]);
+ charpos.m_AdjustMatrix[0] =
+ pCIDFont->CIDTransformToFloat(pTransform[0]) * scalingFactor;
+ charpos.m_AdjustMatrix[1] =
+ pCIDFont->CIDTransformToFloat(pTransform[1]) * scalingFactor;
charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]);
- charpos.m_AdjustMatrix[1] = pCIDFont->CIDTransformToFloat(pTransform[1]);
charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]);
charpos.m_Origin.x +=
pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize;