[Libreoffice-commits] core.git: Branch 'feature/drop-findcmap' - 54 commits - cui/source distro-configs/Jenkins extras/source filter/source helpcontent2 include/vcl sc/inc sc/qa sc/source sc/uiconfig sd/qa solenv/sanitizers sw/source vcl/inc vcl/qt5 vcl/quartz vcl/source vcl/unx vcl/win
Jan-Marek Glogowski (via logerrit)
logerrit at kemper.freedesktop.org
Mon Sep 14 19:57:04 UTC 2020
Rebased ref, commits from common ancestor:
commit 94da816f900ad588a49e84a07c4e788a27a13238
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: Mon Sep 14 21:56:03 2020 +0200
WIN OSX Qt5 unify CreateFontSubset code
This is basically just some refactoring. Most 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 86cb718809b3..8711364ed46f 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 8836f7dd71d9a5f7a85b8ae7b44632f0b58542bf
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: Mon Sep 14 21:56:03 2020 +0200
Qt5 implement GetGlyphWidths
Basically implement it the same way then Windows and MacOS.
Change-Id: I643581af49aeb9274505e90e12acbe5bcf0c98fb
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
commit 8f98e74ed5979d68b306dd00184a3bbdc44bdcec
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: Mon Sep 14 21:56:03 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 cc39be0f02cd4578a011fb3e00935549205f7ed6
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: Mon Sep 14 21:56:03 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 6bc4321d479d..777b2b1115e4 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -936,11 +936,7 @@ void SalGraphics::GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF,
continue;
sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
-#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
- sal_uInt32 nGlyph = MapChar(&rTTF, nUcsChar);
-#else
sal_uInt32 nGlyph = xFCMap->GetGlyphIndex(nUcsChar);
-#endif
if (nGlyph > 0)
rUnicodeEnc[nUcsChar] = nGlyph;
}
commit 8c804f29382bacfc58fcb6722da129a420dc4870
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: Mon Sep 14 21:56:03 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..6bc4321d479d 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,54 @@ 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);
+#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
+ sal_uInt32 nGlyph = MapChar(&rTTF, nUcsChar);
+#else
+ sal_uInt32 nGlyph = xFCMap->GetGlyphIndex(nUcsChar);
+#endif
+ 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 60da0a2d3717c763abc1b103f8ca77c845f5be30
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: Mon Sep 14 21:56:03 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..4d74cf899069 100644
--- a/vcl/source/gdi/pdfbuildin_fonts.cxx
+++ b/vcl/source/gdi/pdfbuildin_fonts.cxx
@@ -21,8 +21,6 @@
#include <rtl/strbuf.hxx>
-using namespace vcl;
-
namespace vcl::pdf
{
OString BuildinFont::getNameObject() const
@@ -43,6 +41,16 @@ OString BuildinFont::getNameObject() const
return aBuf.makeStringAndClear();
}
+FontCharMapRef BuildinFont::GetFontCharMap() const
+{
+ assert(false && "pdf::BuildinFont doesn't provide correct char maps!");
+ if (m_xFontCharMap.is())
+ return m_xFontCharMap;
+
+ m_xFontCharMap = FontCharMap::GetDefaultMap(m_eCharSet != RTL_TEXTENCODING_MS_1252);
+ return m_xFontCharMap;
+}
+
FontAttributes BuildinFont::GetFontAttributes() const
{
FontAttributes aDFA;
@@ -103,7 +111,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 +158,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 +205,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 +252,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 +299,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 +346,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 +393,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 +440,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 +487,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 +534,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 +581,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 +628,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 +677,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 +724,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 +757,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 4d85d2d482f640a4b5d66995e099895cff6f9c77
Author: Xisco Fauli <xiscofauli at libreoffice.org>
AuthorDate: Mon Sep 14 12:12:32 2020 +0200
Commit: Xisco Fauli <xiscofauli at libreoffice.org>
CommitDate: Mon Sep 14 20:51:03 2020 +0200
tdf#133327: sc_subsequent_filters_test: Add unittest
Change-Id: Icf8fff02fd0ad9576cb9773ca18a228a42daa34f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102659
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli at libreoffice.org>
diff --git a/sc/qa/unit/data/ods/tdf133327.ods b/sc/qa/unit/data/ods/tdf133327.ods
new file mode 100644
index 000000000000..164391488fa5
Binary files /dev/null and b/sc/qa/unit/data/ods/tdf133327.ods differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 81a222051835..0f0f39a419c0 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -222,6 +222,7 @@ public:
void testHiddenSheetsXLSX();
void testRelFormulaValidationXLS();
void testTdf130132();
+ void testTdf133327();
void testColumnStyle2XLSX();
void testAutofilterXLSX();
@@ -389,6 +390,7 @@ public:
CPPUNIT_TEST(testRefStringXLSX);
CPPUNIT_TEST(testRelFormulaValidationXLS);
CPPUNIT_TEST(testTdf130132);
+ CPPUNIT_TEST(testTdf133327);
CPPUNIT_TEST(testColumnStyle2XLSX);
CPPUNIT_TEST(testAutofilterXLSX);
@@ -3572,6 +3574,25 @@ void ScFiltersTest::testTdf130132()
}
}
+void ScFiltersTest::testTdf133327()
+{
+ ScDocShellRef xDocSh = loadDoc("tdf133327.", FORMAT_ODS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
+
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ const ScPatternAttr* pAttr = rDoc.GetPattern(250, 1, 0);
+
+ const SfxPoolItem& rItem = pAttr->GetItem(ATTR_BACKGROUND);
+ const SvxBrushItem& rBackground = static_cast<const SvxBrushItem&>(rItem);
+ const Color& rColor = rBackground.GetColor();
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: Color: R:255 G:255 B: 0
+ // - Actual : Color: R:255 G:255 B: 255
+ CPPUNIT_ASSERT_EQUAL(Color(255, 255, 0), rColor);
+}
+
void ScFiltersTest::testColumnStyle2XLSX()
{
ScDocShellRef xDocSh = loadDoc("column_style.", FORMAT_XLSX);
commit be714ddd3048ab41d653c3fbd13c83079e44c198
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Mon Sep 14 09:34:04 2020 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Mon Sep 14 20:23:20 2020 +0200
ScFormulaListener dtor always dereferences its ScDocument* member
Change-Id: I7eb22d693fc61a8ce46bb14c4fc421e7d0454684
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102654
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index dce4563d0c90..cd49a361a324 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -184,7 +184,7 @@ class ScFormulaListener final : public SvtListener
{
private:
mutable bool mbDirty;
- ScDocument* mpDoc;
+ ScDocument& mrDoc;
std::function<void()> maCallbackFunction;
void startListening(const ScTokenArray* pTokens, const ScRange& rPos);
@@ -192,8 +192,8 @@ private:
public:
explicit ScFormulaListener(ScFormulaCell* pCell);
- explicit ScFormulaListener(ScDocument* pDoc);
- explicit ScFormulaListener(ScDocument* pDoc, const ScRangeList& rRange);
+ explicit ScFormulaListener(ScDocument& rDoc);
+ explicit ScFormulaListener(ScDocument& rDoc, const ScRangeList& rRange);
virtual ~ScFormulaListener() override;
void Notify( const SfxHint& rHint ) override;
@@ -348,7 +348,7 @@ class SC_DLLPUBLIC ScConditionEntry : public ScFormatEntry
public:
ScConditionEntry( ScConditionMode eOper,
const OUString& rExpr1, const OUString& rExpr2,
- ScDocument* pDocument, const ScAddress& rPos,
+ ScDocument& rDocument, const ScAddress& rPos,
const OUString& rExprNmsp1, const OUString& rExprNmsp2,
formula::FormulaGrammar::Grammar eGrammar1,
formula::FormulaGrammar::Grammar eGrammar2,
@@ -454,7 +454,7 @@ class SC_DLLPUBLIC ScCondFormatEntry final : public ScConditionEntry
public:
ScCondFormatEntry( ScConditionMode eOper,
const OUString& rExpr1, const OUString& rExpr2,
- ScDocument* pDocument, const ScAddress& rPos,
+ ScDocument& rDocument, const ScAddress& rPos,
const OUString& rStyle,
const OUString& rExprNmsp1 = EMPTY_OUSTRING,
const OUString& rExprNmsp2 = EMPTY_OUSTRING,
diff --git a/sc/inc/validat.hxx b/sc/inc/validat.hxx
index d4e92bd9ce4e..36b3ee5a1584 100644
--- a/sc/inc/validat.hxx
+++ b/sc/inc/validat.hxx
@@ -83,7 +83,7 @@ private:
public:
ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
const OUString& rExpr1, const OUString& rExpr2,
- ScDocument* pDocument, const ScAddress& rPos,
+ ScDocument& rDocument, const ScAddress& rPos,
const OUString& rExprNmsp1 = EMPTY_OUSTRING, const OUString& rExprNmsp2 = EMPTY_OUSTRING,
formula::FormulaGrammar::Grammar eGrammar1 = formula::FormulaGrammar::GRAM_DEFAULT,
formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT );
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 459f72ea95f6..81a222051835 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -1327,7 +1327,7 @@ void checkValiditationEntries( const ValDataTestParams& rVDTParams )
//create expected data validation entry
ScValidationData aValData(
rVDTParams.eValMode, rVDTParams.eCondOp, rVDTParams.aStrVal1,
- rVDTParams.aStrVal2, &rDoc, rVDTParams.aPosition, EMPTY_OUSTRING,
+ rVDTParams.aStrVal2, rDoc, rVDTParams.aPosition, EMPTY_OUSTRING,
EMPTY_OUSTRING, rDoc.GetStorageGrammar(), rDoc.GetStorageGrammar()
);
aValData.SetIgnoreBlank( true );
diff --git a/sc/qa/unit/ucalc_condformat.cxx b/sc/qa/unit/ucalc_condformat.cxx
index 3c9fcefee6d2..d6f32d13b7c4 100644
--- a/sc/qa/unit/ucalc_condformat.cxx
+++ b/sc/qa/unit/ucalc_condformat.cxx
@@ -101,7 +101,7 @@ void Test::testCondFormatINSDEL()
auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
ScRangeList aRangeList(ScRange(0,0,0,0,3,0));
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
@@ -127,7 +127,7 @@ void Test::testCondFormatInsertCol()
ScRangeList aRangeList(ScRange(0,0,0,3,3,0));
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
@@ -150,7 +150,7 @@ void Test::testCondFormatInsertRow()
ScRangeList aRangeList(ScRange(0,0,0,3,3,0));
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
@@ -177,7 +177,7 @@ void Test::testCondFormatInsertDeleteSheets()
// Add condition in which if the value equals 2, set the "Result" style.
ScCondFormatEntry* pEntry = new ScCondFormatEntry(
- ScConditionMode::Equal, "=2", "" , m_pDoc, ScAddress(0,0,0), ScResId(STR_STYLENAME_RESULT));
+ ScConditionMode::Equal, "=2", "" , *m_pDoc, ScAddress(0,0,0), ScResId(STR_STYLENAME_RESULT));
pFormatTmp->AddEntry(pEntry);
// Apply the format to the range.
@@ -280,7 +280,7 @@ void Test::testCondCopyPaste()
ScRangeList aRangeList(aCondFormatRange);
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
@@ -319,7 +319,7 @@ void Test::testCondCopyPasteSingleCell()
ScRangeList aRangeList(aCondFormatRange);
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
@@ -358,7 +358,7 @@ void Test::testCondCopyPasteSingleCellToRange()
ScRangeList aRangeList(aCondFormatRange);
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
@@ -403,7 +403,7 @@ void Test::testCondCopyPasteSingleCellIntoSameFormatRange()
ScRangeList aRangeList(aCondFormatRange);
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct, "=B2", "", m_pDoc, ScAddress(0, 0, 0), ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct, "=B2", "", *m_pDoc, ScAddress(0, 0, 0), ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
@@ -440,7 +440,7 @@ void Test::testCondCopyPasteSingleRowToRange()
ScRangeList aRangeList(aCondFormatRange);
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
auto pFormatTmp = pFormat.get();
m_pDoc->AddCondFormat(std::move(pFormat), 0);
@@ -472,7 +472,7 @@ void Test::testCondCopyPasteSingleRowToRange2()
ScRangeList aRangeList(aCondFormatRange);
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
m_pDoc->AddCondFormat(std::move(pFormat), 0);
@@ -502,7 +502,7 @@ void Test::testCondCopyPasteSheetBetweenDoc()
ScRangeList aRangeList(aCondFormatRange);
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
m_pDoc->AddCondFormat(std::move(pFormat), 0);
@@ -524,7 +524,7 @@ void Test::testCondCopyPasteSheet()
ScRangeList aRangeList(aCondFormatRange);
pFormat->SetRange(aRangeList);
- ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
+ ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
pFormat->AddEntry(pEntry);
m_pDoc->AddCondFormat(std::move(pFormat), 0);
@@ -749,7 +749,7 @@ void Test::testCondFormatEndsWithStr()
{
m_pDoc->InsertTab(0, "Test");
- ScConditionEntry aEntry(ScConditionMode::EndsWith, "\"TestString\"", "", m_pDoc, ScAddress(),
+ ScConditionEntry aEntry(ScConditionMode::EndsWith, "\"TestString\"", "", *m_pDoc, ScAddress(),
"", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
svl::SharedStringPool& rStringPool = m_pDoc->GetSharedStringPool();
@@ -767,7 +767,7 @@ void Test::testCondFormatEndsWithVal()
{
m_pDoc->InsertTab(0, "Test");
- ScConditionEntry aEntry(ScConditionMode::EndsWith, "2", "", m_pDoc, ScAddress(),
+ ScConditionEntry aEntry(ScConditionMode::EndsWith, "2", "", *m_pDoc, ScAddress(),
"", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
for (sal_Int32 i = 0; i < 15; ++i)
@@ -791,7 +791,7 @@ void Test::testFormulaListenerSingleCellToSingleCell()
std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
- ScFormulaListener aListener(m_pDoc);
+ ScFormulaListener aListener(*m_pDoc);
aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
@@ -809,7 +809,7 @@ void Test::testFormulaListenerSingleCellToMultipleCells()
std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
- ScFormulaListener aListener(m_pDoc);
+ ScFormulaListener aListener(*m_pDoc);
aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
@@ -827,7 +827,7 @@ void Test::testFormulaListenerMultipleCellsToSingleCell()
std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
- ScFormulaListener aListener(m_pDoc);
+ ScFormulaListener aListener(*m_pDoc);
aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
@@ -845,7 +845,7 @@ void Test::testFormulaListenerMultipleCellsToMultipleCells()
std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
- ScFormulaListener aListener(m_pDoc);
+ ScFormulaListener aListener(*m_pDoc);
aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
@@ -862,7 +862,7 @@ void Test::testFormulaListenerUpdateInsertTab()
ScCompiler aCompiler(m_pDoc, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH);
std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
- ScFormulaListener aListener(m_pDoc);
+ ScFormulaListener aListener(*m_pDoc);
aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
CPPUNIT_ASSERT(!aListener.NeedsRepaint());
@@ -887,7 +887,7 @@ void Test::testFormulaListenerUpdateDeleteTab()
ScCompiler aCompiler(m_pDoc, ScAddress(10, 10, 1), formula::FormulaGrammar::GRAM_ENGLISH);
std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
- ScFormulaListener aListener(m_pDoc);
+ ScFormulaListener aListener(*m_pDoc);
aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 1));
CPPUNIT_ASSERT(!aListener.NeedsRepaint());
@@ -905,7 +905,7 @@ void Test::testCondFormatUpdateMoveTab()
m_pDoc->InsertTab(0, "test");
m_pDoc->InsertTab(1, "Test2");
- ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+ ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", *m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
@@ -941,7 +941,7 @@ void Test::testCondFormatUpdateInsertTab()
{
m_pDoc->InsertTab(0, "test");
- ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+ ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", *m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
@@ -981,7 +981,7 @@ void Test::testCondFormatUpdateDeleteTab()
m_pDoc->InsertTab(0, "test");
m_pDoc->InsertTab(1, "Test2");
- ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", m_pDoc, ScAddress(10, 10, 1), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+ ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", *m_pDoc, ScAddress(10, 10, 1), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
pFormat->SetRange(ScRange(10, 10, 1, 10, 12, 1));
@@ -1014,7 +1014,7 @@ void Test::testCondFormatUpdateReference()
m_pDoc->InsertTab(0, "test");
m_pDoc->InsertTab(1, "Test2");
- ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+ ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", *m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
@@ -1038,7 +1038,7 @@ void Test::testCondFormatUpdateReferenceDelRow()
{
m_pDoc->InsertTab(0, "test");
- ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+ ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", *m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
pFormat->SetRange(ScRange(0, 5, 0, 0, 5, 0));
@@ -1059,7 +1059,7 @@ void Test::testCondFormatUpdateReferenceInsRow()
{
m_pDoc->InsertTab(0, "test");
- ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+ ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", *m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
pFormat->SetRange(ScRange(0, 5, 0, 0, 5, 0));
@@ -1080,7 +1080,7 @@ void Test::testCondFormatUndoList()
{
m_pDoc->InsertTab(0, "test");
- ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
+ ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", *m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
pFormat->AddEntry(pEntry);
@@ -1128,7 +1128,7 @@ sal_uInt32 addSingleCellCondFormat(ScDocument* pDoc, const ScAddress& rAddr, sal
pFormat->SetRange(aRangeList);
ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct, rCondition, "",
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list