summaryrefslogtreecommitdiff
path: root/sdext
diff options
context:
space:
mode:
authorKevin Suo <suokunlong@126.com>2021-07-17 14:25:45 +0800
committerAdolfo Jayme Barrientos <fitojb@ubuntu.com>2021-07-23 14:53:03 +0200
commit0ebe806d011b7084b49dd038f3521a03bc935f8c (patch)
treee6c0e7aaf2507607709759464b3f991b6679b6c0 /sdext
parent4b5dd477bbe1647c6c60374da2e4cabcf5b6b58b (diff)
sdext.pdfimport: Restore to read font file for the determination...
of font attributes, as suggested by Mike Kaganski in https://gerrit.libreoffice.org/c/core/+/118977. This partially reverts da59686672fd2bc98f8cb28d5f04dc978b50ac13 but did some modification of the previous code with some explanationary comments. Change-Id: I224d9e717bf374a90f4834cbd9e11bf1138b41ff (cherry picked from commit a91d373837550fbde9c6ba8ca0f43aa8603d86f2) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119118 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Diffstat (limited to 'sdext')
-rw-r--r--sdext/source/pdfimport/wrapper/wrapper.cxx97
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx5
2 files changed, 89 insertions, 13 deletions
diff --git a/sdext/source/pdfimport/wrapper/wrapper.cxx b/sdext/source/pdfimport/wrapper/wrapper.cxx
index ae4903526c65..a887160eb56c 100644
--- a/sdext/source/pdfimport/wrapper/wrapper.cxx
+++ b/sdext/source/pdfimport/wrapper/wrapper.cxx
@@ -49,6 +49,7 @@
#include <com/sun/star/geometry/RealRectangle2D.hpp>
#include <com/sun/star/geometry/RealSize2D.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <tools/diagnose_ex.h>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
@@ -594,25 +595,36 @@ void LineParser::parseFontFamilyName( FontAttributes& rResult )
void LineParser::readFont()
{
- OString aFontName;
+ /*
+ xpdf line is like (separated by space):
+ updateFont <FontID> <isEmbedded> <isBold> <isItalic> <isUnderline> <TransformedFontSize> <nEmbedSize> <FontName>
+ updateFont 14 1 0 0 0 1200.000000 23068 TimesNewRomanPSMT
+
+ If nEmbedSize > 0, then a fontFile is followed as a stream.
+ */
+
+ OString aFontName;
sal_Int64 nFontID;
sal_Int32 nIsEmbedded, nIsBold, nIsItalic, nIsUnderline, nFileLen;
double nSize;
- readInt64(nFontID);
- readInt32(nIsEmbedded);
- readInt32(nIsBold);
- readInt32(nIsItalic);
- readInt32(nIsUnderline);
- readDouble(nSize);
- readInt32(nFileLen);
+ readInt64(nFontID); // read FontID
+ readInt32(nIsEmbedded); // read isEmbedded
+ readInt32(nIsBold); // read isBold
+ readInt32(nIsItalic); // read isItalic
+ readInt32(nIsUnderline);// read isUnderline
+ readDouble(nSize); // read TransformedFontSize
+ readInt32(nFileLen); // read nEmbedSize
nSize = nSize < 0.0 ? -nSize : nSize;
- aFontName = lcl_unescapeLineFeeds( m_aLine.subView( m_nCharIndex ) );
+ // Read FontName. From the current position to the end (any white spaces will be included).
+ aFontName = lcl_unescapeLineFeeds(m_aLine.subView(m_nCharIndex));
// name gobbles up rest of line
m_nCharIndex = std::string_view::npos;
+ // Check if this font is already in our font map list.
+ // If yes, update the font size and skip.
Parser::FontMapType::const_iterator pFont( m_parser.m_aFontMap.find(nFontID) );
if( pFont != m_parser.m_aFontMap.end() )
{
@@ -625,16 +637,75 @@ void LineParser::readFont()
}
// yet unknown font - get info and add to map
- FontAttributes aResult( OStringToOUString( aFontName,
- RTL_TEXTENCODING_UTF8 ),
+ FontAttributes aResult( OStringToOUString( aFontName, RTL_TEXTENCODING_UTF8 ),
nIsBold != 0,
nIsItalic != 0,
nIsUnderline != 0,
nSize,
1.0);
- // extract textual attributes (bold, italic in the name, etc.)
- parseFontFamilyName(aResult);
+ /* The above font attributes (fontName, bold, italic) are based on
+ xpdf line output and may not be reliable. To get correct attributes,
+ we do the following:
+ 1. Read the embeded font file and determine the attributes based on the
+ font file.
+ 2. If we failed to read the font file, or empty result is returned, then
+ determine the font attributes from the font name.
+ 3. If all these attemps have failed, then use a fallback font.
+ */
+ if (nFileLen > 0)
+ {
+ uno::Sequence<sal_Int8> aFontFile(nFileLen);
+ readBinaryData(aFontFile); // Read fontFile.
+
+ uno::Sequence<uno::Any> aArgs(1);
+ awt::FontDescriptor aFontDescriptor;
+ aArgs[0] <<= aFontFile;
+
+ try
+ {
+ uno::Reference<beans::XMaterialHolder> xHolder(
+ m_parser.m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.awt.FontIdentificator", aArgs, m_parser.m_xContext),
+ uno::UNO_QUERY);
+ if (xHolder.is())
+ {
+ uno::Any aFontReadResult(xHolder->getMaterial());
+ aFontReadResult >>= aFontDescriptor;
+ if (!aFontDescriptor.Name.isEmpty())
+ {
+ aResult.familyName = aFontDescriptor.Name;
+ aResult.isBold = (aFontDescriptor.Weight > 100.0);
+ aResult.isItalic = (aFontDescriptor.Slant == awt::FontSlant_OBLIQUE ||
+ aFontDescriptor.Slant == awt::FontSlant_ITALIC);
+ } else
+ {
+ SAL_WARN("sdext.pdfimport",
+ "Font detection from fontFile returned empty result.\
+ Guessing font info from font name.");
+ parseFontFamilyName(aResult);
+ }
+ } else
+ {
+ SAL_WARN("sdext.pdfimport",
+ "Failed to run FontIdentificator service.\
+ Guessing font info from font name.");
+ parseFontFamilyName(aResult);
+ }
+ } catch (uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("sdext.pdfimport", "Exception when trying to read font file.");
+ parseFontFamilyName(aResult);
+ }
+ } else
+ parseFontFamilyName(aResult);
+
+ // last fallback
+ if (aResult.familyName.isEmpty())
+ {
+ SAL_WARN("sdext.pdfimport", "Failed to determine the font, using a fallback font Arial.");
+ aResult.familyName = "Arial";
+ }
if (!m_parser.m_xDev)
m_parser.m_xDev.disposeAndReset(VclPtr<VirtualDevice>::Create());
diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
index bc313f76ecc4..97abf3a6f432 100644
--- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
+++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
@@ -791,6 +791,11 @@ void PDFOutDev::updateFont(GfxState *state)
aEsc.data() );
}
printf( "\n" );
+
+ if (nEmbedSize)
+ {
+ writeFontFile(gfxFont);
+ }
}
void PDFOutDev::updateRender(GfxState *state)