[Libreoffice-commits] core.git: Branch 'feature/drop-findcmap' - 24 commits - desktop/inc desktop/source desktop/unx desktop/win32 drawinglayer/source dtrans/source dtrans/test editeng/inc editeng/source embeddedobj/source embeddedobj/test include/vcl sc/inc sc/qa sc/source vcl/inc vcl/qt5 vcl/quartz vcl/source vcl/unx vcl/win
Jan-Marek Glogowski (via logerrit)
logerrit at kemper.freedesktop.org
Sun Sep 13 20:41:46 UTC 2020
Rebased ref, commits from common ancestor:
commit a1dbf99e57865104c8e8a433c2fa8bc00f67bc04
Author: Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Sun Sep 13 15:01:22 2020 +0200
Commit: Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Sep 13 22:39:43 2020 +0200
WIN OSX Qt5 unify CreateFontSubset code
This is basically just some refactoring. Mots interestingly the
MacOS used to work with 257 glyphs. I couldn't find any
explaination for the 256 glyph limit. Sadly the PrintFontManager
is out of scope. That needs more inspection.
Change-Id: Ibfa0e905f5efeb7d4a609884d64b4ed2615a9d3d
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 9d86421e4e10..3a8fb1700862 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -57,6 +57,7 @@ namespace basegfx {
namespace vcl
{
class AbstractTrueTypeFont;
+typedef struct TTGlobalFontInfo_ TTGlobalFontInfo;
}
typedef sal_Unicode sal_Ucs; // TODO: use sal_UCS4 instead of sal_Unicode
@@ -622,6 +623,19 @@ protected:
static void GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF,
const PhysicalFontFace& rFontFace, bool bVertical,
std::vector<sal_Int32>& rWidths, Ucs2UIntMap& rUnicodeEnc);
+
+ static bool CreateTTFfontSubset(vcl::AbstractTrueTypeFont& aTTF, const OString& rSysPath,
+ const bool bVertical, const sal_GlyphId* pGlyphIds,
+ const sal_uInt8* pEncoding, sal_Int32* pGlyphWidths,
+ int nGlyphCount);
+
+ static bool CreateCFFfontSubset(const unsigned char* pFontBytes, int nByteLength,
+ const OString& rSysPath, const sal_GlyphId* pGlyphIds,
+ const sal_uInt8* pEncoding, sal_Int32* pGlyphWidths,
+ int nGlyphCount, FontSubsetInfo& rInfo);
+
+ static void FillFontSubsetInfo(const vcl::TTGlobalFontInfo& rTTInfo, const OUString& pPSName,
+ FontSubsetInfo& rInfo);
};
bool SalGraphics::IsNativeControlSupported(ControlType eType, ControlPart ePart)
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index bb582b06d6fc..6a844002711d 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -144,7 +144,7 @@ namespace vcl
/** Return value of GetTTGlobalFontInfo() */
- typedef struct {
+ typedef struct TTGlobalFontInfo_ {
char *family; /**< family name */
sal_Unicode *ufamily; /**< family name UCS2 */
char *subfamily; /**< subfamily name */
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 351bb3023213..de39fc7009b8 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -219,7 +219,6 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
const sal_GlyphId* pGlyphIds, const sal_uInt8* pEncoding,
sal_Int32* pGlyphWidths, int nGlyphCount, FontSubsetInfo& rInfo)
{
- // prepare the requested file name for writing the font-subset file
OUString aSysPath;
if (osl_File_E_None != osl_getSystemPathFromFileURL(rToFile.pData, &aSysPath.pData))
return false;
@@ -228,23 +227,16 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
const Qt5FontFace* pQt5FontFace = static_cast<const Qt5FontFace*>(pFontFace);
const QFont aFont = pQt5FontFace->CreateFont();
const QRawFont aRawFont(QRawFont::fromFont(aFont));
- const QFontInfo aFontInfo(aFont);
const OString aToFile(OUStringToOString(aSysPath, osl_getThreadTextEncoding()));
- const int nOrigGlyphCount = nGlyphCount;
+ // handle CFF-subsetting
QByteArray aCFFtable = aRawFont.fontTable("CFF ");
if (!aCFFtable.isEmpty())
- {
- FILE* pOutFile = fopen(aToFile.getStr(), "wb");
- rInfo.LoadFont(FontType::CFF_FONT, reinterpret_cast<const sal_uInt8*>(aCFFtable.data()),
- aCFFtable.size());
- bool bRet = rInfo.CreateFontSubset(FontType::TYPE1_PFB, pOutFile, nullptr, pGlyphIds,
- pEncoding, nGlyphCount, pGlyphWidths);
- fclose(pOutFile);
- return bRet;
- }
+ return SalGraphics::CreateCFFfontSubset(
+ reinterpret_cast<const sal_uInt8*>(aCFFtable.data()), aCFFtable.size(), aToFile,
+ pGlyphIds, pEncoding, pGlyphWidths, nGlyphCount, rInfo);
- // get details about the subsetted font
+ // fill details about the subsetted font
rInfo.m_nFontType = FontType::SFNT_TTF;
rInfo.m_aPSName = toOUString(aRawFont.familyName());
rInfo.m_nCapHeight = aRawFont.capHeight();
@@ -257,49 +249,8 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
if (GetTTGlobalFontHeadInfo(&aTTF, nXmin, nYmin, nXmax, nYmax, nMacStyleFlags))
rInfo.m_aFontBBox = tools::Rectangle(Point(nXmin, nYmin), Point(nXmax, nYmax));
- sal_uInt16 aShortIDs[nGlyphCount + 1];
- sal_uInt8 aTempEncs[nGlyphCount + 1];
-
- int nNotDef = -1;
-
- for (int i = 0; i < nGlyphCount; ++i)
- {
- aTempEncs[i] = pEncoding[i];
-
- sal_GlyphId aGlyphId(pGlyphIds[i]);
- aShortIDs[i] = static_cast<sal_uInt16>(aGlyphId);
- if (!aGlyphId && nNotDef < 0)
- nNotDef = i; // first NotDef glyph found
- }
-
- if (nNotDef != 0)
- {
- // add fake NotDef glyph if needed
- if (nNotDef < 0)
- nNotDef = nGlyphCount++;
- // NotDef glyph must be in pos 0 => swap glyphids
- aShortIDs[nNotDef] = aShortIDs[0];
- aTempEncs[nNotDef] = aTempEncs[0];
- aShortIDs[0] = 0;
- aTempEncs[0] = 0;
- }
-
- std::unique_ptr<sal_uInt16[]> pGlyphMetrics
- = GetTTSimpleGlyphMetrics(&aTTF, aShortIDs, nGlyphCount, false);
- if (!pGlyphMetrics)
- return false;
-
- sal_uInt16 nNotDefAdv = pGlyphMetrics[0];
- pGlyphMetrics[0] = pGlyphMetrics[nNotDef];
- pGlyphMetrics[nNotDef] = nNotDefAdv;
-
- for (int i = 0; i < nOrigGlyphCount; ++i)
- pGlyphWidths[i] = pGlyphMetrics[i];
-
- // write subset into destination file
- vcl::SFErrCodes nRC
- = vcl::CreateTTFromTTGlyphs(&aTTF, aToFile.getStr(), aShortIDs, aTempEncs, nGlyphCount);
- return (nRC == vcl::SFErrCodes::Ok);
+ return SalGraphics::CreateTTFfontSubset(aTTF, aToFile, false /* use FontSelectPattern? */,
+ pGlyphIds, pEncoding, pGlyphWidths, nGlyphCount);
}
const void* Qt5Graphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pDataLen*/)
diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx
index c72e8ee5cabd..3f2ec10bbd30 100644
--- a/vcl/quartz/salgdicommon.cxx
+++ b/vcl/quartz/salgdicommon.cxx
@@ -145,7 +145,7 @@ static void AddPolyPolygonToPath( CGMutablePathRef xPath,
bool AquaSalGraphics::CreateFontSubset( const OUString& rToFile,
const PhysicalFontFace* pFontData,
const sal_GlyphId* pGlyphIds, const sal_uInt8* pEncoding,
- sal_Int32* pGlyphWidths, int nGlyphCount,
+ sal_Int32* pGlyphWidths, const int nGlyphCount,
FontSubsetInfo& rInfo )
{
// TODO: move more of the functionality here into the generic subsetter code
@@ -153,36 +153,21 @@ bool AquaSalGraphics::CreateFontSubset( const OUString& rToFile,
// prepare the requested file name for writing the font-subset file
OUString aSysPath;
if( osl_File_E_None != osl_getSystemPathFromFileURL( rToFile.pData, &aSysPath.pData ) )
- {
return false;
- }
// get the raw-bytes from the font to be subset
std::vector<unsigned char> aBuffer;
bool bCffOnly = false;
if( !GetRawFontData( pFontData, aBuffer, &bCffOnly ) )
- {
return false;
- }
const OString aToFile( OUStringToOString( aSysPath,
osl_getThreadTextEncoding()));
// handle CFF-subsetting
- if( bCffOnly )
- {
- // provide the raw-CFF data to the subsetter
- ByteCount nCffLen = aBuffer.size();
- rInfo.LoadFont( FontType::CFF_FONT, aBuffer.data(), nCffLen );
-
- // NOTE: assuming that all glyphids requested on Aqua are fully translated
-
- // make the subsetter provide the requested subset
- FILE* pOutFile = fopen( aToFile.getStr(), "wb" );
- bool bRC = rInfo.CreateFontSubset( FontType::TYPE1_PFB, pOutFile, nullptr,
- pGlyphIds, pEncoding, nGlyphCount, pGlyphWidths );
- fclose( pOutFile );
- return bRC;
- }
+ // NOTE: assuming that all glyphids requested on Aqua are fully translated
+ if (bCffOnly)
+ return SalGraphics::CreateCFFfontSubset(aBuffer.data(), aBuffer.size(), aToFile, pGlyphIds,
+ pEncoding, pGlyphWidths, nGlyphCount, rInfo);
// TODO: modernize psprint's horrible fontsubset C-API
// this probably only makes sense after the switch to another SCM
@@ -190,102 +175,22 @@ bool AquaSalGraphics::CreateFontSubset( const OUString& rToFile,
// prepare data for psprint's font subsetter
TrueTypeFont* pSftFont = nullptr;
- SFErrCodes nRC = ::OpenTTFontBuffer( static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont);
- if( nRC != SFErrCodes::Ok )
- {
+ if (::OpenTTFontBuffer( static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont)
+ != SFErrCodes::Ok)
return false;
- }
+
// get details about the subsetted font
TTGlobalFontInfo aTTInfo;
::GetTTGlobalFontInfo( pSftFont, &aTTInfo );
- rInfo.m_nFontType = FontType::SFNT_TTF;
- rInfo.m_aPSName = OUString( aTTInfo.psname, std::strlen(aTTInfo.psname),
- RTL_TEXTENCODING_UTF8 );
- rInfo.m_aFontBBox = tools::Rectangle( Point( aTTInfo.xMin, aTTInfo.yMin ),
- Point( aTTInfo.xMax, aTTInfo.yMax ) );
- rInfo.m_nCapHeight = aTTInfo.yMax; // Well ...
- rInfo.m_nAscent = aTTInfo.winAscent;
- rInfo.m_nDescent = aTTInfo.winDescent;
- // mac fonts usually do not have an OS2-table
- // => get valid ascent/descent values from other tables
- if( !rInfo.m_nAscent )
- {
- rInfo.m_nAscent = +aTTInfo.typoAscender;
- }
- if( !rInfo.m_nAscent )
- {
- rInfo.m_nAscent = +aTTInfo.ascender;
- }
- if( !rInfo.m_nDescent )
- {
- rInfo.m_nDescent = +aTTInfo.typoDescender;
- }
- if( !rInfo.m_nDescent )
- {
- rInfo.m_nDescent = -aTTInfo.descender;
- }
-
- // subset glyphs and get their properties
- // take care that subset fonts require the NotDef glyph in pos 0
- int nOrigCount = nGlyphCount;
- sal_uInt16 aShortIDs[ 257 ];
- sal_uInt8 aTempEncs[ 257 ];
- int nNotDef = -1;
-
- assert( (nGlyphCount <= 256 && "too many glyphs for subsetting" ));
-
- for( int i = 0; i < nGlyphCount; ++i )
- {
- aTempEncs[i] = pEncoding[i];
-
- sal_GlyphId aGlyphId(pGlyphIds[i]);
- aShortIDs[i] = static_cast<sal_uInt16>( aGlyphId );
- if( !aGlyphId && nNotDef < 0 )
- {
- nNotDef = i; // first NotDef glyph found
- }
- }
-
- if( nNotDef != 0 )
- {
- // add fake NotDef glyph if needed
- if( nNotDef < 0 )
- {
- nNotDef = nGlyphCount++;
- }
- // NotDef glyph must be in pos 0 => swap glyphids
- aShortIDs[ nNotDef ] = aShortIDs[0];
- aTempEncs[ nNotDef ] = aTempEncs[0];
- aShortIDs[0] = 0;
- aTempEncs[0] = 0;
- }
-
- // TODO: where to get bVertical?
- const bool bVertical = false;
-
- // fill the pGlyphWidths array
- // while making sure that the NotDef glyph is at index==0
- std::unique_ptr<sal_uInt16[]> pGlyphMetrics = ::GetTTSimpleGlyphMetrics( pSftFont, aShortIDs,
- nGlyphCount, bVertical );
- if( !pGlyphMetrics )
- {
- return false;
- }
-
- sal_uInt16 nNotDefAdv = pGlyphMetrics[0];
- pGlyphMetrics[0] = pGlyphMetrics[nNotDef];
- pGlyphMetrics[nNotDef] = nNotDefAdv;
- for( int i = 0; i < nOrigCount; ++i )
- {
- pGlyphWidths[i] = pGlyphMetrics[i];
- }
- pGlyphMetrics.reset();
+ OUString aPSName(aTTInfo.psname, std::strlen(aTTInfo.psname), RTL_TEXTENCODING_UTF8);
+ FillFontSubsetInfo(aTTInfo, aPSName, rInfo);
// write subset into destination file
- nRC = ::CreateTTFromTTGlyphs( pSftFont, aToFile.getStr(), aShortIDs,
- aTempEncs, nGlyphCount );
+ bool bRet
+ = SalGraphics::CreateTTFfontSubset(*pSftFont, aToFile, false /* use FontSelectPattern? */,
+ pGlyphIds, pEncoding, pGlyphWidths, nGlyphCount);
::CloseTTFont(pSftFont);
- return (nRC == SFErrCodes::Ok);
+ return bRet;
}
static void alignLinePoint( const SalPoint* i_pIn, float& o_fX, float& o_fY )
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 777b2b1115e4..5758bfd2acec 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -29,6 +29,7 @@
#endif
#endif
#include <PhysicalFontFace.hxx>
+#include <fontsubset.hxx>
#include <salgdi.hxx>
#include <salframe.hxx>
#include <sft.hxx>
@@ -942,4 +943,111 @@ void SalGraphics::GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF,
}
}
+bool SalGraphics::CreateTTFfontSubset(vcl::AbstractTrueTypeFont& rTTF, const OString& rSysPath,
+ const bool bVertical, const sal_GlyphId* pGlyphIds,
+ const sal_uInt8* pEncoding, sal_Int32* pGlyphWidths,
+ const int nOrigGlyphCount)
+{
+ // Multiple questions:
+ // - Why is there a glyph limit?
+ // MacOS used to handle 257 glyphs...
+ // Also the much more complex PrintFontManager variant has this limit.
+ // Also the very first implementation has the limit in
+ // commit 8789ed701e98031f2a1657ea0dfd6f7a0b050992
+ // - Why doesn't the PrintFontManager care about the fake glpyh? It
+ // is used on all unx platforms to create the subset font.
+ // - Should the SAL_WARN actually be asserts, like on MacOS?
+ if (nOrigGlyphCount > 256)
+ {
+ SAL_WARN("vcl.fonts", "too many glyphs for subsetting");
+ return false;
+ }
+
+ int nGlyphCount = nOrigGlyphCount;
+ sal_uInt16 aShortIDs[256];
+ sal_uInt8 aTempEncs[256];
+
+ // handle the undefined / first font glyph
+ int nNotDef = -1, i;
+ for (i = 0; i < nGlyphCount; ++i)
+ {
+ aTempEncs[i] = pEncoding[i];
+ aShortIDs[i] = static_cast<sal_uInt16>(pGlyphIds[i]);
+ if (!aShortIDs[i])
+ if (nNotDef < 0)
+ nNotDef = i;
+ }
+
+ // nNotDef glyph must be in pos 0 => swap glyphids
+ if (nNotDef != 0)
+ {
+ if (nNotDef < 0)
+ {
+ if (nGlyphCount == 256)
+ {
+ SAL_WARN("vcl.fonts", "too many glyphs for subsetting");
+ return false;
+ }
+ nNotDef = nGlyphCount++;
+ }
+
+ aShortIDs[nNotDef] = aShortIDs[0];
+ aTempEncs[nNotDef] = aTempEncs[0];
+ aShortIDs[0] = 0;
+ aTempEncs[0] = 0;
+ }
+
+ std::unique_ptr<sal_uInt16[]> pMetrics
+ = GetTTSimpleGlyphMetrics(&rTTF, aShortIDs, nGlyphCount, bVertical);
+ if (!pMetrics)
+ return false;
+
+ sal_uInt16 nNotDefAdv = pMetrics[0];
+ pMetrics[0] = pMetrics[nNotDef];
+ pMetrics[nNotDef] = nNotDefAdv;
+ for (i = 0; i < nOrigGlyphCount; ++i)
+ pGlyphWidths[i] = pMetrics[i];
+ pMetrics.reset();
+
+ // write subset into destination file
+ return (CreateTTFromTTGlyphs(&rTTF, rSysPath.getStr(), aShortIDs, aTempEncs, nGlyphCount)
+ == vcl::SFErrCodes::Ok);
+}
+
+bool SalGraphics::CreateCFFfontSubset(const unsigned char* pFontBytes, int nByteLength,
+ const OString& rSysPath, const sal_GlyphId* pGlyphIds,
+ const sal_uInt8* pEncoding, sal_Int32* pGlyphWidths,
+ int nGlyphCount, FontSubsetInfo& rInfo)
+{
+ FILE* pOutFile = fopen(rSysPath.getStr(), "wb");
+ rInfo.LoadFont(FontType::CFF_FONT, pFontBytes, nByteLength);
+ bool bRet = rInfo.CreateFontSubset(FontType::TYPE1_PFB, pOutFile, nullptr, pGlyphIds, pEncoding,
+ nGlyphCount, pGlyphWidths);
+ fclose(pOutFile);
+ return bRet;
+}
+
+void SalGraphics::FillFontSubsetInfo(const vcl::TTGlobalFontInfo& rTTInfo, const OUString& pPSName,
+ FontSubsetInfo& rInfo)
+{
+ rInfo.m_aPSName = pPSName;
+ rInfo.m_nFontType = FontType::SFNT_TTF;
+ rInfo.m_aFontBBox
+ = tools::Rectangle(Point(rTTInfo.xMin, rTTInfo.yMin), Point(rTTInfo.xMax, rTTInfo.yMax));
+ rInfo.m_nCapHeight = rTTInfo.yMax; // Well ...
+ rInfo.m_nAscent = rTTInfo.winAscent;
+ rInfo.m_nDescent = rTTInfo.winDescent;
+
+ // mac fonts usually do not have an OS2-table
+ // => get valid ascent/descent values from other tables
+ if (!rInfo.m_nAscent)
+ rInfo.m_nAscent = +rTTInfo.typoAscender;
+ if (!rInfo.m_nAscent)
+ rInfo.m_nAscent = +rTTInfo.ascender;
+ if (!rInfo.m_nDescent)
+ rInfo.m_nDescent = +rTTInfo.typoDescender;
+ if (!rInfo.m_nDescent)
+ rInfo.m_nDescent = -rTTInfo.descender;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index bc7f83b8b6f2..0d7930d20e71 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1605,17 +1605,12 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
// check if the font has a CFF-table
const DWORD nCffTag = CalcTag( "CFF " );
const RawFontData aRawCffData( getHDC(), nCffTag );
- if( aRawCffData.get() )
+ if (aRawCffData.get())
{
pWinFontData->UpdateFromHDC( getHDC() );
-
- // provide a font subset from the CFF-table
- FILE* pOutFile = fopen( aToFile.getStr(), "wb" );
- rInfo.LoadFont( FontType::CFF_FONT, aRawCffData.get(), aRawCffData.size() );
- bool bRC = rInfo.CreateFontSubset( FontType::TYPE1_PFB, pOutFile, nullptr,
- pGlyphIds, pEncoding, nGlyphCount, pGlyphWidths );
- fclose( pOutFile );
- return bRC;
+ return SalGraphics::CreateCFFfontSubset(aRawCffData.get(), aRawCffData.size(), aToFile,
+ pGlyphIds, pEncoding, pGlyphWidths, nGlyphCount,
+ rInfo);
}
// get raw font file data
@@ -1635,60 +1630,12 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
TTGlobalFontInfo aTTInfo;
::GetTTGlobalFontInfo( aSftTTF.get(), &aTTInfo );
- rInfo.m_nFontType = FontType::SFNT_TTF;
- rInfo.m_aPSName = ImplSalGetUniString( aTTInfo.psname );
- rInfo.m_nAscent = aTTInfo.winAscent;
- rInfo.m_nDescent = aTTInfo.winDescent;
- rInfo.m_aFontBBox = tools::Rectangle( Point( aTTInfo.xMin, aTTInfo.yMin ),
- Point( aTTInfo.xMax, aTTInfo.yMax ) );
- rInfo.m_nCapHeight = aTTInfo.yMax; // Well ...
-
- // subset TTF-glyphs and get their properties
- // take care that subset fonts require the NotDef glyph in pos 0
- int nOrigCount = nGlyphCount;
- sal_uInt16 aShortIDs[ 256 ];
- sal_uInt8 aTempEncs[ 256 ];
-
- int nNotDef=-1, i;
- for( i = 0; i < nGlyphCount; ++i )
- {
- aTempEncs[i] = pEncoding[i];
- aShortIDs[i] = static_cast<sal_uInt16>(pGlyphIds[i]);
- if (!aShortIDs[i])
- if( nNotDef < 0 )
- nNotDef = i; // first NotDef glyph found
- }
-
- if( nNotDef != 0 )
- {
- // add fake NotDef glyph if needed
- if( nNotDef < 0 )
- nNotDef = nGlyphCount++;
-
- // NotDef glyph must be in pos 0 => swap glyphids
- aShortIDs[ nNotDef ] = aShortIDs[0];
- aTempEncs[ nNotDef ] = aTempEncs[0];
- aShortIDs[0] = 0;
- aTempEncs[0] = 0;
- }
- SAL_WARN_IF( nGlyphCount >= 257, "vcl", "too many glyphs for subsetting" );
-
- // fill pWidth array
- std::unique_ptr<sal_uInt16[]> pMetrics =
- ::GetTTSimpleGlyphMetrics( aSftTTF.get(), aShortIDs, nGlyphCount, aIFSD.mbVertical );
- if( !pMetrics )
- return false;
- sal_uInt16 nNotDefAdv = pMetrics[0];
- pMetrics[0] = pMetrics[nNotDef];
- pMetrics[nNotDef] = nNotDefAdv;
- for( i = 0; i < nOrigCount; ++i )
- pGlyphWidths[i] = pMetrics[i];
- pMetrics.reset();
+ OUString aPSName = ImplSalGetUniString(aTTInfo.psname);
+ FillFontSubsetInfo(aTTInfo, aPSName, rInfo);
// write subset into destination file
- nRC = ::CreateTTFromTTGlyphs( aSftTTF.get(), aToFile.getStr(), aShortIDs,
- aTempEncs, nGlyphCount );
- return (nRC == SFErrCodes::Ok);
+ return SalGraphics::CreateTTFfontSubset(*aSftTTF.get(), aToFile, aIFSD.mbVertical, pGlyphIds,
+ pEncoding, pGlyphWidths, nGlyphCount);
}
const void* WinSalGraphics::GetEmbedFontData(const PhysicalFontFace* pFont, long* pDataLen)
commit 9b68c3c183e37c130ae4325a1ae676ec3be3c7af
Author: Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Sep 11 22:34:11 2020 +0200
Commit: Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Sep 13 22:39:43 2020 +0200
Qt5 implement GetGlyphWidths
Basically implement it the same way then Windows and MacOS.
Change-Id: I643581af49aeb9274505e90e12acbe5bcf0c98fb
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index 86cb718809b3..bb582b06d6fc 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -680,7 +680,7 @@ class TrueTypeFont;
* @return true, if table data could be decoded
* @ingroup sft
*/
- VCL_DLLPUBLIC bool GetTTGlobalFontHeadInfo(AbstractTrueTypeFont *ttf, int& xMin, int& yMin, int& xMax, int& yMax, sal_uInt16& macStyle);
+ VCL_DLLPUBLIC bool GetTTGlobalFontHeadInfo(const AbstractTrueTypeFont *ttf, int& xMin, int& yMin, int& xMax, int& yMax, sal_uInt16& macStyle);
/**
* Returns fonts metrics.
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 0b823858a9bb..351bb3023213 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -309,9 +309,13 @@ const void* Qt5Graphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pData
void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/) {}
-void Qt5Graphics::GetGlyphWidths(const PhysicalFontFace* /*pPFF*/, bool /*bVertical*/,
- std::vector<sal_Int32>& /*rWidths*/, Ucs2UIntMap& /*rUnicodeEnc*/)
+void Qt5Graphics::GetGlyphWidths(const PhysicalFontFace* pFontFace, bool bVertical,
+ std::vector<sal_Int32>& rWidths, Ucs2UIntMap& rUnicodeEnc)
{
+ const Qt5FontFace* pQt5FontFace = static_cast<const Qt5FontFace*>(pFontFace);
+ const QRawFont aRawFont(QRawFont::fromFont(pQt5FontFace->CreateFont()));
+ Qt5TrueTypeFont aTTF(*pQt5FontFace, aRawFont);
+ SalGraphics::GetGlyphWidths(aTTF, *pFontFace, bVertical, rWidths, rUnicodeEnc);
}
namespace
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 6aba6d6d48d2..9fcf26f97d9c 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -2004,7 +2004,7 @@ void GetTTFontMetrics(const uint8_t *pHhea, size_t nHhea,
}
}
-bool GetTTGlobalFontHeadInfo(AbstractTrueTypeFont *ttf, int& xMin, int& yMin, int& xMax, int& yMax, sal_uInt16& macStyle)
+bool GetTTGlobalFontHeadInfo(const AbstractTrueTypeFont *ttf, int& xMin, int& yMin, int& xMax, int& yMax, sal_uInt16& macStyle)
{
sal_uInt32 table_size;
const sal_uInt8* table = ttf->table(O_head, table_size);
commit 9b6f2a0e72b5e3c251b3a22267c354df40e0e9e1
Author: Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Sep 11 22:31:51 2020 +0200
Commit: Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Sep 13 22:39:42 2020 +0200
Forward existing FontCharMap from PhysicalFontFace
Since removed code in the previous commit is primary used in
CreateFontSubset and GetGlyphWidths, you have a high chance, that
the CMAP was already used for displaying a font, so it's already
decoded and can be forwarded. Also the lookup should be faster in
general this way.
Change-Id: Icf4d8a1a84ff6ccdaccb7e870abe5df3837f9541
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index bcbf74b07aa1..86cb718809b3 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -470,11 +470,13 @@ class TrueTypeFont;
* @param nLen - size of memory buffer
* @param facenum - logical font number within a TTC file. This value is ignored
* for TrueType fonts
- * @param ttf - array of TrueTypeFonts
+ * @param ttf - returns the opened TrueTypeFont
+ * @param xCharMap - optional parsed character map
* @return value of SFErrCodes enum
* @ingroup sft
*/
- SFErrCodes VCL_DLLPUBLIC OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf);
+ SFErrCodes VCL_DLLPUBLIC OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum,
+ TrueTypeFont** ttf, const FontCharMapRef xCharMap = nullptr);
#if !defined(_WIN32)
/**
* TrueTypeFont constructor.
@@ -483,11 +485,13 @@ class TrueTypeFont;
* @param fname - name of TrueType font file
* @param facenum - logical font number within a TTC file. This value is ignored
* for TrueType fonts
- * @param ttf - array of TrueTypeFonts
+ * @param ttf - returns the opened TrueTypeFont
+ * @param xCharMap - optional parsed character map
* @return value of SFErrCodes enum
* @ingroup sft
*/
- SFErrCodes VCL_DLLPUBLIC OpenTTFontFile(const char *fname, sal_uInt32 facenum, TrueTypeFont** ttf);
+ SFErrCodes VCL_DLLPUBLIC OpenTTFontFile(const char *fname, sal_uInt32 facenum, TrueTypeFont** ttf,
+ const FontCharMapRef xCharMap = nullptr);
#endif
bool VCL_DLLPUBLIC getTTCoverage(
@@ -728,7 +732,7 @@ protected:
SFErrCodes indexGlyphData();
public:
- AbstractTrueTypeFont(const char* fileName = nullptr);
+ AbstractTrueTypeFont(const char* fileName = nullptr, const FontCharMapRef xCharMap = nullptr);
virtual ~AbstractTrueTypeFont();
const char* fileName() const { return m_pFileName; }
@@ -765,7 +769,7 @@ public:
sal_uInt32 ntables;
- TrueTypeFont(const char* pFileName = nullptr);
+ TrueTypeFont(const char* pFileName = nullptr, const FontCharMapRef xCharMap = nullptr);
~TrueTypeFont() override;
SFErrCodes open(sal_uInt32 facenum);
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 0fe602d1ce3f..0b823858a9bb 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -137,14 +137,15 @@ class Qt5TrueTypeFont : public vcl::AbstractTrueTypeFont
mutable QByteArray m_aFontTable[vcl::NUM_TAGS];
public:
- Qt5TrueTypeFont(const QRawFont& aRawFont);
+ Qt5TrueTypeFont(const Qt5FontFace& aFontFace, const QRawFont& aRawFont);
bool hasTable(sal_uInt32 ord) const override;
const sal_uInt8* table(sal_uInt32 ord, sal_uInt32& size) const override;
};
-Qt5TrueTypeFont::Qt5TrueTypeFont(const QRawFont& aRawFont)
- : m_aRawFont(aRawFont)
+Qt5TrueTypeFont::Qt5TrueTypeFont(const Qt5FontFace& aFontFace, const QRawFont& aRawFont)
+ : vcl::AbstractTrueTypeFont(nullptr, aFontFace.GetFontCharMap())
+ , m_aRawFont(aRawFont)
{
indexGlyphData();
}
@@ -224,7 +225,8 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
return false;
// get the raw-bytes from the font to be subset
- const QFont aFont = static_cast<const Qt5FontFace*>(pFontFace)->CreateFont();
+ const Qt5FontFace* pQt5FontFace = static_cast<const Qt5FontFace*>(pFontFace);
+ const QFont aFont = pQt5FontFace->CreateFont();
const QRawFont aRawFont(QRawFont::fromFont(aFont));
const QFontInfo aFontInfo(aFont);
const OString aToFile(OUStringToOString(aSysPath, osl_getThreadTextEncoding()));
@@ -249,7 +251,7 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
rInfo.m_nAscent = aRawFont.ascent();
rInfo.m_nDescent = aRawFont.descent();
- Qt5TrueTypeFont aTTF(aRawFont);
+ Qt5TrueTypeFont aTTF(*pQt5FontFace, aRawFont);
int nXmin, nYmin, nXmax, nYmax;
sal_uInt16 nMacStyleFlags;
if (GetTTGlobalFontHeadInfo(&aTTF, nXmin, nYmin, nXmax, nYmax, nMacStyleFlags))
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 2c1fdff16eec..1501043924b6 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -759,7 +759,8 @@ void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bV
// use the font subsetter to get the widths
TrueTypeFont* pSftFont = nullptr;
- SFErrCodes nRC = ::OpenTTFontBuffer( static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont);
+ SFErrCodes nRC = ::OpenTTFontBuffer(static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont,
+ pFontData->GetFontCharMap());
if( nRC != SFErrCodes::Ok )
return;
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 812c539d6700..6aba6d6d48d2 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1021,7 +1021,8 @@ int CountTTCFonts(const char* fname)
}
#if !defined(_WIN32)
-SFErrCodes OpenTTFontFile( const char* fname, sal_uInt32 facenum, TrueTypeFont** ttf )
+SFErrCodes OpenTTFontFile(const char* fname, sal_uInt32 facenum, TrueTypeFont** ttf,
+ const FontCharMapRef xCharMap)
{
SFErrCodes ret;
int fd = -1;
@@ -1029,7 +1030,7 @@ SFErrCodes OpenTTFontFile( const char* fname, sal_uInt32 facenum, TrueTypeFont**
if (!fname || !*fname) return SFErrCodes::BadFile;
- *ttf = new TrueTypeFont(fname);
+ *ttf = new TrueTypeFont(fname, xCharMap);
if( ! *ttf )
return SFErrCodes::Memory;
@@ -1080,9 +1081,10 @@ cleanup:
}
#endif
-SFErrCodes OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf)
+SFErrCodes OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf,
+ const FontCharMapRef xCharMap)
{
- *ttf = new TrueTypeFont();
+ *ttf = new TrueTypeFont(nullptr, xCharMap);
if( *ttf == nullptr )
return SFErrCodes::Memory;
@@ -1111,13 +1113,14 @@ bool withinBounds(sal_uInt32 tdoffset, sal_uInt32 moreoffset, sal_uInt32 len, sa
}
}
-AbstractTrueTypeFont::AbstractTrueTypeFont(const char* pFileName)
+AbstractTrueTypeFont::AbstractTrueTypeFont(const char* pFileName, const FontCharMapRef xCharMap)
: m_pFileName(nullptr)
, m_nGlyphs(0xFFFFFFFF)
, m_pGlyphOffsets(nullptr)
, m_nHorzMetrics(0)
, m_nVertMetrics(0)
, m_nUnitsPerEm(0)
+ , m_xCharMap(xCharMap)
{
if (pFileName)
m_pFileName = strdup(pFileName);
@@ -1129,8 +1132,8 @@ AbstractTrueTypeFont::~AbstractTrueTypeFont()
free(m_pGlyphOffsets);
}
-TrueTypeFont::TrueTypeFont(const char* pFileName)
- : AbstractTrueTypeFont(pFileName)
+TrueTypeFont::TrueTypeFont(const char* pFileName, const FontCharMapRef xCharMap)
+ : AbstractTrueTypeFont(pFileName, xCharMap)
, fsize(-1)
, ptr(nullptr)
, psname(nullptr)
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index f5f69f3eab33..bc7f83b8b6f2 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1543,7 +1543,7 @@ public:
~ScopedTrueTypeFont();
- SFErrCodes open(void const * pBuffer, sal_uInt32 nLen, sal_uInt32 nFaceNum);
+ SFErrCodes open(void const * pBuffer, sal_uInt32 nLen, sal_uInt32 nFaceNum, const FontCharMapRef xCharMap = nullptr);
TrueTypeFont * get() const { return m_pFont; }
TrueTypeFont* operator->() { return m_pFont; }
@@ -1561,10 +1561,10 @@ ScopedTrueTypeFont::~ScopedTrueTypeFont()
}
SFErrCodes ScopedTrueTypeFont::open(void const * pBuffer, sal_uInt32 nLen,
- sal_uInt32 nFaceNum)
+ sal_uInt32 nFaceNum, const FontCharMapRef xCharMap)
{
OSL_ENSURE(m_pFont == nullptr, "already open");
- return OpenTTFontBuffer(pBuffer, nLen, nFaceNum, &m_pFont);
+ return OpenTTFontBuffer(pBuffer, nLen, nFaceNum, &m_pFont, xCharMap);
}
bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
@@ -1629,7 +1629,7 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
nFaceNum = ~0U; // indicate "TTC font extracts only"
ScopedTrueTypeFont aSftTTF;
- SFErrCodes nRC = aSftTTF.open( xRawFontData.get(), xRawFontData.size(), nFaceNum );
+ SFErrCodes nRC = aSftTTF.open( xRawFontData.get(), xRawFontData.size(), nFaceNum, pFont->GetFontCharMap());
if( nRC != SFErrCodes::Ok )
return false;
@@ -1745,7 +1745,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
nFaceNum = ~0U; // indicate "TTC font extracts only"
ScopedTrueTypeFont aSftTTF;
- SFErrCodes nRC = aSftTTF.open( xRawFontData.get(), xRawFontData.size(), nFaceNum );
+ SFErrCodes nRC = aSftTTF.open(xRawFontData.get(), xRawFontData.size(), nFaceNum, pFont->GetFontCharMap());
if( nRC != SFErrCodes::Ok )
return;
commit 6debcbb64e76c64dfec33d4f4636c5b06b658833
Author: Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Sep 11 22:07:12 2020 +0200
Commit: Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Sep 13 22:39:42 2020 +0200
Replace FindCmap with ParseCMAP
This introduces a potential performance regression, because
FindCmap works on the existing font tables and just sets up
a lookup function, while ParseCMAP creates some optimized,
in-memory lookup table, which needs a bit more work, but
is faster in its usage, I think. At least the initial usage
is faster the old way, as the CMAPs aren't decoded at all.
As you can see, the old code is just used on Windows and
MacOS / iOS. Deep in the bowels of the PrintFontManager, the
CMAP is also decoded using ParseCMAP...
So I'm not sure this potential regression really exists. Most
fonts will already have a decoded CMAP, so my guess is this
is actually faster in the end. No idea, how to measure.
Change-Id: I52caac1264cd3ff11a2a3fa6e9c800f67f146a79
diff --git a/include/vcl/fontcharmap.hxx b/include/vcl/fontcharmap.hxx
index 2a4e1dd08ff1..f600c3e6849f 100644
--- a/include/vcl/fontcharmap.hxx
+++ b/include/vcl/fontcharmap.hxx
@@ -39,7 +39,11 @@ public:
all codepoints in the Unicode BMP range, including surrogates.
**/
FontCharMap();
+
+ /** A new FontCharMap is created based on the CmapResult
+ */
FontCharMap( const CmapResult& rCR );
+
virtual ~FontCharMap() override;
/** Get the default font character map
@@ -134,6 +138,8 @@ public:
int GetGlyphIndex( sal_UCS4 ) const;
+ bool isSymbolic() const;
+
private:
ImplFontCharMapRef mpImplFontCharMap;
diff --git a/vcl/inc/impfontcharmap.hxx b/vcl/inc/impfontcharmap.hxx
index eaa99dbe2d4d..287b663b4820 100644
--- a/vcl/inc/impfontcharmap.hxx
+++ b/vcl/inc/impfontcharmap.hxx
@@ -49,6 +49,7 @@ private:
const sal_uInt16* mpGlyphIds; // individual glyphid mappings
int mnRangeCount;
int mnCharCount; // covered codepoints
+ const bool m_bSymbolic;
};
bool VCL_DLLPUBLIC ParseCMAP( const unsigned char* pRawData, int nRawLength, CmapResult& );
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index 89853335db54..bcbf74b07aa1 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -42,6 +42,7 @@
#include <vcl/dllapi.h>
#include <vcl/fontcapabilities.hxx>
+#include <vcl/fontcharmap.hxx>
#include <i18nlangtag/lang.h>
#include <array>
@@ -650,19 +651,6 @@ class TrueTypeFont;
*/
VCL_DLLPUBLIC std::unique_ptr<sal_uInt16[]> GetTTSimpleGlyphMetrics(AbstractTrueTypeFont const *ttf, const sal_uInt16 *glyphArray, int nGlyphs, bool vertical);
-#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
-/**
- * Maps a Unicode (UCS-2) character to a glyph ID and returns it. Missing glyph has
- * a glyphID of 0 so this function can be used to test if a character is encoded in the font.
- *
- * @param ttf pointer to the TrueTypeFont structure
- * @param ch Unicode (UCS-2) character
- * @return glyph ID, if the character is missing in the font, the return value is 0.
- * @ingroup sft
- */
- VCL_DLLPUBLIC sal_uInt16 MapChar(TrueTypeFont const *ttf, sal_uInt16 ch);
-#endif
-
/**
* Returns global font information about the TrueType font.
* @see TTGlobalFontInfo
@@ -734,6 +722,7 @@ class VCL_DLLPUBLIC AbstractTrueTypeFont
sal_uInt32 m_nHorzMetrics;
sal_uInt32 m_nVertMetrics; /* if not 0 => font has vertical metrics information */
sal_uInt32 m_nUnitsPerEm;
+ FontCharMapRef m_xCharMap;
protected:
SFErrCodes indexGlyphData();
@@ -748,6 +737,7 @@ public:
sal_uInt32 horzMetricCount() const { return m_nHorzMetrics; }
sal_uInt32 vertMetricCount() const { return m_nVertMetrics; }
sal_uInt32 unitsPerEm() const { return m_nUnitsPerEm; }
+ FontCharMapRef GetCharMap() const { return m_xCharMap; }
virtual bool hasTable(sal_uInt32 ord) const = 0;
virtual const sal_uInt8* table(sal_uInt32 ord, sal_uInt32& size) const = 0;
@@ -774,9 +764,6 @@ public:
sal_Unicode *usubfamily;
sal_uInt32 ntables;
- const sal_uInt8* cmap;
- int cmapType;
- sal_uInt32 (*mapper)(const sal_uInt8 *, sal_uInt32, sal_uInt32); /* character to glyphID translation function */
TrueTypeFont(const char* pFileName = nullptr);
~TrueTypeFont() override;
diff --git a/vcl/source/font/fontcharmap.cxx b/vcl/source/font/fontcharmap.cxx
index 61f22f48f141..05a800fe1af7 100644
--- a/vcl/source/font/fontcharmap.cxx
+++ b/vcl/source/font/fontcharmap.cxx
@@ -54,6 +54,7 @@ ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR )
, mpGlyphIds( rCR.mpGlyphIds )
, mnRangeCount( rCR.mnRangeCount )
, mnCharCount( 0 )
+ , m_bSymbolic(rCR.mbSymbolic)
{
const sal_UCS4* pRangePtr = mpRangeCodes;
for( int i = mnRangeCount; --i >= 0; pRangePtr += 2 )
@@ -429,6 +430,8 @@ bool FontCharMap::IsDefaultMap() const
return mpImplFontCharMap->isDefaultMap();
}
+bool FontCharMap::isSymbolic() const { return mpImplFontCharMap->m_bSymbolic; }
+
int FontCharMap::GetCharCount() const
{
return mpImplFontCharMap->mnCharCount;
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 6eabe8480608..812c539d6700 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -35,6 +35,7 @@
#include <unistd.h>
#endif
#include <sft.hxx>
+#include <impfontcharmap.hxx>
#include "ttcr.hxx"
#include "xlat.hxx"
#include <rtl/crc.h>
@@ -165,18 +166,6 @@ static sal_uInt32 GetUInt32(const sal_uInt8 *ptr, size_t offset)
return t;
}
-#if defined(OSL_BIGENDIAN)
-#define Int16FromMOTA(a) (a)
-#define Int32FromMOTA(a) (a)
-#else
-static sal_uInt16 Int16FromMOTA(sal_uInt16 a) {
- return static_cast<sal_uInt16>(static_cast<sal_uInt8>(a >> 8) | (static_cast<sal_uInt8>(a) << 8));
-}
-static sal_uInt32 Int32FromMOTA(sal_uInt32 a) {
- return ((a>>24)&0xFF) | (((a>>8)&0xFF00) | ((a&0xFF00)<<8) | ((a&0xFF)<<24));
-}
-#endif
-
static F16Dot16 fixedMul(F16Dot16 a, F16Dot16 b)
{
unsigned int a1, b1;
@@ -1014,332 +1003,6 @@ static void GetNames(TrueTypeFont *t)
}
}
-namespace {
-
-enum cmapType {
- CMAP_NOT_USABLE = -1,
- CMAP_MS_Symbol = 10,
- CMAP_MS_Unicode = 11,
- CMAP_MS_ShiftJIS = 12,
- CMAP_MS_PRC = 13,
- CMAP_MS_Big5 = 14,
- CMAP_MS_Wansung = 15,
- CMAP_MS_Johab = 16
-};
-
-}
-
-#define MISSING_GLYPH_INDEX 0
-
-static sal_uInt32 getGlyph0(const sal_uInt8* cmap, sal_uInt32, sal_uInt32 c) {
- if (c <= 255) {
- return *(cmap + 6 + c);
- } else {
- return MISSING_GLYPH_INDEX;
- }
-}
-
-namespace {
-
-struct subHeader2 {
- sal_uInt16 firstCode;
- sal_uInt16 entryCount;
- sal_uInt16 idDelta;
- sal_uInt16 idRangeOffset;
-};
-
-}
-
-static sal_uInt32 getGlyph2(const sal_uInt8 *cmap, const sal_uInt32 nMaxCmapSize, sal_uInt32 c) {
- sal_uInt16 const *CMAP2 = reinterpret_cast<sal_uInt16 const *>(cmap);
- sal_uInt8 theHighByte;
-
- sal_uInt8 theLowByte;
- subHeader2 const * subHeader2s;
- sal_uInt16 const * subHeader2Keys;
- sal_uInt16 firstCode;
- int k = -1;
- sal_uInt32 ToReturn;
-
- theHighByte = static_cast<sal_uInt8>((c >> 8) & 0x00ff);
- theLowByte = static_cast<sal_uInt8>(c & 0x00ff);
- subHeader2Keys = CMAP2 + 3;
- subHeader2s = reinterpret_cast<subHeader2 const *>(subHeader2Keys + 256);
- if(reinterpret_cast<sal_uInt8 const *>(&subHeader2Keys[theHighByte]) - cmap < int(nMaxCmapSize - 2))
- {
- k = Int16FromMOTA(subHeader2Keys[theHighByte]) / 8;
- // check if the subheader record fits into available space
- if(reinterpret_cast<sal_uInt8 const *>(&subHeader2s[k]) - cmap >= int(nMaxCmapSize - sizeof(subHeader2)))
- k = -1;
- }
-
- if(k == 0) {
- firstCode = Int16FromMOTA(subHeader2s[0].firstCode);
- if(theLowByte >= firstCode && theLowByte < (firstCode + Int16FromMOTA(subHeader2s[k].entryCount))) {
- sal_uInt16 const * pGlyph = (&(subHeader2s[0].idRangeOffset))
- + (Int16FromMOTA(subHeader2s[0].idRangeOffset)/2) /* + offset */
- + theLowByte /* + to_look */
- - firstCode
- ;
- if (reinterpret_cast<sal_uInt8 const *>(pGlyph) - cmap < int(nMaxCmapSize) - 4)
- return *pGlyph;
- else
- return MISSING_GLYPH_INDEX;
- } else {
- return MISSING_GLYPH_INDEX;
- }
- } else if (k > 0) {
- firstCode = Int16FromMOTA(subHeader2s[k].firstCode);
- if(theLowByte >= firstCode && theLowByte < (firstCode + Int16FromMOTA(subHeader2s[k].entryCount))) {
- ToReturn = *((&(subHeader2s[k].idRangeOffset))
- + (Int16FromMOTA(subHeader2s[k].idRangeOffset)/2)
- + theLowByte - firstCode);
- if(ToReturn == 0) {
- return MISSING_GLYPH_INDEX;
- } else {
- ToReturn += Int16FromMOTA(subHeader2s[k].idDelta);
- return (ToReturn & 0xFFFF);
- }
- } else {
- return MISSING_GLYPH_INDEX;
- }
- } else {
- return MISSING_GLYPH_INDEX;
- }
-}
-
-static sal_uInt32 getGlyph6(const sal_uInt8 *cmap, sal_uInt32, sal_uInt32 c) {
- sal_uInt16 firstCode, lastCode, count;
- sal_uInt16 const *CMAP6 = reinterpret_cast<sal_uInt16 const *>(cmap);
-
- firstCode = Int16FromMOTA(*(CMAP6 + 3));
- count = Int16FromMOTA(*(CMAP6 + 4));
- lastCode = firstCode + count - 1;
- if (c < firstCode || c > lastCode) {
- return MISSING_GLYPH_INDEX;
- } else {
- return *((CMAP6 + 5)/*glyphIdArray*/ + (c - firstCode));
- }
-}
-
-static sal_uInt16 GEbinsearch(sal_uInt16 const *ar, sal_uInt16 length, sal_uInt16 toSearch) {
- signed int low, high, lastfound = 0xffff;
- sal_uInt16 res;
- if(length == sal_uInt16(0) || length == sal_uInt16(0xFFFF)) {
- return sal_uInt16(0xFFFF);
- }
- low = 0;
- high = length - 1;
- while(high >= low) {
- int mid = (high + low)/2;
- res = Int16FromMOTA(*(ar+mid));
- if(res >= toSearch) {
- lastfound = mid;
- high = --mid;
- } else {
- low = ++mid;
- }
- }
- return static_cast<sal_uInt16>(lastfound);
-}
-
-static sal_uInt32 getGlyph4(const sal_uInt8 *cmap, const sal_uInt32 nMaxCmapSize, sal_uInt32 c) {
- sal_uInt16 i;
- int ToReturn;
- sal_uInt16 segCount;
- sal_uInt16 const * startCode;
- sal_uInt16 const * endCode;
- sal_uInt16 const * idDelta;
- /* sal_uInt16 * glyphIdArray; */
- sal_uInt16 const * idRangeOffset;
- /*sal_uInt16 * glyphIndexArray;*/
- sal_uInt16 const *CMAP4 = reinterpret_cast<sal_uInt16 const *>(cmap);
- /* sal_uInt16 GEbinsearch(sal_uInt16 *ar, sal_uInt16 length, sal_uInt16 toSearch); */
-
- segCount = Int16FromMOTA(*(CMAP4 + 3))/2;
- endCode = CMAP4 + 7;
- i = GEbinsearch(endCode, segCount, static_cast<sal_uInt16>(c));
-
- if (i == sal_uInt16(0xFFFF)) {
- return MISSING_GLYPH_INDEX;
- }
- startCode = endCode + segCount + 1;
-
- if((reinterpret_cast<sal_uInt8 const *>(&startCode[i]) - cmap >= int(nMaxCmapSize - 2)) || Int16FromMOTA(startCode[i]) > c) {
- return MISSING_GLYPH_INDEX;
- }
- idDelta = startCode + segCount;
- idRangeOffset = idDelta + segCount;
- /*glyphIndexArray = idRangeOffset + segCount;*/
-
- if((reinterpret_cast<sal_uInt8 const *>(&idRangeOffset[i]) - cmap < int(nMaxCmapSize - 2)) && Int16FromMOTA(idRangeOffset[i]) != 0) {
- sal_uInt16 const * pGlyphOffset = &(idRangeOffset[i]) + (Int16FromMOTA(idRangeOffset[i])/2 + (c - Int16FromMOTA(startCode[i])));
- if(reinterpret_cast<sal_uInt8 const *>(pGlyphOffset) - cmap >= int(nMaxCmapSize - 2))
- return MISSING_GLYPH_INDEX;
- c = Int16FromMOTA(*pGlyphOffset);
- }
-
- ToReturn = (Int16FromMOTA(idDelta[i]) + c) & 0xFFFF;
- return ToReturn;
-}
-
-static sal_uInt32 getGlyph12(const sal_uInt8 *pCmap, sal_uInt32, sal_uInt32 cChar) {
- const sal_uInt32* pCMAP12 = reinterpret_cast<const sal_uInt32*>(pCmap);
- int nLength = Int32FromMOTA( pCMAP12[1] );
- int nGroups = Int32FromMOTA( pCMAP12[3] );
- int nLower = 0;
- int nUpper = nGroups;
-
- if( nUpper > (nLength-16)/12 )
- nUpper = (nLength-16)/12;
-
- /* binary search in "segmented coverage" subtable */
- while( nLower < nUpper ) {
- int nIndex = (nLower + nUpper) / 2;
- const sal_uInt32* pEntry = &pCMAP12[ 4 + 3*nIndex ];
- sal_uInt32 cStart = Int32FromMOTA( pEntry[0] );
- sal_uInt32 cLast = Int32FromMOTA( pEntry[1] );
- if( cChar < cStart )
- nUpper = nIndex;
- else if( cChar > cLast )
- nLower = nIndex + 1;
- else { /* found matching entry! */
- sal_uInt32 nGlyph = Int32FromMOTA( pEntry[2] );
- nGlyph += cChar - cStart;
- return nGlyph;
- }
- }
-
- return MISSING_GLYPH_INDEX;
-}
-
-static void FindCmap(TrueTypeFont *ttf)
-{
- sal_uInt32 table_size;
- const sal_uInt8* table = ttf->table(O_cmap, table_size);
- if (table_size < 4)
- {
- SAL_WARN("vcl.fonts", "Parsing error in " << OUString::createFromAscii(ttf->fileName()) <<
- "cmap table size too short");
- return;
- }
- sal_uInt16 ncmaps = GetUInt16(table, 2);
- sal_uInt32 AppleUni = 0; // Apple Unicode
- sal_uInt32 ThreeZero = 0; /* MS Symbol */
- sal_uInt32 ThreeOne = 0; /* MS UCS-2 */
- sal_uInt32 ThreeTwo = 0; /* MS ShiftJIS */
- sal_uInt32 ThreeThree = 0; /* MS PRC */
- sal_uInt32 ThreeFour = 0; /* MS Big5 */
- sal_uInt32 ThreeFive = 0; /* MS Wansung */
- sal_uInt32 ThreeSix = 0; /* MS Johab */
-
- const sal_uInt32 remaining_table_size = table_size-4;
- const sal_uInt32 nMinRecordSize = 8;
- const sal_uInt32 nMaxRecords = remaining_table_size / nMinRecordSize;
- if (ncmaps > nMaxRecords)
- {
- SAL_WARN("vcl.fonts", "Parsing error in " << OUString::createFromAscii(ttf->fileName()) <<
- ": " << nMaxRecords << " max possible entries, but " <<
- ncmaps << " claimed, truncating");
- ncmaps = nMaxRecords;
- }
-
- for (unsigned int i = 0; i < ncmaps; i++) {
- /* sanity check, cmap entry must lie within table */
- sal_uInt32 nLargestFixedOffsetPos = 8 + i * 8;
- sal_uInt32 nMinSize = nLargestFixedOffsetPos + sizeof(sal_uInt32);
- if (nMinSize > table_size)
- {
- SAL_WARN( "vcl.fonts", "Font " << OUString::createFromAscii(ttf->fileName()) << " claimed to have "
- << ncmaps << " cmaps, but only space for " << i);
- break;
- }
-
- sal_uInt16 pID = GetUInt16(table, 4 + i * 8);
- sal_uInt16 eID = GetUInt16(table, 6 + i * 8);
- sal_uInt32 offset = GetUInt32(table, nLargestFixedOffsetPos);
-
- /* sanity check, cmap must lie within file */
- if( (table - ttf->ptr) + offset > static_cast<sal_uInt32>(ttf->fsize) )
- continue;
-
- /* Unicode tables in Apple fonts */
- if (pID == 0) {
- AppleUni = offset;
- }
-
- if (pID == 3) {
- switch (eID) {
- case 0: ThreeZero = offset; break;
- case 10: // UCS-4
- case 1: ThreeOne = offset; break;
- case 2: ThreeTwo = offset; break;
- case 3: ThreeThree = offset; break;
- case 4: ThreeFour = offset; break;
- case 5: ThreeFive = offset; break;
- case 6: ThreeSix = offset; break;
- }
- }
- }
-
- // fall back to AppleUnicode if there are no ThreeOne/Threezero tables
- if( AppleUni && !ThreeZero && !ThreeOne)
- ThreeOne = AppleUni;
-
- if (ThreeOne) {
- ttf->cmapType = CMAP_MS_Unicode;
- ttf->cmap = table + ThreeOne;
- } else if (ThreeTwo) {
- ttf->cmapType = CMAP_MS_ShiftJIS;
- ttf->cmap = table + ThreeTwo;
- } else if (ThreeThree) {
- ttf->cmapType = CMAP_MS_PRC;
- ttf->cmap = table + ThreeThree;
- } else if (ThreeFour) {
- ttf->cmapType = CMAP_MS_Big5;
- ttf->cmap = table + ThreeFour;
- } else if (ThreeFive) {
- ttf->cmapType = CMAP_MS_Wansung;
- ttf->cmap = table + ThreeFive;
- } else if (ThreeSix) {
- ttf->cmapType = CMAP_MS_Johab;
- ttf->cmap = table + ThreeSix;
- } else if (ThreeZero) {
- ttf->cmapType = CMAP_MS_Symbol;
- ttf->cmap = table + ThreeZero;
- } else {
- ttf->cmapType = CMAP_NOT_USABLE;
- ttf->cmap = nullptr;
- }
-
- if (ttf->cmapType != CMAP_NOT_USABLE) {
- if( (ttf->cmap - ttf->ptr + 2U) > static_cast<sal_uInt32>(ttf->fsize) ) {
- ttf->cmapType = CMAP_NOT_USABLE;
- ttf->cmap = nullptr;
- }
- }
-
- if (ttf->cmapType == CMAP_NOT_USABLE) return;
-
- switch (GetUInt16(ttf->cmap, 0)) {
- case 0: ttf->mapper = getGlyph0; break;
- case 2: ttf->mapper = getGlyph2; break;
- case 4: ttf->mapper = getGlyph4; break;
- case 6: ttf->mapper = getGlyph6; break;
- case 12: ttf->mapper= getGlyph12; break;
- default:
-#if OSL_DEBUG_LEVEL > 1
- /*- if the cmap table is really broken */
- SAL_WARN("vcl.fonts", ttf->fileName() << ": "
- << GetUInt16(ttf->cmap, 0)
- << " is not a recognized cmap format..");
-#endif
- ttf->cmapType = CMAP_NOT_USABLE;
- ttf->cmap = nullptr;
- ttf->mapper = nullptr;
- }
-}
-
/*- Public functions */
int CountTTCFonts(const char* fname)
@@ -1476,9 +1139,6 @@ TrueTypeFont::TrueTypeFont(const char* pFileName)
, subfamily(nullptr)
, usubfamily(nullptr)
, ntables(0)
- , cmap(nullptr)
- , cmapType(0)
- , mapper(nullptr)
{
}
@@ -1554,6 +1214,15 @@ SFErrCodes AbstractTrueTypeFont::indexGlyphData()
table = this->table(O_vhea, table_size);
m_nVertMetrics = (table && table_size >= 36) ? GetUInt16(table, 34) : 0;
+ if (!m_xCharMap.is())
+ {
+ CmapResult aCmapResult;
+ table = this->table(O_cmap, table_size);
+ if (!ParseCMAP(table, table_size, aCmapResult))
+ return SFErrCodes::TtFormat;
+ m_xCharMap = new FontCharMap(aCmapResult);
+ }
+
return SFErrCodes::Ok;
}
@@ -1695,16 +1364,11 @@ SFErrCodes TrueTypeFont::open(sal_uInt32 facenum)
/* At this point TrueTypeFont is constructed, now need to verify the font format
and read the basic font properties */
- /* The following tables are absolutely required:
- * maxp, head, name, cmap
- */
-
SFErrCodes ret = indexGlyphData();
if (ret != SFErrCodes::Ok)
return ret;
GetNames(this);
- FindCmap(this);
return SFErrCodes::Ok;
}
@@ -2268,33 +1932,6 @@ SFErrCodes CreateT42FromTTGlyphs(TrueTypeFont *ttf,
return SFErrCodes::Ok;
}
-#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
-sal_uInt16 MapChar(TrueTypeFont const *ttf, sal_uInt16 ch)
-{
- switch (ttf->cmapType) {
- case CMAP_MS_Symbol:
- {
- const sal_uInt32 nMaxCmapSize = ttf->ptr + ttf->fsize - ttf->cmap;
- if( ttf->mapper == getGlyph0 && ( ch & 0xf000 ) == 0xf000 )
- ch &= 0x00ff;
- return static_cast<sal_uInt16>(ttf->mapper(ttf->cmap, nMaxCmapSize, ch ));
- }
-
- case CMAP_MS_Unicode: break;
- case CMAP_MS_ShiftJIS: ch = TranslateChar12(ch); break;
- case CMAP_MS_PRC: ch = TranslateChar13(ch); break;
- case CMAP_MS_Big5: ch = TranslateChar14(ch); break;
- case CMAP_MS_Wansung: ch = TranslateChar15(ch); break;
- case CMAP_MS_Johab: ch = TranslateChar16(ch); break;
- default: return 0;
- }
- const sal_uInt32 nMaxCmapSize = ttf->ptr + ttf->fsize - ttf->cmap;
- ch = static_cast<sal_uInt16>(ttf->mapper(ttf->cmap, nMaxCmapSize, ch));
- return ch;
-}
-#endif
-
-
std::unique_ptr<sal_uInt16[]> GetTTSimpleGlyphMetrics(AbstractTrueTypeFont const *ttf, const sal_uInt16 *glyphArray, int nGlyphs, bool vertical)
{
const sal_uInt8* pTable;
@@ -2391,7 +2028,7 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
info->subfamily = ttf->subfamily;
info->usubfamily = ttf->usubfamily;
info->psname = ttf->psname;
- info->symbolEncoded = (ttf->cmapType == CMAP_MS_Symbol);
+ info->symbolEncoded = ttf->GetCharMap()->isSymbolic();
sal_uInt32 table_size;
const sal_uInt8* table = ttf->table(O_OS2, table_size);
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 1f80539eb8e9..777b2b1115e4 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -936,7 +936,7 @@ void SalGraphics::GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF,
continue;
sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
- sal_uInt32 nGlyph = ::MapChar(&rTTF, nUcsChar);
+ sal_uInt32 nGlyph = xFCMap->GetGlyphIndex(nUcsChar);
if (nGlyph > 0)
rUnicodeEnc[nUcsChar] = nGlyph;
}
commit 8813caa2c57f30a8bbdc12ffa60da6f6b2f7d39c
Author: Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Fri Sep 11 17:24:59 2020 +0200
Commit: Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Sep 13 22:39:41 2020 +0200
WIN OSX unify GetGlyphWidths code
Now that GetFontChatMap is a member of PhysicalFontFace, we can
copy the common part of both architectures into a SalGraphics
helper function.
Change-Id: Iad379ea690a1c5346b69b5042188506ccf575cc2
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index d2b92c65110f..9d86421e4e10 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -54,6 +54,11 @@ namespace basegfx {
class B2DPolyPolygon;
}
+namespace vcl
+{
+class AbstractTrueTypeFont;
+}
+
typedef sal_Unicode sal_Ucs; // TODO: use sal_UCS4 instead of sal_Unicode
typedef std::map< sal_Ucs, sal_uInt32 > Ucs2UIntMap;
@@ -613,6 +618,10 @@ protected:
std::unique_ptr<vcl::WidgetDrawInterface> m_pWidgetDraw;
vcl::WidgetDrawInterface* forWidget() { return m_pWidgetDraw ? m_pWidgetDraw.get() : this; }
+
+ static void GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF,
+ const PhysicalFontFace& rFontFace, bool bVertical,
+ std::vector<sal_Int32>& rWidths, Ucs2UIntMap& rUnicodeEnc);
};
bool SalGraphics::IsNativeControlSupported(ControlType eType, ControlPart ePart)
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 4cab7731eca5..2c1fdff16eec 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -763,51 +763,7 @@ void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bV
if( nRC != SFErrCodes::Ok )
return;
- const int nGlyphCount = pSftFont->glyphCount();
- if( nGlyphCount > 0 )
- {
- // get glyph metrics
- rGlyphWidths.resize(nGlyphCount);
- std::vector<sal_uInt16> aGlyphIds(nGlyphCount);
- for( int i = 0; i < nGlyphCount; i++ )
- {
- aGlyphIds[i] = static_cast<sal_uInt16>(i);
- }
-
- std::unique_ptr<sal_uInt16[]> pGlyphMetrics = ::GetTTSimpleGlyphMetrics( pSftFont, aGlyphIds.data(),
- nGlyphCount, bVertical );
- if( pGlyphMetrics )
- {
- for( int i = 0; i < nGlyphCount; ++i )
- {
- rGlyphWidths[i] = pGlyphMetrics[i];
- }
- pGlyphMetrics.reset();
- }
-
- rtl::Reference<CoreTextFontFace> rCTFontData(new CoreTextFontFace(*pFontData, pFontData->GetFontId()));
- FontCharMapRef xFCMap = rCTFontData->GetFontCharMap();
- SAL_WARN_IF( !xFCMap.is() || !xFCMap->GetCharCount(), "vcl", "no charmap" );
-
- // get unicode<->glyph encoding
- // TODO? avoid sft mapping by using the xFCMap itself
- int nCharCount = xFCMap->GetCharCount();
- sal_uInt32 nChar = xFCMap->GetFirstChar();
- for( ; --nCharCount >= 0; nChar = xFCMap->GetNextChar( nChar ) )
- {
- if( nChar > 0xFFFF ) // TODO: allow UTF-32 chars
- break;
-
- sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
- sal_uInt32 nGlyph = ::MapChar( pSftFont, nUcsChar );
- if( nGlyph > 0 )
- {
- rUnicodeEnc[ nUcsChar ] = nGlyph;
- }
- }
-
- xFCMap = nullptr;
- }
+ SalGraphics::GetGlyphWidths(*pSftFont, *pFontData, bVertical, rGlyphWidths, rUnicodeEnc);
::CloseTTFont( pSftFont );
}
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 21844bff732a..1f80539eb8e9 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -28,8 +28,10 @@
#include <svsys.h>
#endif
#endif
+#include <PhysicalFontFace.hxx>
#include <salgdi.hxx>
#include <salframe.hxx>
+#include <sft.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <FileDefinitionWidgetDraw.hxx>
@@ -894,4 +896,50 @@ OUString SalGraphics::getRenderBackendName() const
return OUString();
}
+void SalGraphics::GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF,
+ const PhysicalFontFace& rFontFace, const bool bVertical,
+ std::vector<sal_Int32>& rWidths, Ucs2UIntMap& rUnicodeEnc)
+{
+ rWidths.clear();
+ rUnicodeEnc.clear();
+
+ const int nGlyphCount = rTTF.glyphCount();
+ if (nGlyphCount <= 0)
+ return;
+
+ FontCharMapRef xFCMap = rFontFace.GetFontCharMap();
+ if (!xFCMap.is() || !xFCMap->GetCharCount())
+ {
+ SAL_WARN("vcl.fonts", "no charmap");
+ return;
+ }
+
+ rWidths.resize(nGlyphCount);
+ std::vector<sal_uInt16> aGlyphIds(nGlyphCount);
+ for (int i = 0; i < nGlyphCount; i++)
+ aGlyphIds[i] = static_cast<sal_uInt16>(i);
+
+ std::unique_ptr<sal_uInt16[]> pGlyphMetrics
+ = GetTTSimpleGlyphMetrics(&rTTF, aGlyphIds.data(), nGlyphCount, bVertical);
+ if (pGlyphMetrics)
+ {
+ for (int i = 0; i < nGlyphCount; ++i)
+ rWidths[i] = pGlyphMetrics[i];
+ pGlyphMetrics.reset();
+ }
+
+ int nCharCount = xFCMap->GetCharCount();
+ sal_uInt32 nChar = xFCMap->GetFirstChar();
+ for (; --nCharCount >= 0; nChar = xFCMap->GetNextChar(nChar))
+ {
+ if (nChar > 0xFFFF)
+ continue;
+
+ sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
+ sal_uInt32 nGlyph = ::MapChar(&rTTF, nUcsChar);
+ if (nGlyph > 0)
+ rUnicodeEnc[nUcsChar] = nGlyph;
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 4dac58aaafb2..f5f69f3eab33 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1749,44 +1749,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
if( nRC != SFErrCodes::Ok )
return;
- int nGlyphs = aSftTTF->glyphCount();
- if( nGlyphs > 0 )
- {
- rWidths.resize(nGlyphs);
- std::vector<sal_uInt16> aGlyphIds(nGlyphs);
- for( int i = 0; i < nGlyphs; i++ )
- aGlyphIds[i] = sal_uInt16(i);
- std::unique_ptr<sal_uInt16[]> pMetrics = ::GetTTSimpleGlyphMetrics( aSftTTF.get(),
- aGlyphIds.data(),
- nGlyphs,
- bVertical );
- if( pMetrics )
- {
- for( int i = 0; i< nGlyphs; i++ )
- rWidths[i] = pMetrics[i];
- pMetrics.reset();
- rUnicodeEnc.clear();
- }
- const WinFontFace* pWinFont = static_cast<const WinFontFace*>(pFont);
- FontCharMapRef xFCMap = pWinFont->GetFontCharMap();
- SAL_WARN_IF( !xFCMap.is() || !xFCMap->GetCharCount(), "vcl", "no map" );
-
- int nCharCount = xFCMap->GetCharCount();
- sal_uInt32 nChar = xFCMap->GetFirstChar();
- for( int i = 0; i < nCharCount; i++ )
- {
- if( nChar < 0x00010000 )
- {
- sal_uInt16 nGlyph = ::MapChar( aSftTTF.get(),
- static_cast<sal_Ucs>(nChar));
- if( nGlyph )
- rUnicodeEnc[ static_cast<sal_Unicode>(nChar) ] = nGlyph;
- }
- nChar = xFCMap->GetNextChar( nChar );
- }
-
- xFCMap = nullptr;
- }
+ SalGraphics::GetGlyphWidths(*aSftTTF.get(), *pFont, bVertical, rWidths, rUnicodeEnc);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 92b5d60d65f409d9e0ce58584c522f606607649d
Author: Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Mon Sep 7 23:56:20 2020 +0200
Commit: Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Sep 13 22:39:41 2020 +0200
VCL register common functions in PhysicalFontFace
This makes GetFontCapabilities and GetFontChatMap members of the
PhysicalFontFace. These are implemented in all the real font face
classes anyway. Also provide dummies for the PDF buildin fonts.
Change-Id: Icb8cb14480ce1e020977b8f69892095d787982ce
diff --git a/vcl/inc/PhysicalFontFace.hxx b/vcl/inc/PhysicalFontFace.hxx
index 23af5be9169e..b6c0be37d99c 100644
--- a/vcl/inc/PhysicalFontFace.hxx
+++ b/vcl/inc/PhysicalFontFace.hxx
@@ -23,6 +23,7 @@
#include <salhelper/simplereferenceobject.hxx>
#include <rtl/ref.hxx>
#include <vcl/dllapi.h>
+#include <vcl/fontcharmap.hxx>
#include "fontattributes.hxx"
@@ -31,6 +32,11 @@ struct FontMatchStatus;
class FontSelectPattern;
class PhysicalFontFamily;
+namespace vcl
+{
+struct FontCapabilities;
+}
+
struct FontMatchStatus
{
public:
@@ -59,6 +65,8 @@ public:
int GetHeight() const { return mnHeight; }
int GetWidth() const { return mnWidth; }
virtual sal_IntPtr GetFontId() const = 0;
+ virtual FontCharMapRef GetFontCharMap() const = 0;
+ virtual bool GetFontCapabilities(vcl::FontCapabilities&) const = 0;
bool IsBetterMatch( const FontSelectPattern&, FontMatchStatus& ) const;
sal_Int32 CompareWithSize( const PhysicalFontFace& ) const;
diff --git a/vcl/inc/qt5/Qt5FontFace.hxx b/vcl/inc/qt5/Qt5FontFace.hxx
index f9853af0f8c9..9c893d4f88c8 100644
--- a/vcl/inc/qt5/Qt5FontFace.hxx
+++ b/vcl/inc/qt5/Qt5FontFace.hxx
@@ -48,8 +48,8 @@ public:
QFont CreateFont() const;
int GetFontTable(const char pTagName[5], unsigned char*) const;
- const FontCharMapRef& GetFontCharMap() const;
- bool GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const;
+ FontCharMapRef GetFontCharMap() const override;
+ bool GetFontCapabilities(vcl::FontCapabilities&) const override;
bool HasChar(sal_uInt32 cChar) const;
rtl::Reference<LogicalFontInstance>
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index a5c74c17705c..8058b68378b6 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -67,8 +67,8 @@ public:
int GetFontTable( uint32_t nTagCode, unsigned char* ) const;
int GetFontTable( const char pTagName[5], unsigned char* ) const;
- FontCharMapRef GetFontCharMap() const;
- bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
+ FontCharMapRef GetFontCharMap() const override;
+ bool GetFontCapabilities(vcl::FontCapabilities&) const override;
bool HasChar( sal_uInt32 cChar ) const;
rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern&) const override;
diff --git a/vcl/inc/unx/freetype_glyphcache.hxx b/vcl/inc/unx/freetype_glyphcache.hxx
index c375ba2ff5d4..4586c6fd2e6d 100644
--- a/vcl/inc/unx/freetype_glyphcache.hxx
+++ b/vcl/inc/unx/freetype_glyphcache.hxx
@@ -72,7 +72,8 @@ public:
void AnnounceFont( PhysicalFontCollection* );
- const FontCharMapRef& GetFontCharMap();
+ FontCharMapRef GetFontCharMap() const;
+ bool GetFontCapabilities(vcl::FontCapabilities&) const;
private:
friend class FreetypeManager;
@@ -87,7 +88,7 @@ private:
sal_IntPtr mnFontId;
FontAttributes maDevFontAttributes;
- FontCharMapRef mxFontCharMap;
+ mutable FontCharMapRef mxFontCharMap;
};
class FreetypeFontFace : public PhysicalFontFace
@@ -100,8 +101,16 @@ public:
virtual rtl::Reference<LogicalFontInstance> CreateFontInstance( const FontSelectPattern& ) const override;
virtual sal_IntPtr GetFontId() const override { return mpFreetypeFontInfo->GetFontId(); }
+
+ FontCharMapRef GetFontCharMap() const override { return mpFreetypeFontInfo->GetFontCharMap(); }
+ inline bool GetFontCapabilities(vcl::FontCapabilities&) const override;
};
+bool FreetypeFontFace::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const
+{
+ return mpFreetypeFontInfo->GetFontCapabilities(rFontCapabilities);
+}
+
class SAL_DLLPUBLIC_RTTI FreetypeFontInstance : public LogicalFontInstance
{
friend rtl::Reference<LogicalFontInstance> FreetypeFontFace::CreateFontInstance(const FontSelectPattern&) const;
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 5fe6645e7d2c..bf89853e1a8e 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -72,8 +72,8 @@ public:
BYTE GetCharSet() const { return meWinCharSet; }
BYTE GetPitchAndFamily() const { return mnPitchAndFamily; }
- FontCharMapRef GetFontCharMap() const;
- bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
+ FontCharMapRef GetFontCharMap() const override;
+ bool GetFontCapabilities(vcl::FontCapabilities&) const override;
private:
sal_IntPtr mnId;
diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx
index d02e61955103..ce349099030a 100644
--- a/vcl/qt5/Qt5FontFace.cxx
+++ b/vcl/qt5/Qt5FontFace.cxx
@@ -162,7 +162,7 @@ Qt5FontFace::CreateFontInstance(const FontSelectPattern& rFSD) const
return new Qt5Font(*this, rFSD);
}
-const FontCharMapRef& Qt5FontFace::GetFontCharMap() const
+FontCharMapRef Qt5FontFace::GetFontCharMap() const
{
if (m_xCharMap.is())
return m_xCharMap;
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 26b53ff694b8..0fe602d1ce3f 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -72,15 +72,14 @@ FontCharMapRef Qt5Graphics::GetFontCharMap() const
{
if (!m_pTextStyle[0])
return FontCharMapRef(new FontCharMap());
- return static_cast<const Qt5FontFace*>(m_pTextStyle[0]->GetFontFace())->GetFontCharMap();
+ return m_pTextStyle[0]->GetFontFace()->GetFontCharMap();
}
bool Qt5Graphics::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const
{
if (!m_pTextStyle[0])
return false;
- return static_cast<const Qt5FontFace*>(m_pTextStyle[0]->GetFontFace())
- ->GetFontCapabilities(rFontCapabilities);
+ return m_pTextStyle[0]->GetFontFace()->GetFontCapabilities(rFontCapabilities);
}
void Qt5Graphics::GetDevFontList(PhysicalFontCollection* pPFC)
diff --git a/vcl/source/gdi/pdfbuildin_fonts.cxx b/vcl/source/gdi/pdfbuildin_fonts.cxx
index 41c208b93b67..bc7bc01004c0 100644
--- a/vcl/source/gdi/pdfbuildin_fonts.cxx
+++ b/vcl/source/gdi/pdfbuildin_fonts.cxx
@@ -43,6 +43,15 @@ OString BuildinFont::getNameObject() const
return aBuf.makeStringAndClear();
}
+FontCharMapRef BuildinFont::GetFontCharMap() const
+{
+ if (m_xFontCharMap.is())
+ return m_xFontCharMap;
+
+ m_xFontCharMap = new FontCharMap();
+ return m_xFontCharMap;
+}
+
FontAttributes BuildinFont::GetFontAttributes() const
{
FontAttributes aDFA;
@@ -103,7 +112,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
600, 600, 600, 600, 600, 600, 600, 600, // 232 - 239
600, 600, 600, 600, 600, 600, 600, 600, // 240 - 247
600, 600, 600, 600, 600, 600, 600, 600 // 248 - 255
- } },
+ },
+ nullptr },
{ "Courier", // family name
"Italic", // style
@@ -149,7 +159,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
600, 600, 600, 600, 600, 600, 600, 600, // 232 - 239
600, 600, 600, 600, 600, 600, 600, 600, // 240 - 247
600, 600, 600, 600, 600, 600, 600, 600 // 248 - 255
- } },
+ },
+ nullptr },
{ "Courier", // family name
"Bold", // style
@@ -195,7 +206,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
600, 600, 600, 600, 600, 600, 600, 600, // 232 - 239
600, 600, 600, 600, 600, 600, 600, 600, // 240 - 247
600, 600, 600, 600, 600, 600, 600, 600 // 248 - 255
- } },
+ },
+ nullptr },
{ "Courier", // family name
"Bold Italic", // style
@@ -241,7 +253,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
600, 600, 600, 600, 600, 600, 600, 600, // 232 - 239
600, 600, 600, 600, 600, 600, 600, 600, // 240 - 247
600, 600, 600, 600, 600, 600, 600, 600 // 248 - 255
- } },
+ },
+ nullptr },
{ "Helvetica", // family name
"Normal", // style
@@ -287,7 +300,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
556, 556, 556, 556, 278, 278, 278, 278, // 232 - 239
556, 556, 556, 556, 556, 556, 556, 584, // 240 - 247
611, 556, 556, 556, 556, 500, 556, 500 // 248 - 255
- } },
+ },
+ nullptr },
{ "Helvetica", // family name
"Italic", // style
@@ -333,7 +347,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
556, 556, 556, 556, 278, 278, 278, 278, // 232 - 239
556, 556, 556, 556, 556, 556, 556, 584, // 240 - 247
611, 556, 556, 556, 556, 500, 556, 500 // 248 - 255
- } },
+ },
+ nullptr },
{ "Helvetica", // family name
"Bold", // style
@@ -379,7 +394,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
556, 556, 556, 556, 278, 278, 278, 278, // 232 - 239
611, 611, 611, 611, 611, 611, 611, 584, // 240 - 247
611, 611, 611, 611, 611, 556, 611, 556 // 248 - 255
- } },
+ },
+ nullptr },
{ "Helvetica", // family name
"Bold Italic", // style
@@ -425,7 +441,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
556, 556, 556, 556, 278, 278, 278, 278, // 232 - 239
611, 611, 611, 611, 611, 611, 611, 584, // 240 - 247
611, 611, 611, 611, 611, 556, 611, 556 // 248 - 255
- } },
+ },
+ nullptr },
{ "Times", // family name
"Normal", // style
@@ -471,7 +488,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
444, 444, 444, 444, 278, 278, 278, 278, // 232 - 239
500, 500, 500, 500, 500, 500, 500, 564, // 240 - 247
500, 500, 500, 500, 500, 500, 500, 500 // 248 - 255
- } },
+ },
+ nullptr },
{ "Times", // family name
"Italic", // style
@@ -517,7 +535,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
444, 444, 444, 444, 278, 278, 278, 278, // 232 - 239
500, 500, 500, 500, 500, 500, 500, 675, // 240 - 247
500, 500, 500, 500, 500, 444, 500, 444 // 248 - 255
- } },
+ },
+ nullptr },
{ "Times", // family name
"Bold", // style
@@ -563,7 +582,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
444, 444, 444, 444, 278, 278, 278, 278, // 232 - 239
500, 556, 500, 500, 500, 500, 500, 570, // 240 - 247
500, 556, 556, 556, 556, 500, 556, 500 // 248 - 255
- } },
+ },
+ nullptr },
{ "Times", // family name
"Bold Italic", // style
@@ -609,7 +629,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
444, 444, 444, 444, 278, 278, 278, 278, // 232 - 239
500, 556, 500, 500, 500, 500, 500, 570, // 240 - 247
500, 556, 556, 556, 556, 444, 500, 444 // 248 - 255
- } },
+ },
+ nullptr },
// The font name "Symbol" is too generic and causes plenty of trouble.
// To ensure WYSIWIG the PDF-Base14 variant gets a not-confusable name
@@ -657,7 +678,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
384, 384, 384, 384, 494, 494, 494, 494, // 232 - 239
0, 329, 274, 686, 686, 686, 384, 384, // 240 - 247
384, 384, 384, 384, 494, 494, 494, 0 // 248 - 255
- } },
+ },
+ nullptr },
{ "ZapfDingbats", // family name
"Normal", // style
@@ -703,7 +725,8 @@ const BuildinFont BuildinFontFace::m_aBuildinFonts[14]
883, 836, 836, 867, 867, 696, 696, 874, // 232 - 239
0, 874, 760, 946, 771, 865, 771, 888, // 240 - 247
967, 888, 831, 873, 927, 970, 918, 0 // 248 - 255
- } }
+ },
+ nullptr }
};
@@ -735,6 +758,6 @@ BuildinFontFace::CreateFontInstance(const FontSelectPattern& rFSP) const
return new BuildinFontInstance(*this, rFSP);
}
-} // namespace vcl
+} // namespace vcl::pdf
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/pdfbuildin_fonts.hxx b/vcl/source/gdi/pdfbuildin_fonts.hxx
index 8e91cbcb95b4..b7bf17fdb405 100644
--- a/vcl/source/gdi/pdfbuildin_fonts.hxx
+++ b/vcl/source/gdi/pdfbuildin_fonts.hxx
@@ -38,8 +38,10 @@ struct BuildinFont
FontWeight const m_eWeight;
FontItalic const m_eItalic;
int const m_aWidths[256];
+ mutable FontCharMapRef m_xFontCharMap;
OString getNameObject() const;
+ FontCharMapRef GetFontCharMap() const;
FontAttributes GetFontAttributes() const;
};
@@ -55,7 +57,6 @@ public:
class BuildinFontFace final : public PhysicalFontFace
{
-private:
static const BuildinFont m_aBuildinFonts[14];
const BuildinFont& mrBuildin;
@@ -67,6 +68,8 @@ public:
const BuildinFont& GetBuildinFont() const { return mrBuildin; }
sal_IntPtr GetFontId() const override { return reinterpret_cast<sal_IntPtr>(&mrBuildin); }
+ FontCharMapRef GetFontCharMap() const override { return mrBuildin.GetFontCharMap(); }
+ bool GetFontCapabilities(vcl::FontCapabilities&) const override { return false; }
static const BuildinFont& Get(int nId) { return m_aBuildinFonts[nId]; }
};
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 9ddf206572ac..6d8fec490c11 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -670,7 +670,12 @@ FontCharMapRef FreetypeFont::GetFontCharMap() const
return mxFontInfo->GetFontCharMap();
}
-const FontCharMapRef& FreetypeFontInfo::GetFontCharMap()
+bool FreetypeFont::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
+{
+ return mxFontInfo->GetFontCapabilities(rFontCapabilities);
+}
+
+FontCharMapRef FreetypeFontInfo::GetFontCharMap() const
{
// check if the charmap is already cached
if( mxFontCharMap.is() )
@@ -696,14 +701,14 @@ const FontCharMapRef& FreetypeFontInfo::GetFontCharMap()
return mxFontCharMap;
}
-bool FreetypeFont::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
+bool FreetypeFontInfo::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
{
bool bRet = false;
sal_uLong nLength = 0;
// load OS/2 table
- const FT_Byte* pOS2 = mxFontInfo->GetTable("OS/2", &nLength);
+ const FT_Byte* pOS2 = GetTable("OS/2", &nLength);
if (pOS2)
{
bRet = vcl::getTTCoverage(
commit 3c0dbea19492eecaf8e6e1cb0542a3f93c7298e3
Author: Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Sun Sep 13 20:30:43 2020 +0200
Commit: Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Sep 13 22:35:30 2020 +0200
tdf#125234 Qt5 add missing CFF font subsetting
Implemented like on Windows and MacOS.
Change-Id: Ib0d5125b77770446d4ca01efbb7c54d9c6bdb2e5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102594
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index c533ad1d599a..26b53ff694b8 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -231,6 +231,18 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
const OString aToFile(OUStringToOString(aSysPath, osl_getThreadTextEncoding()));
const int nOrigGlyphCount = nGlyphCount;
+ QByteArray aCFFtable = aRawFont.fontTable("CFF ");
+ if (!aCFFtable.isEmpty())
+ {
+ FILE* pOutFile = fopen(aToFile.getStr(), "wb");
+ rInfo.LoadFont(FontType::CFF_FONT, reinterpret_cast<const sal_uInt8*>(aCFFtable.data()),
+ aCFFtable.size());
+ bool bRet = rInfo.CreateFontSubset(FontType::TYPE1_PFB, pOutFile, nullptr, pGlyphIds,
+ pEncoding, nGlyphCount, pGlyphWidths);
+ fclose(pOutFile);
+ return bRet;
+ }
+
// get details about the subsetted font
rInfo.m_nFontType = FontType::SFNT_TTF;
rInfo.m_aPSName = toOUString(aRawFont.familyName());
commit bee46dbfd9986f324f20852987c05ac4339d4d25
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Sep 13 17:02:35 2020 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Sun Sep 13 22:12:32 2020 +0200
RangeNameBufferWK3 always dereferences its arg
Change-Id: I40c7c73d8d8fa2f9126f5895f8a6ed67a72bdf6b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102592
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sc/source/filter/inc/namebuff.hxx b/sc/source/filter/inc/namebuff.hxx
index 9f3c66bfb1dd..b56fee1d169e 100644
--- a/sc/source/filter/inc/namebuff.hxx
+++ b/sc/source/filter/inc/namebuff.hxx
@@ -97,7 +97,7 @@ private:
std::vector<Entry> maEntries;
public:
- RangeNameBufferWK3(const ScDocument* pDoc);
+ RangeNameBufferWK3(const ScDocument& rDoc);
~RangeNameBufferWK3();
void Add( const ScDocument* pDoc, const OUString& rName, const ScComplexRefData& rCRD );
inline void Add( const ScDocument* pDoc, const OUString& rName, const ScRange& aScRange );
diff --git a/sc/source/filter/lotus/lotus.cxx b/sc/source/filter/lotus/lotus.cxx
index b900c22a58b4..cbdb43e6be33 100644
--- a/sc/source/filter/lotus/lotus.cxx
+++ b/sc/source/filter/lotus/lotus.cxx
@@ -94,7 +94,7 @@ LotusContext::LotusContext(ScDocument* pDocP, rtl_TextEncoding eQ)
, maRangeNames()
, eFirstType( Lotus123Typ::X)
, eActType( Lotus123Typ::X)
- , pRngNmBffWK3( new RangeNameBufferWK3(pDocP) )
+ , pRngNmBffWK3( new RangeNameBufferWK3(*pDocP) )
, maAttrTable( *this )
{
}
diff --git a/sc/source/filter/lotus/tool.cxx b/sc/source/filter/lotus/tool.cxx
index 891eaaa556e0..dd868ee98996 100644
--- a/sc/source/filter/lotus/tool.cxx
+++ b/sc/source/filter/lotus/tool.cxx
@@ -426,8 +426,8 @@ void LotusRangeList::Append( const ScDocument* pDoc, std::unique_ptr<LotusRange>
nIdCnt++;
}
-RangeNameBufferWK3::RangeNameBufferWK3(const ScDocument* pDoc)
- : pScTokenArray( new ScTokenArray(*pDoc) )
+RangeNameBufferWK3::RangeNameBufferWK3(const ScDocument& rDoc)
+ : pScTokenArray( new ScTokenArray(rDoc) )
{
nIntCount = 1;
}
commit 399609c352b3f354e6857ae1beee6283018516e2
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Sep 13 16:56:14 2020 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Sun Sep 13 22:12:13 2020 +0200
ScFormulaCell ctor variant always dereferences its ScDocument arg
Change-Id: Ibf626d52cc7a5968c60a3ec1ea2b34e0331b7ef2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102589
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 0f77f5aa72cf..d57dda491d11 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -178,7 +178,7 @@ public:
ScFormulaCell* Clone() const;
ScFormulaCell* Clone( const ScAddress& rPos ) const;
- ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos );
+ ScFormulaCell( ScDocument& rDoc, const ScAddress& rPos );
/**
* Transfer the ownership of the passed token array instance to the
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index d2733fad4517..f40b6f921898 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -216,7 +216,7 @@ void CopyFromClipContext::setSingleCell( const ScAddress& rSrcPos, const ScColum
else
{
// Turn this into a formula cell with just the error code.
- ScFormulaCell* pErrCell = new ScFormulaCell(mpClipDoc, rSrcPos);
+ ScFormulaCell* pErrCell = new ScFormulaCell(*mpClipDoc, rSrcPos);
pErrCell->SetErrCode(nErr);
rSrcCell.set(pErrCell);
}
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 31b1630e219f..f2f8374df0c8 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1466,7 +1466,7 @@ class CopyByCloneHandler
if (nErr != FormulaError::NONE)
{
// error codes are cloned with values
- ScFormulaCell* pErrCell = new ScFormulaCell(mrDestCol.GetDoc(), aDestPos);
+ ScFormulaCell* pErrCell = new ScFormulaCell(*mrDestCol.GetDoc(), aDestPos);
pErrCell->SetErrCode(nErr);
mrDestCol.SetFormulaCell(maDestPos, nRow, pErrCell, meListenType);
setDefaultAttrToDest(nRow);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index cbd69dc2b5cd..f37ab25d2c51 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1275,7 +1275,7 @@ public:
insertRefCell(nSrcRow, nSrcRow + mnRowOffset);
else
{
- ScFormulaCell* pErrCell = new ScFormulaCell(mrDestCol.GetDoc(), aDestPos);
+ ScFormulaCell* pErrCell = new ScFormulaCell(*mrDestCol.GetDoc(), aDestPos);
pErrCell->SetErrCode(nErr);
mrDestCol.SetFormulaCell(
maDestBlockPos, nSrcRow + mnRowOffset, pErrCell);
@@ -1542,7 +1542,7 @@ class MixDataHandler
{
ScAddress aPos(mrDestColumn.GetCol(), nDestRow, mrDestColumn.GetTab());
- ScFormulaCell* pFC = new ScFormulaCell(mrDestColumn.GetDoc(), aPos);
+ ScFormulaCell* pFC = new ScFormulaCell(*mrDestColumn.GetDoc(), aPos);
pFC->SetErrCode(FormulaError::NoValue);
miNewCellsPos = maNewCells.set(miNewCellsPos, nDestRow-mnRowOffset, pFC);
@@ -2811,7 +2811,7 @@ void ScColumn::SetError( SCROW nRow, const FormulaError nError)
if (!GetDoc()->ValidRow(nRow))
return;
- ScFormulaCell* pCell = new ScFormulaCell(GetDoc(), ScAddress(nCol, nRow, nTab));
+ ScFormulaCell* pCell = new ScFormulaCell(*GetDoc(), ScAddress(nCol, nRow, nTab));
pCell->SetErrCode(nError);
std::vector<SCROW> aNewSharedRows;
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 975e232ca0dd..c981579a2104 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -650,7 +650,7 @@ void ScConditionEntry::Interpret( const ScAddress& rPos )
ScFormulaCell* pEff1 = pFCell1.get();
if ( bRelRef1 )
{
- pTemp1.reset(pFormula1 ? new ScFormulaCell(mpDoc, rPos, *pFormula1) : new ScFormulaCell(mpDoc, rPos));
+ pTemp1.reset(pFormula1 ? new ScFormulaCell(mpDoc, rPos, *pFormula1) : new ScFormulaCell(*mpDoc, rPos));
pEff1 = pTemp1.get();
}
if ( pEff1 )
@@ -680,7 +680,7 @@ void ScConditionEntry::Interpret( const ScAddress& rPos )
ScFormulaCell* pEff2 = pFCell2.get(); //@ 1!=2
if ( bRelRef2 )
{
- pTemp2.reset(pFormula2 ? new ScFormulaCell(mpDoc, rPos, *pFormula2) : new ScFormulaCell(mpDoc, rPos));
+ pTemp2.reset(pFormula2 ? new ScFormulaCell(mpDoc, rPos, *pFormula2) : new ScFormulaCell(*mpDoc, rPos));
pEff2 = pTemp2.get();
}
if ( pEff2 )
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 107d0569b03c..b9886d3abda2 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -603,7 +603,7 @@ void ScFormulaCellGroup::endAllGroupListening( ScDocument& rDoc )
mpImpl->m_AreaListeners.clear();
}
-ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos ) :
+ScFormulaCell::ScFormulaCell( ScDocument& rDoc, const ScAddress& rPos ) :
bDirty(false),
bTableOpDirty(false),
bChanged(false),
@@ -622,8 +622,8 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos ) :
nSeenInIteration(0),
nFormatType(SvNumFormatType::NUMBER),
eTempGrammar(formula::FormulaGrammar::GRAM_DEFAULT),
- pCode(new ScTokenArray(*pDoc)),
- pDocument(pDoc),
+ pCode(new ScTokenArray(rDoc)),
+ pDocument(&rDoc),
pPrevious(nullptr),
pNext(nullptr),
pPreviousTrack(nullptr),
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index e6d194dc513e..2f1cddf17a53 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -363,7 +363,7 @@ void ImportExcel::ReadBoolErr()
std::unique_ptr<ScTokenArray> pScTokArr = ErrorToFormula( nType != EXC_BOOLERR_BOOL, nValue, fValue );
ScFormulaCell* pCell = pScTokArr
? new ScFormulaCell(pD, aScPos, std::move(pScTokArr))
- : new ScFormulaCell(pD, aScPos);
+ : new ScFormulaCell(*pD, aScPos);
pCell->SetHybridDouble( fValue );
GetDocImport().setFormulaCell(aScPos, pCell);
}
diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx
index 685a03b8997b..8d822d10daf6 100644
--- a/sc/source/filter/excel/xipivot.cxx
+++ b/sc/source/filter/excel/xipivot.cxx
@@ -121,7 +121,7 @@ void XclImpPCItem::WriteToSource( XclImpRoot& rRoot, const ScAddress& rScPos ) c
XclTools::ErrorToEnum( fValue, true, nErrCode ) );
ScFormulaCell* pCell = pScTokArr
? new ScFormulaCell(&rDoc.getDoc(), rScPos, std::move(pScTokArr))
- : new ScFormulaCell(&rDoc.getDoc(), rScPos);
+ : new ScFormulaCell(rDoc.getDoc(), rScPos);
pCell->SetHybridDouble( fValue );
rDoc.setFormulaCell(rScPos, pCell);
}
diff --git a/sc/source/filter/lotus/lotimpop.cxx b/sc/source/filter/lotus/lotimpop.cxx
index 69cea998aa91..00f64cfd596f 100644
--- a/sc/source/filter/lotus/lotimpop.cxx
+++ b/sc/source/filter/lotus/lotimpop.cxx
@@ -254,7 +254,7 @@ void ImportLotus::Formulacell( sal_uInt16 n )
if (!aConv.good())
return;
- ScFormulaCell* pCell = pErg ? new ScFormulaCell(pD, aAddr, std::move(pErg)) : new ScFormulaCell(pD, aAddr);
+ ScFormulaCell* pCell = pErg ? new ScFormulaCell(pD, aAddr, std::move(pErg)) : new ScFormulaCell(*pD, aAddr);
pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE );
pD->EnsureTable(aAddr.Tab());
pD->SetFormulaCell(aAddr, pCell);
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index e1d90d36a14e..cb906b447aa5 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -6200,7 +6200,7 @@ void SAL_CALL ScCellObj::setFormulaString( const OUString& aFormula)
ScDocShell *pDocSh = GetDocShell();
if( pDocSh )
{
- ScFormulaCell* pCell = new ScFormulaCell( &pDocSh->GetDocument(), aCellPos );
+ ScFormulaCell* pCell = new ScFormulaCell( pDocSh->GetDocument(), aCellPos );
pCell->SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE );
pDocSh->GetDocFunc().SetFormulaCell(aCellPos, pCell, false);
}
commit f3af5f8e6897279dc8e4ad2695caf7f25937d608
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Sep 13 16:31:23 2020 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Sun Sep 13 22:11:52 2020 +0200
ScTokenArray ctor always dereferences its ScDocument* arg
Change-Id: Ie65ca182fd00600670c1e916343fef511d6cdcc8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102588
Tested-by: Caolán McNamara <caolanm at redhat.com>
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index fb8495fe7da1..3af5fbcb5ca1 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -62,7 +62,7 @@ class SAL_WARN_UNUSED SC_DLLPUBLIC ScTokenArray final : public formula::FormulaT
void CheckForThreading( const formula::FormulaToken& r );
public:
- ScTokenArray(const ScDocument* pDoc);
+ ScTokenArray(const ScDocument& rDoc);
ScTokenArray(ScSheetLimits&);
/** Assignment with incrementing references of FormulaToken entries
(not copied!) */
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index 1926d865669e..d2733fad4517 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -152,7 +152,7 @@ void CopyFromClipContext::setSingleCell( const ScAddress& rSrcPos, const ScColum
aRef.InitAddress(rSrcPos);
aRef.SetFlag3D(true);
- ScTokenArray aArr(mpClipDoc);
+ ScTokenArray aArr(*mpClipDoc);
aArr.AddSingleReference(aRef);
rSrcCell.set(new ScFormulaCell(mpClipDoc, rSrcPos, aArr));
return;
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index fec0cb3de38e..31b1630e219f 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1291,7 +1291,7 @@ class CopyAsLinkHandler
aRef.InitAddress(ScAddress(mrSrcCol.GetCol(), nRow, mrSrcCol.GetTab())); // Absolute reference.
aRef.SetFlag3D(true);
- ScTokenArray aArr(mrDestCol.GetDoc());
+ ScTokenArray aArr(*mrDestCol.GetDoc());
aArr.AddSingleReference(aRef);
return new ScFormulaCell(mrDestCol.GetDoc(), ScAddress(mrDestCol.GetCol(), nRow, mrDestCol.GetTab()), aArr);
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 43dc0c6b5338..cbd69dc2b5cd 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1095,7 +1095,7 @@ class CopyCellsFromClipHandler
aRef.InitAddress(aSrcPos);
aRef.SetFlag3D(true);
- ScTokenArray aArr(mrCxt.getDestDoc());
+ ScTokenArray aArr(*mrCxt.getDestDoc());
aArr.AddSingleReference(aRef);
mrDestCol.SetFormulaCell(
@@ -1429,7 +1429,7 @@ void ScColumn::CopyFromClip(
aRef.SetAbsRow(nDestRow - nDy); // Source row
aDestPos.SetRow( nDestRow );
- ScTokenArray aArr(GetDoc());
+ ScTokenArray aArr(*GetDoc());
aArr.AddSingleReference( aRef );
SetFormulaCell(nDestRow, new ScFormulaCell(pDocument, aDestPos, aArr));
}
@@ -1585,7 +1585,7 @@ public:
case sc::element_type_formula:
{
// Combination of value and at least one formula -> Create formula
- ScTokenArray aArr(mrDestColumn.GetDoc());
+ ScTokenArray aArr(*mrDestColumn.GetDoc());
// First row
aArr.AddDouble(f);
@@ -1643,7 +1643,7 @@ public:
case sc::element_type_numeric:
{
// Source is formula, and dest is value.
- ScTokenArray aArr(mrDestColumn.GetDoc());
+ ScTokenArray aArr(*mrDestColumn.GetDoc());
// First row
lcl_AddCode(aArr, p);
@@ -1672,7 +1672,7 @@ public:
case sc::element_type_formula:
{
// Both are formulas.
- ScTokenArray aArr(mrDestColumn.GetDoc());
+ ScTokenArray aArr(*mrDestColumn.GetDoc());
// First row
lcl_AddCode(aArr, p);
@@ -1752,7 +1752,7 @@ public:
break;
case sc::element_type_formula:
{
- ScTokenArray aArr(mrDestColumn.GetDoc());
+ ScTokenArray aArr(*mrDestColumn.GetDoc());
// First row
ScFormulaCell* pSrc = sc::formula_block::at(*aPos.first->data, aPos.second);
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 12857f329295..975e232ca0dd 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -352,7 +352,7 @@ void ScConditionEntry::Compile( const OUString& rExpr1, const OUString& rExpr2,
if ( mpDoc->IsImportingXML() && !bTextToReal )
{
// temporary formula string as string tokens
- pFormula1.reset( new ScTokenArray(mpDoc) );
+ pFormula1.reset( new ScTokenArray(*mpDoc) );
pFormula1->AssignXMLString( rExpr1, rExprNmsp1 );
// bRelRef1 is set when the formula is compiled again (CompileXML)
}
@@ -371,7 +371,7 @@ void ScConditionEntry::Compile( const OUString& rExpr1, const OUString& rExpr2,
if ( mpDoc->IsImportingXML() && !bTextToReal )
{
// temporary formula string as string tokens
- pFormula2.reset( new ScTokenArray(mpDoc) );
+ pFormula2.reset( new ScTokenArray(*mpDoc) );
pFormula2->AssignXMLString( rExpr2, rExprNmsp2 );
// bRelRef2 is set when the formula is compiled again (CompileXML)
}
@@ -1289,7 +1289,7 @@ std::unique_ptr<ScTokenArray> ScConditionEntry::CreateFlatCopiedTokenArray( sal_
pRet.reset(new ScTokenArray( *pFormula1 ));
else
{
- pRet.reset(new ScTokenArray(mpDoc));
+ pRet.reset(new ScTokenArray(*mpDoc));
if (bIsStr1)
{
svl::SharedStringPool& rSPool = mpDoc->GetSharedStringPool();
@@ -1305,7 +1305,7 @@ std::unique_ptr<ScTokenArray> ScConditionEntry::CreateFlatCopiedTokenArray( sal_
pRet.reset(new ScTokenArray( *pFormula2 ));
else
{
- pRet.reset(new ScTokenArray(mpDoc));
+ pRet.reset(new ScTokenArray(*mpDoc));
if (bIsStr2)
{
svl::SharedStringPool& rSPool = mpDoc->GetSharedStringPool();
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 570f90e24cdf..e3c8e55e0cd2 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -313,7 +313,7 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
aRefData.SetTabRel( true );
aRefData.SetAddress(GetSheetLimits(), aBasePos, aBasePos);
- ScTokenArray aArr(this); // consists only of one single reference token.
+ ScTokenArray aArr(*this); // consists only of one single reference token.
formula::FormulaToken* t = aArr.AddMatrixSingleReference(aRefData);
for (const SCTAB& nTab : rMark)
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index ec528a502bfb..224dfeacae6f 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -410,7 +410,7 @@ void ScDocumentImport::setMatrixCells(
aRefData.SetTabRel(true);
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list