vcl: Make ImplFontCharMap a pImpl and move functions to FontCharMap

To do this, I've made FontCharMap a friend class for ImplFontCharMap,
and have moved the functions directly into FontCharMap. In this patch,
I am attempting to stop the direct use of ImplFontCharMap by anything
other than FontCharMap. However, FontCharMap itself requires a
refcounter, so we will use FontCharMapPtr to access the font character
map.

Change-Id: I509b990a8cbd911c5cc1572c7d24fc5348ca06d9
Reviewed-on: https://gerrit.libreoffice.org/11823
Reviewed-by: Chris Sherlock <chris.sherlock79@gmail.com>
Tested-by: Chris Sherlock <chris.sherlock79@gmail.com>
This commit is contained in:
Chris Sherlock 2014-10-06 18:16:16 +11:00
parent bb1d4f8c9a
commit f6d61562d4
29 changed files with 411 additions and 386 deletions

View File

@ -446,9 +446,9 @@ IMPL_LINK_NOARG(SvxCharacterMap, FontSelectHdl)
bool bNeedSubset = (aFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL);
if( bNeedSubset )
{
FontCharMap aFontCharMap;
m_pShowSet->GetFontCharMap( aFontCharMap );
pSubsetMap = new SubsetMap( &aFontCharMap );
FontCharMapPtr pFontCharMap( new FontCharMap() );
m_pShowSet->GetFontCharMap( pFontCharMap );
pSubsetMap = new SubsetMap( pFontCharMap );
// update subset listbox for new font's unicode subsets
// TODO: is it worth to improve the stupid linear search?

View File

@ -111,7 +111,7 @@ private:
sal_Int32 nSelectedIndex;
FontCharMap maFontCharMap;
FontCharMapPtr mpFontCharMap;
ScrollBar aVscrollSB;
private:

View File

@ -63,7 +63,7 @@ typedef ::std::list<Subset> SubsetList;
class SVX_DLLPUBLIC SubsetMap : private Resource
{
public:
SubsetMap( const FontCharMap* );
SubsetMap( const FontCharMapPtr );
const Subset* GetSubsetByUnicode( sal_UCS4 ) const;
const Subset* GetNextSubset( bool bFirst ) const;
@ -73,7 +73,7 @@ private:
mutable SubsetList::const_iterator maSubsetIterator;
SVX_DLLPRIVATE void InitList();
SVX_DLLPRIVATE void ApplyCharMap( const FontCharMap* );
SVX_DLLPRIVATE void ApplyCharMap( const FontCharMapPtr );
};
#endif

View File

@ -28,9 +28,11 @@
class ImplFontMetric;
class ImplFontCharMap;
class CmapResult;
typedef sal_uInt32 sal_UCS4;
typedef boost::intrusive_ptr< ImplFontCharMap > ImplFontCharMapPtr;
typedef boost::intrusive_ptr< FontCharMap > FontCharMapPtr;
namespace vcl {
@ -96,16 +98,20 @@ inline std::basic_ostream<charT, traits> & operator <<(
class VCL_DLLPUBLIC FontCharMap
{
private:
ImplFontCharMapPtr mpImplFontCharMap;
public:
/** A new FontCharMap is created based on a "default" map, which includes
all codepoints in the Unicode BMP range, including surrogates.
**/
FontCharMap();
FontCharMap( const CmapResult& rCR );
~FontCharMap();
/** Get the default font character map
@returns the default font character map.
*/
static FontCharMapPtr GetDefaultMap( bool bSymbols=false );
/** Determines if the font character map is the "default". The default map
includes all codepoints in the Unicode BMP range, including surrogates.
@ -119,8 +125,8 @@ public:
*/
bool HasChar( sal_UCS4 ) const;
/** UCS4 codepoints.
/** Returns the number of chars supported by the font, which
are inside the unicode range from cMin to cMax (inclusive).
@param cMin Lowest codepoint in range to be counted
@param cMax Highest codepoitn in range to be counted
@ -190,16 +196,37 @@ public:
*/
sal_UCS4 GetCharFromIndex( int nCharIndex ) const;
int GetGlyphIndex( sal_UCS4 ) const;
private:
ImplFontCharMapPtr mpImplFontCharMap;
friend class ::OutputDevice;
void Reset( const ImplFontCharMapPtr pNewMap = NULL );
friend void intrusive_ptr_release(FontCharMap* pFontCharMap);
friend void intrusive_ptr_add_ref(FontCharMap* pFontCharMap);
int findRangeIndex( sal_uInt32 ) const;
FontCharMap( ImplFontCharMapPtr pIFCMap );
sal_uInt32 mnRefCount;
// prevent assignment and copy construction
FontCharMap( const FontCharMap& );
void operator=( const FontCharMap& );
};
inline void intrusive_ptr_add_ref(FontCharMap* pFontCharMap)
{
++pFontCharMap->mnRefCount;
}
inline void intrusive_ptr_release(FontCharMap* pFontCharMap)
{
if (--pFontCharMap->mnRefCount == 0)
delete pFontCharMap;
}
class VCL_DLLPUBLIC TextRectInfo
{
friend class ::OutputDevice;

View File

@ -50,6 +50,7 @@
# undef check
#endif
#include <boost/ptr_container/ptr_deque.hpp>
#include <boost/intrusive_ptr.hpp>
#include <com/sun/star/drawing/LineCap.hpp>
#include <com/sun/star/uno/Reference.h>
@ -235,6 +236,8 @@ class FontSelectPattern;
class ImplFontMetricData;
class VCLXGraphics;
typedef boost::intrusive_ptr< FontCharMap > FontCharMapPtr;
namespace vcl {
class FontInfo;
}
@ -1145,7 +1148,7 @@ public:
FontMetric GetFontMetric() const;
FontMetric GetFontMetric( const vcl::Font& rFont ) const;
bool GetFontCharMap( FontCharMap& rFontCharMap ) const;
bool GetFontCharMap( FontCharMapPtr& rFontCharMap ) const;
bool GetFontCapabilities( vcl::FontCapabilities& rFontCapabilities ) const;
/** Retrieve detailed font information in platform independent structure

View File

@ -446,39 +446,41 @@ void XclImpFont::GuessScriptType()
if( OutputDevice* pPrinter = GetPrinter() )
{
vcl::Font aFont( maData.maName, Size( 0, 10 ) );
FontCharMap aCharMap;
FontCharMapPtr pCharMap;
pPrinter->SetFont( aFont );
if( pPrinter->GetFontCharMap( aCharMap ) )
if( pPrinter->GetFontCharMap( pCharMap ) )
{
// CJK fonts
mbHasAsian =
aCharMap.HasChar( 0x3041 ) || // 3040-309F: Hiragana
aCharMap.HasChar( 0x30A1 ) || // 30A0-30FF: Katakana
aCharMap.HasChar( 0x3111 ) || // 3100-312F: Bopomofo
aCharMap.HasChar( 0x3131 ) || // 3130-318F: Hangul Compatibility Jamo
aCharMap.HasChar( 0x3301 ) || // 3300-33FF: CJK Compatibility
aCharMap.HasChar( 0x3401 ) || // 3400-4DBF: CJK Unified Ideographs Extension A
aCharMap.HasChar( 0x4E01 ) || // 4E00-9FAF: CJK Unified Ideographs
aCharMap.HasChar( 0x7E01 ) || // 4E00-9FAF: CJK unified ideographs
aCharMap.HasChar( 0xA001 ) || // A001-A48F: Yi Syllables
aCharMap.HasChar( 0xAC01 ) || // AC00-D7AF: Hangul Syllables
aCharMap.HasChar( 0xCC01 ) || // AC00-D7AF: Hangul Syllables
aCharMap.HasChar( 0xF901 ) || // F900-FAFF: CJK Compatibility Ideographs
aCharMap.HasChar( 0xFF71 ); // FF00-FFEF: Halfwidth/Fullwidth Forms
pCharMap->HasChar( 0x3041 ) || // 3040-309F: Hiragana
pCharMap->HasChar( 0x30A1 ) || // 30A0-30FF: Katakana
pCharMap->HasChar( 0x3111 ) || // 3100-312F: Bopomofo
pCharMap->HasChar( 0x3131 ) || // 3130-318F: Hangul Compatibility Jamo
pCharMap->HasChar( 0x3301 ) || // 3300-33FF: CJK Compatibility
pCharMap->HasChar( 0x3401 ) || // 3400-4DBF: CJK Unified Ideographs Extension A
pCharMap->HasChar( 0x4E01 ) || // 4E00-9FAF: CJK Unified Ideographs
pCharMap->HasChar( 0x7E01 ) || // 4E00-9FAF: CJK unified ideographs
pCharMap->HasChar( 0xA001 ) || // A001-A48F: Yi Syllables
pCharMap->HasChar( 0xAC01 ) || // AC00-D7AF: Hangul Syllables
pCharMap->HasChar( 0xCC01 ) || // AC00-D7AF: Hangul Syllables
pCharMap->HasChar( 0xF901 ) || // F900-FAFF: CJK Compatibility Ideographs
pCharMap->HasChar( 0xFF71 ); // FF00-FFEF: Halfwidth/Fullwidth Forms
// CTL fonts
mbHasCmplx =
aCharMap.HasChar( 0x05D1 ) || // 0590-05FF: Hebrew
aCharMap.HasChar( 0x0631 ) || // 0600-06FF: Arabic
aCharMap.HasChar( 0x0721 ) || // 0700-074F: Syriac
aCharMap.HasChar( 0x0911 ) || // 0900-0DFF: Indic scripts
aCharMap.HasChar( 0x0E01 ) || // 0E00-0E7F: Thai
aCharMap.HasChar( 0xFB21 ) || // FB1D-FB4F: Hebrew Presentation Forms
aCharMap.HasChar( 0xFB51 ) || // FB50-FDFF: Arabic Presentation Forms-A
aCharMap.HasChar( 0xFE71 ); // FE70-FEFF: Arabic Presentation Forms-B
pCharMap->HasChar( 0x05D1 ) || // 0590-05FF: Hebrew
pCharMap->HasChar( 0x0631 ) || // 0600-06FF: Arabic
pCharMap->HasChar( 0x0721 ) || // 0700-074F: Syriac
pCharMap->HasChar( 0x0911 ) || // 0900-0DFF: Indic scripts
pCharMap->HasChar( 0x0E01 ) || // 0E00-0E7F: Thai
pCharMap->HasChar( 0xFB21 ) || // FB1D-FB4F: Hebrew Presentation Forms
pCharMap->HasChar( 0xFB51 ) || // FB50-FDFF: Arabic Presentation Forms-A
pCharMap->HasChar( 0xFE71 ); // FE70-FEFF: Arabic Presentation Forms-B
// Western fonts
mbHasWstrn = (!mbHasAsian && !mbHasCmplx) || aCharMap.HasChar( 'A' );
mbHasWstrn = (!mbHasAsian && !mbHasCmplx) || pCharMap->HasChar( 'A' );
}
pCharMap = 0;
}
}

View File

@ -2277,11 +2277,11 @@ void SmSymDefineDialog::SetFont(const OUString &rFontName, const OUString &rStyl
pSymbolDisplay->SetFont(aFI);
// update subset listbox for new font's unicode subsets
FontCharMap aFontCharMap;
pCharsetDisplay->GetFontCharMap( aFontCharMap );
FontCharMapPtr pFontCharMap;
pCharsetDisplay->GetFontCharMap( pFontCharMap );
if (pSubsetMap)
delete pSubsetMap;
pSubsetMap = new SubsetMap( &aFontCharMap );
pSubsetMap = new SubsetMap( pFontCharMap );
pFontsSubsetLB->Clear();
bool bFirst = true;
@ -2298,6 +2298,8 @@ void SmSymDefineDialog::SetFont(const OUString &rFontName, const OUString &rStyl
if( bFirst )
pFontsSubsetLB->SetNoSelection();
pFontsSubsetLB->Enable( !bFirst );
pFontCharMap = 0;
}

View File

@ -164,8 +164,8 @@ OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice)
if (!bOpenSymbol)
{
FontCharMap aFontCharMap;
bool bHasCharMap = rDevice.GetFontCharMap(aFontCharMap);
FontCharMapPtr pFontCharMap;
bool bHasCharMap = rDevice.GetFontCharMap(pFontCharMap);
if( bHasCharMap )
{
// use some sample characters available in the font
@ -175,7 +175,7 @@ OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice)
sal_uInt32 cNewChar = 0xFF00;
const int nMaxCount = sizeof(aText)/sizeof(*aText) - 1;
int nSkip = aFontCharMap.GetCharCount() / nMaxCount;
int nSkip = pFontCharMap->GetCharCount() / nMaxCount;
if( nSkip > 10 )
nSkip = 10;
else if( nSkip <= 0 )
@ -184,7 +184,7 @@ OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice)
{
sal_uInt32 cOldChar = cNewChar;
for( int j = nSkip; --j >= 0; )
cNewChar = aFontCharMap.GetPrevChar( cNewChar );
cNewChar = pFontCharMap->GetPrevChar( cNewChar );
if( cOldChar == cNewChar )
break;
aText[ i ] = static_cast<sal_Unicode>(cNewChar); // TODO: support UCS4 samples
@ -193,6 +193,8 @@ OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice)
return OUString(aText);
}
pFontCharMap = 0;
}
static const sal_Unicode aImplSymbolFontText[] = {

View File

@ -224,7 +224,7 @@ int SvxShowCharSet::LastInView( void ) const
{
sal_uIntPtr nIndex = FirstInView();
nIndex += ROW_COUNT * COLUMN_COUNT - 1;
sal_uIntPtr nCompare = sal::static_int_cast<sal_uIntPtr>( maFontCharMap.GetCharCount() - 1 );
sal_uIntPtr nCompare = sal::static_int_cast<sal_uIntPtr>( mpFontCharMap->GetCharCount() - 1 );
if( nIndex > nCompare )
nIndex = nCompare;
return nIndex;
@ -288,7 +288,7 @@ void SvxShowCharSet::KeyInput( const KeyEvent& rKEvt )
tmpSelected = 0;
break;
case KEY_END:
tmpSelected = maFontCharMap.GetCharCount() - 1;
tmpSelected = mpFontCharMap->GetCharCount() - 1;
break;
case KEY_TAB: // some fonts have a character at these unicode control codes
case KEY_ESCAPE:
@ -299,8 +299,8 @@ void SvxShowCharSet::KeyInput( const KeyEvent& rKEvt )
default:
{
sal_UCS4 cChar = rKEvt.GetCharCode();
sal_UCS4 cNext = maFontCharMap.GetNextChar( cChar - 1 );
tmpSelected = maFontCharMap.GetIndexFromChar( cNext );
sal_UCS4 cNext = mpFontCharMap->GetNextChar( cChar - 1 );
tmpSelected = mpFontCharMap->GetIndexFromChar( cNext );
if( tmpSelected < 0 || (cChar != cNext) )
{
Control::KeyInput( rKEvt );
@ -391,7 +391,7 @@ void SvxShowCharSet::DrawChars_Impl( int n1, int n2 )
int y = pix.Y();
OUStringBuffer buf;
buf.appendUtf32( maFontCharMap.GetCharFromIndex( i ) );
buf.appendUtf32( mpFontCharMap->GetCharFromIndex( i ) );
OUString aCharStr(buf.makeStringAndClear());
int nTextWidth = GetTextWidth(aCharStr);
int tx = x + (nX - nTextWidth + 1) / 2;
@ -500,7 +500,7 @@ void SvxShowCharSet::InitSettings( bool bForeground, bool bBackground )
sal_UCS4 SvxShowCharSet::GetSelectCharacter() const
{
if( nSelectedIndex >= 0 )
getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex );
getSelectedChar() = mpFontCharMap->GetCharFromIndex( nSelectedIndex );
return getSelectedChar();
}
@ -510,7 +510,7 @@ void SvxShowCharSet::SetFont( const vcl::Font& rFont )
{
// save last selected unicode
if( nSelectedIndex >= 0 )
getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex );
getSelectedChar() = mpFontCharMap->GetCharFromIndex( nSelectedIndex );
Size aSize = GetOutputSizePixel();
long nSBWidth = aVscrollSB.GetOptimalSize().Width();
@ -523,20 +523,20 @@ void SvxShowCharSet::SetFont( const vcl::Font& rFont )
aFont.SetSize( PixelToLogic( Size( 0, nFontHeight ) ) );
aFont.SetTransparent( true );
Control::SetFont( aFont );
GetFontCharMap( maFontCharMap );
GetFontCharMap( mpFontCharMap );
nX = aSize.Width() / COLUMN_COUNT;
nY = aSize.Height() / ROW_COUNT;
aVscrollSB.setPosSizePixel( aSize.Width(), 0, nSBWidth, aSize.Height() );
aVscrollSB.SetRangeMin( 0 );
int nLastRow = (maFontCharMap.GetCharCount() - 1 + COLUMN_COUNT) / COLUMN_COUNT;
int nLastRow = (mpFontCharMap->GetCharCount() - 1 + COLUMN_COUNT) / COLUMN_COUNT;
aVscrollSB.SetRangeMax( nLastRow );
aVscrollSB.SetPageSize( ROW_COUNT-1 );
aVscrollSB.SetVisibleSize( ROW_COUNT );
// restore last selected unicode
int nMapIndex = maFontCharMap.GetIndexFromChar( getSelectedChar() );
int nMapIndex = mpFontCharMap->GetIndexFromChar( getSelectedChar() );
SelectIndex( nMapIndex );
aVscrollSB.Show();
@ -556,8 +556,8 @@ void SvxShowCharSet::SelectIndex( int nNewIndex, bool bFocus )
if( nNewIndex < 0 )
{
// need to scroll see closest unicode
sal_uInt32 cPrev = maFontCharMap.GetPrevChar( getSelectedChar() );
int nMapIndex = maFontCharMap.GetIndexFromChar( cPrev );
sal_uInt32 cPrev = mpFontCharMap->GetPrevChar( getSelectedChar() );
int nMapIndex = mpFontCharMap->GetIndexFromChar( cPrev );
int nNewPos = nMapIndex / COLUMN_COUNT;
aVscrollSB.SetThumbPos( nNewPos );
nSelectedIndex = bFocus ? nMapIndex+1 : -1;
@ -581,7 +581,7 @@ void SvxShowCharSet::SelectIndex( int nNewIndex, bool bFocus )
int nOldPos = aVscrollSB.GetThumbPos();
int nDelta = (nNewIndex - LastInView() + COLUMN_COUNT) / COLUMN_COUNT;
aVscrollSB.SetThumbPos( nOldPos + nDelta );
if( nNewIndex < maFontCharMap.GetCharCount() )
if( nNewIndex < mpFontCharMap->GetCharCount() )
{
nSelectedIndex = nNewIndex;
Invalidate();
@ -617,7 +617,7 @@ void SvxShowCharSet::SelectIndex( int nNewIndex, bool bFocus )
if( nSelectedIndex >= 0 )
{
getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex );
getSelectedChar() = mpFontCharMap->GetCharFromIndex( nSelectedIndex );
if( m_pAccessible )
{
::svx::SvxShowCharSetItem* pItem = ImplGetItem(nSelectedIndex);
@ -648,9 +648,9 @@ void SvxShowCharSet::SelectIndex( int nNewIndex, bool bFocus )
void SvxShowCharSet::SelectCharacter( sal_UCS4 cNew, bool bFocus )
{
// get next available char of current font
sal_UCS4 cNext = maFontCharMap.GetNextChar( (cNew > 0) ? cNew - 1 : cNew );
sal_UCS4 cNext = mpFontCharMap->GetNextChar( (cNew > 0) ? cNew - 1 : cNew );
int nMapIndex = maFontCharMap.GetIndexFromChar( cNext );
int nMapIndex = mpFontCharMap->GetIndexFromChar( cNext );
SelectIndex( nMapIndex, bFocus );
if( !bFocus )
{
@ -720,7 +720,7 @@ void SvxShowCharSet::ReleaseAccessible()
m_pAccessible->getTable(), sal::static_int_cast< sal_uInt16 >(_nPos)));
aFind = m_aItems.insert(ItemsMap::value_type(_nPos, xItem)).first;
OUStringBuffer buf;
buf.appendUtf32( maFontCharMap.GetCharFromIndex( _nPos ) );
buf.appendUtf32( mpFontCharMap->GetCharFromIndex( _nPos ) );
aFind->second->maText = buf.makeStringAndClear();
Point pix = MapIndexToPixel( _nPos );
aFind->second->maRect = Rectangle( Point( pix.X() + 1, pix.Y() + 1 ), Size(nX-1,nY-1) );
@ -733,13 +733,13 @@ void SvxShowCharSet::ReleaseAccessible()
sal_Int32 SvxShowCharSet::getMaxCharCount() const
{
return maFontCharMap.GetCharCount();
return mpFontCharMap->GetCharCount();
}
// TODO: should be moved into Font Attributes stuff
// we let it mature here though because it is currently the only use
SubsetMap::SubsetMap( const FontCharMap* pFontCharMap )
SubsetMap::SubsetMap( const FontCharMapPtr pFontCharMap )
: Resource( SVX_RES(RID_SUBSETMAP) )
{
InitList();
@ -1472,7 +1472,7 @@ void SubsetMap::InitList()
maSubsets = aAllSubsets;
}
void SubsetMap::ApplyCharMap( const FontCharMap* pFontCharMap )
void SubsetMap::ApplyCharMap( const FontCharMapPtr pFontCharMap )
{
if( !pFontCharMap )
return;

View File

@ -2088,7 +2088,7 @@ void PrintFontManager::getGlyphWidths( fontID nFont,
CmapResult aCmapResult;
if( ParseCMAP( pCmapData, nCmapSize, aCmapResult ) )
{
const ImplFontCharMapPtr pCharMap( new ImplFontCharMap(aCmapResult) );
FontCharMapPtr pCharMap( new FontCharMap(aCmapResult) );
for( sal_uInt32 cOld = 0;;)
{
// get next unicode covered by font
@ -2105,6 +2105,8 @@ void PrintFontManager::getGlyphWidths( fontID nFont,
// update the requested map
rUnicodeEnc[ (sal_Unicode)c ] = aGlyphId;
}
pCharMap = 0;
}
}
}

View File

@ -1266,13 +1266,13 @@ bool ServerFont::GetGlyphBitmap8( sal_GlyphId aGlyphId, RawBitmap& rRawBitmap )
// determine unicode ranges in font
const ImplFontCharMapPtr ServerFont::GetImplFontCharMap( void ) const
const FontCharMapPtr ServerFont::GetFontCharMap() const
{
const ImplFontCharMapPtr pIFCMap = mpFontInfo->GetImplFontCharMap();
return pIFCMap;
const FontCharMapPtr pFCMap = mpFontInfo->GetFontCharMap();
return pFCMap;
}
const ImplFontCharMapPtr FtFontInfo::GetImplFontCharMap( void )
const FontCharMapPtr FtFontInfo::GetFontCharMap()
{
// check if the charmap is already cached
if( mpFontCharMap )
@ -1283,12 +1283,13 @@ const ImplFontCharMapPtr FtFontInfo::GetImplFontCharMap( void )
bool bOK = GetFontCodeRanges( aCmapResult );
if( bOK )
{
ImplFontCharMapPtr pFontCharMap( new ImplFontCharMap( aCmapResult ) );
FontCharMapPtr pFontCharMap( new FontCharMap ( aCmapResult ) );
mpFontCharMap = pFontCharMap;
}
else
{
mpFontCharMap = ImplFontCharMap::GetDefaultMap();
FontCharMapPtr pFontCharMap( new FontCharMap() );
mpFontCharMap = pFontCharMap;
}
// mpFontCharMap on either branch now has a refcount of 1
return mpFontCharMap;

View File

@ -84,7 +84,7 @@ public:
void CacheGlyphIndex( sal_UCS4 cChar, int nGI ) const;
bool GetFontCodeRanges( CmapResult& ) const;
const ImplFontCharMapPtr GetImplFontCharMap( void );
const FontCharMapPtr GetFontCharMap();
private:
FT_FaceRec_* maFaceFT;
@ -99,7 +99,7 @@ private:
sal_IntPtr mnFontId;
ImplDevFontAttributes maDevFontAttributes;
ImplFontCharMapPtr mpFontCharMap;
FontCharMapPtr mpFontCharMap;
// cache unicode->glyphid mapping because looking it up is expensive
// TODO: change to boost::unordered_multimap when a use case requires a m:n mapping

View File

@ -777,13 +777,13 @@ void GenPspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
DrawPrinterLayout( rLayout, *m_pPrinterGfx, true );
}
const ImplFontCharMapPtr GenPspGraphics::GetImplFontCharMap() const
const FontCharMapPtr GenPspGraphics::GetFontCharMap() const
{
if( !m_pServerFont[0] )
return NULL;
const ImplFontCharMapPtr pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
return pIFCMap;
const FontCharMapPtr pFCMap = m_pServerFont[0]->GetFontCharMap();
return pFCMap;
}
bool GenPspGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const

View File

@ -231,13 +231,13 @@ void SvpSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLe
}
}
const ImplFontCharMapPtr SvpSalGraphics::GetImplFontCharMap() const
const FontCharMapPtr SvpSalGraphics::GetFontCharMap() const
{
if( !m_pServerFont[0] )
return NULL;
const ImplFontCharMapPtr pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
return pIFCMap;
const FontCharMapPtr pFCMap = m_pServerFont[0]->GetFontCharMap();
return pFCMap;
}
bool SvpSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const

View File

@ -89,7 +89,7 @@ public:
virtual void SetTextColor( SalColor nSalColor ) SAL_OVERRIDE;
virtual sal_uInt16 SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE;
virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
virtual const ImplFontCharMapPtr GetImplFontCharMap() const SAL_OVERRIDE;
virtual const FontCharMapPtr GetFontCharMap() const SAL_OVERRIDE;
virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
virtual void GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;
// graphics must drop any cached font info

View File

@ -33,9 +33,9 @@
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include <tools/gen.hxx>
#include <vcl/dllapi.h>
#include <vcl/metric.hxx>
#include <outfont.hxx>
#include <impfont.hxx>
#include <sallayout.hxx>
class FtFontInfo;
@ -182,7 +182,7 @@ public:
const unsigned char* GetTable( const char* pName, sal_uLong* pLength );
int GetEmUnits() const { return maFaceFT->units_per_EM;}
const FT_Size_Metrics& GetMetricsFT() const { return maSizeFT->metrics; }
const ImplFontCharMapPtr GetImplFontCharMap() const;
const FontCharMapPtr GetFontCharMap() const;
bool GetFontCapabilities(vcl::FontCapabilities &) const;
GlyphData& GetGlyphData( sal_GlyphId );

View File

@ -23,6 +23,7 @@
#include <basebmp/bitmapdevice.hxx>
#include <basebmp/color.hxx>
#include <vcl/sysdata.hxx>
#include <vcl/metric.hxx>
#include "salgdi.hxx"
#include "sallayout.hxx"
@ -156,7 +157,7 @@ public:
virtual void SetTextColor( SalColor nSalColor ) SAL_OVERRIDE;
virtual sal_uInt16 SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE;
virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
virtual const ImplFontCharMapPtr GetImplFontCharMap() const SAL_OVERRIDE;
virtual const FontCharMapPtr GetFontCharMap() const SAL_OVERRIDE;
virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
virtual void GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;
virtual void ClearDevFontCache() SAL_OVERRIDE;

View File

@ -163,34 +163,18 @@ public:
explicit ImplFontCharMap( const CmapResult& );
virtual ~ImplFontCharMap();
static ImplFontCharMapPtr GetDefaultMap( bool bSymbols=false);
bool IsDefaultMap() const;
bool HasChar( sal_uInt32 ) const;
int CountCharsInRange( sal_uInt32 cMin, sal_uInt32 cMax ) const;
int GetCharCount() const { return mnCharCount;}
sal_uInt32 GetFirstChar() const { return mpRangeCodes[0];}
sal_uInt32 GetLastChar() const;
sal_uInt32 GetNextChar( sal_uInt32 ) const;
sal_uInt32 GetPrevChar( sal_uInt32 ) const;
int GetIndexFromChar( sal_uInt32 ) const;
sal_uInt32 GetCharFromIndex( int ) const;
int GetGlyphIndex( sal_uInt32 ) const;
private:
friend class FontCharMap;
friend void intrusive_ptr_add_ref(ImplFontCharMap* pImplFontCharMap);
friend void intrusive_ptr_release(ImplFontCharMap* pImplFontCharMap);
int ImplFindRangeIndex( sal_uInt32 ) const;
// prevent assignment and copy construction
explicit ImplFontCharMap( const ImplFontCharMap& );
void operator=( const ImplFontCharMap& );
static ImplFontCharMapPtr getDefaultMap( bool bSymbols=false);
bool isDefaultMap() const;
private:
const sal_uInt32* mpRangeCodes; // pairs of StartCode/(EndCode+1)
const int* mpStartGlyphs; // range-specific mapper to glyphs

View File

@ -45,6 +45,7 @@ extern "C" {
#include "postmac.h"
#include <vcl/fontcapabilities.hxx>
#include <vcl/metric.hxx>
#include "outfont.hxx"
#include "PhysicalFontFace.hxx"
@ -73,7 +74,7 @@ public:
CoreTextStyle* CreateTextStyle( const FontSelectPattern& ) const;
int GetFontTable( const char pTagName[5], unsigned char* ) const;
const ImplFontCharMapPtr GetImplFontCharMap() const;
const FontCharMapPtr GetFontCharMap() const;
bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
bool HasChar( sal_uInt32 cChar ) const;
@ -85,7 +86,7 @@ protected:
private:
const sal_IntPtr mnFontId;
mutable ImplFontCharMapPtr mpCharMap;
mutable FontCharMapPtr mpCharMap;
mutable vcl::FontCapabilities maFontCapabilities;
mutable bool mbOs2Read; // true if OS2-table related info is valid
mutable bool mbHasOs2Table;
@ -330,8 +331,7 @@ public:
// get the current font's metrics
virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
// get the repertoire of the current font
virtual const ImplFontCharMapPtr
GetImplFontCharMap() const SAL_OVERRIDE;
virtual const FontCharMapPtr GetFontCharMap() const SAL_OVERRIDE;
virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
// graphics must fill supplied font list
virtual void GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;

View File

@ -20,15 +20,17 @@
#ifndef INCLUDED_VCL_INC_SALGDI_HXX
#define INCLUDED_VCL_INC_SALGDI_HXX
#include "tools/solar.h"
#include "vcl/dllapi.h"
#include "vcl/salgtype.hxx"
#include "osl/thread.hxx"
#include "vcl/outdev.hxx"
#include "vcl/salnativewidgets.hxx"
#include <tools/solar.h>
#include <osl/thread.hxx>
#include <vcl/dllapi.h>
#include <vcl/salgtype.hxx>
#include <vcl/outdev.hxx>
#include <vcl/salnativewidgets.hxx>
#include <vcl/metric.hxx>
#include "salglyphid.hxx"
#include "sallayout.hxx"
#include <impfont.hxx>
#include <map>
@ -231,8 +233,7 @@ public:
virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel = 0 ) = 0;
// get the repertoire of the current font
virtual const ImplFontCharMapPtr
GetImplFontCharMap() const = 0;
virtual const FontCharMapPtr GetFontCharMap() const = 0;
// get the layout capabilities of the current font
virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const = 0;

View File

@ -24,8 +24,9 @@
#include <postx.h>
#include <tools/rational.hxx>
#include "vcl/salgtype.hxx"
#include "vcl/vclenum.hxx"
#include <vcl/salgtype.hxx>
#include <vcl/vclenum.hxx>
#include <vcl/metric.hxx>
#include "salgdi.hxx"
#include "sallayout.hxx"
@ -229,7 +230,7 @@ public:
virtual void SetTextColor( SalColor nSalColor ) SAL_OVERRIDE;
virtual sal_uInt16 SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE;
virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
virtual const ImplFontCharMapPtr GetImplFontCharMap() const SAL_OVERRIDE;
virtual const FontCharMapPtr GetFontCharMap() const SAL_OVERRIDE;
virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
virtual void GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;
virtual void ClearDevFontCache() SAL_OVERRIDE;

View File

@ -94,7 +94,7 @@ public:
const gr_face* GraphiteFace() const;
#endif
const ImplFontCharMapPtr GetImplFontCharMap() const;
FontCharMapPtr GetFontCharMap() const;
bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
const Ucs2SIntMap* GetEncodingVector() const { return mpEncodingVector; }
void SetEncodingVector( const Ucs2SIntMap* pNewVec ) const
@ -116,7 +116,7 @@ private:
#endif
mutable bool mbHasArabicSupport;
mutable bool mbFontCapabilitiesRead;
mutable ImplFontCharMapPtr mpUnicodeMap;
mutable FontCharMapPtr mpUnicodeMap;
mutable const Ucs2SIntMap* mpEncodingVector;
mutable vcl::FontCapabilities maFontCapabilities;
@ -310,7 +310,7 @@ public:
// get the current font's metrics
virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel );
// get the repertoire of the current font
virtual const ImplFontCharMapPtr GetImplFontCharMap() const;
virtual const FontCharMapPtr GetFontCharMap() const;
// get the layout capabilities of the current font
virtual bool GetFontCapabilities(vcl::FontCapabilities &rGetFontCapabilities) const;
// graphics must fill supplied font list

View File

@ -28,17 +28,19 @@ public:
void VclFontCharMapTest::testDefaultFontCharMap()
{
FontCharMap fcmap; // gets default map
FontCharMapPtr pfcmap( new FontCharMap() ); // gets default map
CPPUNIT_ASSERT( fcmap.IsDefaultMap() );
CPPUNIT_ASSERT( pfcmap->IsDefaultMap() );
sal_uInt32 nStartBMPPlane = fcmap.GetFirstChar();
sal_uInt32 nStartSupBMPPlane = fcmap.GetNextChar(0xD800);
sal_uInt32 nEndBMPPlane = fcmap.GetLastChar();
sal_uInt32 nStartBMPPlane = pfcmap->GetFirstChar();
sal_uInt32 nStartSupBMPPlane = pfcmap->GetNextChar(0xD800);
sal_uInt32 nEndBMPPlane = pfcmap->GetLastChar();
CPPUNIT_ASSERT( nStartBMPPlane == 0x0020 );
CPPUNIT_ASSERT( nStartSupBMPPlane == 0xE000 );
CPPUNIT_ASSERT( nEndBMPPlane == 0xFFF0-1 );
pfcmap = 0;
}
CPPUNIT_TEST_SUITE_REGISTRATION(VclFontCharMapTest);

View File

@ -37,6 +37,9 @@
#include "vcl/sysdata.hxx"
#include "vcl/svapp.hxx"
#include "vcl/metric.hxx"
#include "impfont.hxx"
#include "quartz/salgdi.h"
#include "quartz/utils.h"
@ -53,7 +56,6 @@
#include "ctfonts.hxx"
#include "fontsubset.hxx"
#include "impfont.hxx"
#include "sallayout.hxx"
#include "sft.hxx"
@ -93,37 +95,38 @@ sal_IntPtr CoreTextFontData::GetFontId() const
static unsigned GetUShort( const unsigned char* p ){return((p[0]<<8)+p[1]);}
const ImplFontCharMapPtr CoreTextFontData::GetImplFontCharMap() const
const FontCharMapPtr CoreTextFontData::GetFontCharMap() const
{
// return the cached charmap
if( mpCharMap )
return mpCharMap;
// set the default charmap
mpCharMap = ImplFontCharMap::GetDefaultMap();
FontCharMapPtr pCharMap( new FontCharMap() );
mpCharMap = pCharMap;
// get the CMAP byte size
// allocate a buffer for the CMAP raw data
const int nBufSize = GetFontTable( "cmap", NULL );
DBG_ASSERT( (nBufSize > 0), "CoreTextFontData::GetImplFontCharMap : GetFontTable1 failed!\n");
DBG_ASSERT( (nBufSize > 0), "CoreTextFontData::GetFontCharMap : GetFontTable1 failed!\n");
if( nBufSize <= 0 )
return mpCharMap;
// get the CMAP raw data
ByteVector aBuffer( nBufSize );
const int nRawLength = GetFontTable( "cmap", &aBuffer[0] );
DBG_ASSERT( (nRawLength > 0), "CoreTextFontData::GetImplFontCharMap : GetFontTable2 failed!\n");
DBG_ASSERT( (nRawLength > 0), "CoreTextFontData::GetFontCharMap : GetFontTable2 failed!\n");
if( nRawLength <= 0 )
return mpCharMap;
DBG_ASSERT( (nBufSize==nRawLength), "CoreTextFontData::GetImplFontCharMap : ByteCount mismatch!\n");
DBG_ASSERT( (nBufSize==nRawLength), "CoreTextFontData::GetFontCharMap : ByteCount mismatch!\n");
// parse the CMAP
CmapResult aCmapResult;
if( ParseCMAP( &aBuffer[0], nRawLength, aCmapResult ) )
{
ImplFontCharMapPtr pCharMap(new ImplFontCharMap( aCmapResult ) );
FontCharMapPtr pDefFontCharMap( new FontCharMap(aCmapResult) );
// create the matching charmap
mpCharMap = pCharMap;
mpCharMap = pDefFontCharMap;
}
return mpCharMap;
@ -485,12 +488,15 @@ SalLayout* AquaSalGraphics::GetTextLayout( ImplLayoutArgs& /*rArgs*/, int /*nFal
return pSalLayout;
}
const ImplFontCharMapPtr AquaSalGraphics::GetImplFontCharMap() const
const FontCharMapPtr AquaSalGraphics::GetFontCharMap() const
{
if( !mpFontData )
return ImplFontCharMap::GetDefaultMap();
{
FontCharMapPtr pFontCharMap( new FontCharMap() );
return pFontCharMap;
}
return mpFontData->GetImplFontCharMap();
return mpFontData->GetFontCharMap();
}
bool AquaSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
@ -722,7 +728,7 @@ void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bV
free( (void*)pGlyphMetrics );
}
ImplFontCharMapPtr pMap = mpFontData->GetImplFontCharMap();
FontCharMapPtr pMap = mpFontData->GetFontCharMap();
DBG_ASSERT( pMap && pMap->GetCharCount(), "no charmap" );
// get unicode<->glyph encoding

View File

@ -945,15 +945,18 @@ void WMFWriter::SetAllAttr()
pVirDev->SetFont(aSrcFont);
if ( aDstFont.GetName() != aSrcFont.GetName() )
{
FontCharMap aFontCharMap;
if ( pVirDev->GetFontCharMap( aFontCharMap ) )
FontCharMapPtr pFontCharMap;
if ( pVirDev->GetFontCharMap( pFontCharMap ) )
{
if ( ( aFontCharMap.GetFirstChar() & 0xff00 ) == 0xf000 )
if ( ( pFontCharMap->GetFirstChar() & 0xff00 ) == 0xf000 )
aSrcFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
else if ( aSrcFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
aSrcFont.SetCharSet( RTL_TEXTENCODING_MS_1252 );
}
pFontCharMap = 0;
}
aDstFont = aSrcFont;
CreateSelectDeleteFont(aDstFont);
}

View File

@ -33,6 +33,19 @@ CmapResult::CmapResult( bool bSymbolic,
, mbRecoded( false)
{}
static ImplFontCharMapPtr pDefaultImplFontCharMap;
static const sal_UCS4 aDefaultUnicodeRanges[] = {0x0020,0xD800, 0xE000,0xFFF0};
static const sal_UCS4 aDefaultSymbolRanges[] = {0x0020,0x0100, 0xF020,0xF100};
ImplFontCharMap::~ImplFontCharMap()
{
if( isDefaultMap() )
return;
delete[] mpRangeCodes;
delete[] mpStartGlyphs;
delete[] mpGlyphIds;
}
ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR )
: mpRangeCodes( rCR.mpRangeCodes )
, mpStartGlyphs( rCR.mpStartGlyphs )
@ -50,26 +63,7 @@ ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR )
}
}
static ImplFontCharMapPtr pDefaultImplFontCharMap;
static const sal_UCS4 aDefaultUnicodeRanges[] = {0x0020,0xD800, 0xE000,0xFFF0};
static const sal_UCS4 aDefaultSymbolRanges[] = {0x0020,0x0100, 0xF020,0xF100};
bool ImplFontCharMap::IsDefaultMap() const
{
const bool bIsDefault = (mpRangeCodes == aDefaultUnicodeRanges) || (mpRangeCodes == aDefaultSymbolRanges);
return bIsDefault;
}
ImplFontCharMap::~ImplFontCharMap()
{
if( IsDefaultMap() )
return;
delete[] mpRangeCodes;
delete[] mpStartGlyphs;
delete[] mpGlyphIds;
}
ImplFontCharMapPtr ImplFontCharMap::GetDefaultMap( bool bSymbols)
ImplFontCharMapPtr ImplFontCharMap::getDefaultMap( bool bSymbols )
{
const sal_UCS4* pRangeCodes = aDefaultUnicodeRanges;
int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes);
@ -85,173 +79,10 @@ ImplFontCharMapPtr ImplFontCharMap::GetDefaultMap( bool bSymbols)
return pDefaultImplFontCharMap;
}
int ImplFontCharMap::ImplFindRangeIndex( sal_UCS4 cChar ) const
bool ImplFontCharMap::isDefaultMap() const
{
int nLower = 0;
int nMid = mnRangeCount;
int nUpper = 2 * mnRangeCount - 1;
while( nLower < nUpper )
{
if( cChar >= mpRangeCodes[ nMid ] )
nLower = nMid;
else
nUpper = nMid - 1;
nMid = (nLower + nUpper + 1) / 2;
}
return nMid;
}
bool ImplFontCharMap::HasChar( sal_UCS4 cChar ) const
{
bool bHasChar = false;
if( mpStartGlyphs == NULL ) { // only the char-ranges are known
const int nRange = ImplFindRangeIndex( cChar );
if( nRange==0 && cChar<mpRangeCodes[0] )
return false;
bHasChar = ((nRange & 1) == 0); // inside a range
} else { // glyph mapping is available
const int nGlyphIndex = GetGlyphIndex( cChar );
bHasChar = (nGlyphIndex != 0); // not the notdef-glyph
}
return bHasChar;
}
int ImplFontCharMap::GetGlyphIndex( sal_UCS4 cChar ) const
{
// return -1 if the object doesn't know the glyph ids
if( !mpStartGlyphs )
return -1;
// return 0 if the unicode doesn't have a matching glyph
int nRange = ImplFindRangeIndex( cChar );
// check that we are inside any range
if( (nRange == 0) && (cChar < mpRangeCodes[0]) ) {
// symbol aliasing gives symbol fonts a second chance
const bool bSymbolic = cChar <= 0xFF && (mpRangeCodes[0]>=0xF000) && (mpRangeCodes[1]<=0xF0FF);
if( !bSymbolic )
return 0;
// check for symbol aliasing (U+F0xx -> U+00xx)
cChar |= 0xF000;
nRange = ImplFindRangeIndex( cChar );
if( (nRange == 0) && (cChar < mpRangeCodes[0]) ) {
return 0;
}
}
// check that we are inside a range
if( (nRange & 1) != 0 )
return 0;
// get glyph index directly or indirectly
int nGlyphIndex = cChar - mpRangeCodes[ nRange ];
const int nStartIndex = mpStartGlyphs[ nRange/2 ];
if( nStartIndex >= 0 ) {
// the glyph index can be calculated
nGlyphIndex += nStartIndex;
} else {
// the glyphid array has the glyph index
nGlyphIndex = mpGlyphIds[ nGlyphIndex - nStartIndex];
}
return nGlyphIndex;
}
// returns the number of chars supported by the font, which
// are inside the unicode range from cMin to cMax (inclusive)
int ImplFontCharMap::CountCharsInRange( sal_UCS4 cMin, sal_UCS4 cMax ) const
{
int nCount = 0;
// find and adjust range and char count for cMin
int nRangeMin = ImplFindRangeIndex( cMin );
if( nRangeMin & 1 )
++nRangeMin;
else if( cMin > mpRangeCodes[ nRangeMin ] )
nCount -= cMin - mpRangeCodes[ nRangeMin ];
// find and adjust range and char count for cMax
int nRangeMax = ImplFindRangeIndex( cMax );
if( nRangeMax & 1 )
--nRangeMax;
else
nCount -= mpRangeCodes[ nRangeMax+1 ] - cMax - 1;
// count chars in complete ranges between cMin and cMax
for( int i = nRangeMin; i <= nRangeMax; i+=2 )
nCount += mpRangeCodes[i+1] - mpRangeCodes[i];
return nCount;
}
sal_UCS4 ImplFontCharMap::GetLastChar() const
{
return (mpRangeCodes[ 2*mnRangeCount-1 ] - 1);
}
sal_UCS4 ImplFontCharMap::GetNextChar( sal_UCS4 cChar ) const
{
if( cChar < GetFirstChar() )
return GetFirstChar();
if( cChar >= GetLastChar() )
return GetLastChar();
int nRange = ImplFindRangeIndex( cChar + 1 );
if( nRange & 1 ) // outside of range?
return mpRangeCodes[ nRange + 1 ]; // => first in next range
return (cChar + 1);
}
sal_UCS4 ImplFontCharMap::GetPrevChar( sal_UCS4 cChar ) const
{
if( cChar <= GetFirstChar() )
return GetFirstChar();
if( cChar > GetLastChar() )
return GetLastChar();
int nRange = ImplFindRangeIndex( cChar - 1 );
if( nRange & 1 ) // outside a range?
return (mpRangeCodes[ nRange ] - 1); // => last in prev range
return (cChar - 1);
}
int ImplFontCharMap::GetIndexFromChar( sal_UCS4 cChar ) const
{
// TODO: improve linear walk?
int nCharIndex = 0;
const sal_UCS4* pRange = &mpRangeCodes[0];
for( int i = 0; i < mnRangeCount; ++i )
{
sal_UCS4 cFirst = *(pRange++);
sal_UCS4 cLast = *(pRange++);
if( cChar >= cLast )
nCharIndex += cLast - cFirst;
else if( cChar >= cFirst )
return nCharIndex + (cChar - cFirst);
else
break;
}
return -1;
}
sal_UCS4 ImplFontCharMap::GetCharFromIndex( int nCharIndex ) const
{
// TODO: improve linear walk?
const sal_UCS4* pRange = &mpRangeCodes[0];
for( int i = 0; i < mnRangeCount; ++i )
{
sal_UCS4 cFirst = *(pRange++);
sal_UCS4 cLast = *(pRange++);
nCharIndex -= cLast - cFirst;
if( nCharIndex < 0 )
return (cLast + nCharIndex);
}
// we can only get here with an out-of-bounds charindex
return mpRangeCodes[0];
const bool bIsDefault = (mpRangeCodes == aDefaultUnicodeRanges) || (mpRangeCodes == aDefaultSymbolRanges);
return bIsDefault;
}
static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);}
@ -543,74 +374,218 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
}
FontCharMap::FontCharMap()
: mpImplFontCharMap( ImplFontCharMap::GetDefaultMap() )
: mpImplFontCharMap( ImplFontCharMap::getDefaultMap() )
{}
FontCharMap::FontCharMap( ImplFontCharMapPtr pIFCMap )
: mpImplFontCharMap( pIFCMap )
{}
FontCharMap::FontCharMap( const CmapResult& rCR )
{
ImplFontCharMapPtr pImplFontCharMap( new ImplFontCharMap(rCR) );
mpImplFontCharMap = pImplFontCharMap;
const sal_UCS4* pRangePtr = mpImplFontCharMap->mpRangeCodes;
for( int i = mpImplFontCharMap->mnRangeCount; --i >= 0; pRangePtr += 2 )
{
sal_UCS4 cFirst = pRangePtr[0];
sal_UCS4 cLast = pRangePtr[1];
mpImplFontCharMap->mnCharCount += cLast - cFirst;
}
}
FontCharMap::~FontCharMap()
{
mpImplFontCharMap = 0;
}
int FontCharMap::GetCharCount() const
FontCharMapPtr FontCharMap::GetDefaultMap( bool bSymbol )
{
return mpImplFontCharMap->GetCharCount();
}
int FontCharMap::CountCharsInRange( sal_UCS4 cMin, sal_UCS4 cMax ) const
{
return mpImplFontCharMap->CountCharsInRange( cMin, cMax );
}
void FontCharMap::Reset( const ImplFontCharMapPtr pNewMap )
{
if( !pNewMap )
{
mpImplFontCharMap = ImplFontCharMap::GetDefaultMap();
}
else if( pNewMap != mpImplFontCharMap )
{
mpImplFontCharMap = pNewMap;
}
FontCharMapPtr pFontCharMap( new FontCharMap( ImplFontCharMap::getDefaultMap( bSymbol ) ) );
return pFontCharMap;
}
bool FontCharMap::IsDefaultMap() const
{
return mpImplFontCharMap->IsDefaultMap();
return mpImplFontCharMap->isDefaultMap();
}
int FontCharMap::GetCharCount() const
{
return GetCharCount();
}
int FontCharMap::CountCharsInRange( sal_UCS4 cMin, sal_UCS4 cMax ) const
{
int nCount = 0;
// find and adjust range and char count for cMin
int nRangeMin = findRangeIndex( cMin );
if( nRangeMin & 1 )
++nRangeMin;
else if( cMin > mpImplFontCharMap->mpRangeCodes[ nRangeMin ] )
nCount -= cMin - mpImplFontCharMap->mpRangeCodes[ nRangeMin ];
// find and adjust range and char count for cMax
int nRangeMax = findRangeIndex( cMax );
if( nRangeMax & 1 )
--nRangeMax;
else
nCount -= mpImplFontCharMap->mpRangeCodes[ nRangeMax+1 ] - cMax - 1;
// count chars in complete ranges between cMin and cMax
for( int i = nRangeMin; i <= nRangeMax; i+=2 )
nCount += mpImplFontCharMap->mpRangeCodes[i+1] - mpImplFontCharMap->mpRangeCodes[i];
return nCount;
}
bool FontCharMap::HasChar( sal_UCS4 cChar ) const
{
return mpImplFontCharMap->HasChar( cChar );
bool bHasChar = false;
if( mpImplFontCharMap->mpStartGlyphs == NULL ) { // only the char-ranges are known
const int nRange = findRangeIndex( cChar );
if( nRange==0 && cChar < mpImplFontCharMap->mpRangeCodes[0] )
return false;
bHasChar = ((nRange & 1) == 0); // inside a range
} else { // glyph mapping is available
const int nGlyphIndex = GetGlyphIndex( cChar );
bHasChar = (nGlyphIndex != 0); // not the notdef-glyph
}
return bHasChar;
}
sal_UCS4 FontCharMap::GetFirstChar() const
{
return mpImplFontCharMap->GetFirstChar();
return mpImplFontCharMap->mpRangeCodes[0];
}
sal_UCS4 FontCharMap::GetLastChar() const
{
return mpImplFontCharMap->GetLastChar();
return (mpImplFontCharMap->mpRangeCodes[ 2*mpImplFontCharMap->mnRangeCount-1 ] - 1);
}
sal_UCS4 FontCharMap::GetNextChar( sal_UCS4 cChar ) const
{
return mpImplFontCharMap->GetNextChar( cChar );
if( cChar < GetFirstChar() )
return GetFirstChar();
if( cChar >= GetLastChar() )
return GetLastChar();
int nRange = findRangeIndex( cChar + 1 );
if( nRange & 1 ) // outside of range?
return mpImplFontCharMap->mpRangeCodes[ nRange + 1 ]; // => first in next range
return (cChar + 1);
}
sal_UCS4 FontCharMap::GetPrevChar( sal_UCS4 cChar ) const
{
return mpImplFontCharMap->GetPrevChar( cChar );
if( cChar <= GetFirstChar() )
return GetFirstChar();
if( cChar > GetLastChar() )
return GetLastChar();
int nRange = findRangeIndex( cChar - 1 );
if( nRange & 1 ) // outside a range?
return (mpImplFontCharMap->mpRangeCodes[ nRange ] - 1); // => last in prev range
return (cChar - 1);
}
int FontCharMap::GetIndexFromChar( sal_UCS4 cChar ) const
{
return mpImplFontCharMap->GetIndexFromChar( cChar );
// TODO: improve linear walk?
int nCharIndex = 0;
const sal_UCS4* pRange = &mpImplFontCharMap->mpRangeCodes[0];
for( int i = 0; i < mpImplFontCharMap->mnRangeCount; ++i )
{
sal_UCS4 cFirst = *(pRange++);
sal_UCS4 cLast = *(pRange++);
if( cChar >= cLast )
nCharIndex += cLast - cFirst;
else if( cChar >= cFirst )
return nCharIndex + (cChar - cFirst);
else
break;
}
return -1;
}
sal_UCS4 FontCharMap::GetCharFromIndex( int nIndex ) const
{
return mpImplFontCharMap->GetCharFromIndex( nIndex );
// TODO: improve linear walk?
const sal_UCS4* pRange = &mpImplFontCharMap->mpRangeCodes[0];
for( int i = 0; i < mpImplFontCharMap->mnRangeCount; ++i )
{
sal_UCS4 cFirst = *(pRange++);
sal_UCS4 cLast = *(pRange++);
nIndex -= cLast - cFirst;
if( nIndex < 0 )
return (cLast + nIndex);
}
// we can only get here with an out-of-bounds charindex
return mpImplFontCharMap->mpRangeCodes[0];
}
int FontCharMap::findRangeIndex( sal_UCS4 cChar ) const
{
int nLower = 0;
int nMid = mpImplFontCharMap->mnRangeCount;
int nUpper = 2 * mpImplFontCharMap->mnRangeCount - 1;
while( nLower < nUpper )
{
if( cChar >= mpImplFontCharMap->mpRangeCodes[ nMid ] )
nLower = nMid;
else
nUpper = nMid - 1;
nMid = (nLower + nUpper + 1) / 2;
}
return nMid;
}
int FontCharMap::GetGlyphIndex( sal_UCS4 cChar ) const
{
// return -1 if the object doesn't know the glyph ids
if( !mpImplFontCharMap->mpStartGlyphs )
return -1;
// return 0 if the unicode doesn't have a matching glyph
int nRange = findRangeIndex( cChar );
// check that we are inside any range
if( (nRange == 0) && (cChar < mpImplFontCharMap->mpRangeCodes[0]) ) {
// symbol aliasing gives symbol fonts a second chance
const bool bSymbolic = cChar <= 0xFF && (mpImplFontCharMap->mpRangeCodes[0]>=0xF000) &&
(mpImplFontCharMap->mpRangeCodes[1]<=0xF0FF);
if( !bSymbolic )
return 0;
// check for symbol aliasing (U+F0xx -> U+00xx)
cChar |= 0xF000;
nRange = findRangeIndex( cChar );
if( (nRange == 0) && (cChar < mpImplFontCharMap->mpRangeCodes[0]) ) {
return 0;
}
}
// check that we are inside a range
if( (nRange & 1) != 0 )
return 0;
// get glyph index directly or indirectly
int nGlyphIndex = cChar - mpImplFontCharMap->mpRangeCodes[ nRange ];
const int nStartIndex = mpImplFontCharMap->mpStartGlyphs[ nRange/2 ];
if( nStartIndex >= 0 ) {
// the glyph index can be calculated
nGlyphIndex += nStartIndex;
} else {
// the glyphid array has the glyph index
nGlyphIndex = mpImplFontCharMap->mpGlyphIds[ nGlyphIndex - nStartIndex];
}
return nGlyphIndex;
}
// on some systems we have to get the font attributes from the name table

View File

@ -216,10 +216,8 @@ FontMetric OutputDevice::GetFontMetric( const vcl::Font& rFont ) const
return aMetric;
}
bool OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const
bool OutputDevice::GetFontCharMap( FontCharMapPtr& rFontCharMap ) const
{
rFontCharMap.Reset();
// we need a graphics
if( !mpGraphics && !AcquireGraphics() )
return false;
@ -231,10 +229,16 @@ bool OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const
if( !mpFontEntry )
return false;
const ImplFontCharMapPtr pNewMap = mpGraphics->GetImplFontCharMap();
rFontCharMap.Reset( pNewMap );
FontCharMapPtr pFontCharMap ( mpGraphics->GetFontCharMap() );
if (!pFontCharMap)
{
FontCharMapPtr pDefaultMap( new FontCharMap() );
rFontCharMap = pDefaultMap;
}
else
rFontCharMap = pFontCharMap;
if( rFontCharMap.IsDefaultMap() )
if( rFontCharMap->IsDefaultMap() )
return false;
return true;
}
@ -2160,8 +2164,8 @@ sal_Int32 OutputDevice::HasGlyphs( const vcl::Font& rTempFont, const OUString& r
// to get the map temporarily set font
const vcl::Font aOrigFont = GetFont();
const_cast<OutputDevice&>(*this).SetFont( rTempFont );
FontCharMap aFontCharMap;
bool bRet = GetFontCharMap( aFontCharMap );
FontCharMapPtr pFontCharMap ( new FontCharMap() );
bool bRet = GetFontCharMap( pFontCharMap );
const_cast<OutputDevice&>(*this).SetFont( aOrigFont );
// if fontmap is unknown assume it doesn't have the glyphs
@ -2169,9 +2173,11 @@ sal_Int32 OutputDevice::HasGlyphs( const vcl::Font& rTempFont, const OUString& r
return nIndex;
for( sal_Int32 i = nIndex; nIndex < nEnd; ++i, ++nIndex )
if( ! aFontCharMap.HasChar( rStr[i] ) )
if( ! pFontCharMap->HasChar( rStr[i] ) )
return nIndex;
pFontCharMap = 0;
return -1;
}

View File

@ -43,12 +43,13 @@
#include <vcl/jobdata.hxx>
#include <vcl/printerinfomanager.hxx>
#include <vcl/svapp.hxx>
#include <vcl/metric.hxx>
#include "fontmanager.hxx"
#include "impfont.hxx"
#include "gcach_xpeer.hxx"
#include "generic/genpspgraphics.h"
#include "generic/printergfx.hxx"
#include "impfont.hxx"
#include "outdev.h"
#include "PhysicalFontCollection.hxx"
#include "PhysicalFontFace.hxx"
@ -431,13 +432,13 @@ void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
cairo_destroy(cr);
}
const ImplFontCharMapPtr X11SalGraphics::GetImplFontCharMap() const
const FontCharMapPtr X11SalGraphics::GetFontCharMap() const
{
if( !mpServerFont[0] )
return NULL;
const ImplFontCharMapPtr pIFCMap = mpServerFont[0]->GetImplFontCharMap();
return pIFCMap;
const FontCharMapPtr pFCMap = mpServerFont[0]->GetFontCharMap();
return pFCMap;
}
bool X11SalGraphics::GetFontCapabilities(vcl::FontCapabilities &rGetImplFontCapabilities) const

View File

@ -40,6 +40,7 @@
#include <unotools/fontcfg.hxx>
#include <vcl/settings.hxx>
#include <vcl/sysdata.hxx>
#include <vcl/metric.hxx>
#include "fontsubset.hxx"
#include "outdev.h"
@ -430,7 +431,7 @@ public:
bool FindFontSubstitute( FontSelectPattern&, OUString& rMissingChars ) const;
private:
HDC mhDC;
bool HasMissingChars( const PhysicalFontFace*, const OUString& rMissingChars ) const;
bool HasMissingChars( PhysicalFontFace*, const OUString& rMissingChars ) const;
};
inline WinGlyphFallbackSubstititution::WinGlyphFallbackSubstititution( HDC hDC )
@ -441,10 +442,10 @@ void ImplGetLogFontFromFontSelect( HDC, const FontSelectPattern*,
LOGFONTW&, bool /*bTestVerticalAvail*/ );
// does a font face hold the given missing characters?
bool WinGlyphFallbackSubstititution::HasMissingChars( const PhysicalFontFace* pFace, const OUString& rMissingChars ) const
bool WinGlyphFallbackSubstititution::HasMissingChars( PhysicalFontFace* pFace, const OUString& rMissingChars ) const
{
const ImplWinFontData* pWinFont = static_cast<const ImplWinFontData*>(pFace);
ImplFontCharMapPtr pCharMap = pWinFont->GetImplFontCharMap();
ImplWinFontData* pWinFont = static_cast< ImplWinFontData* >(pFace);
FontCharMapPtr pCharMap = pWinFont->GetFontCharMap();
if( !pCharMap )
{
// construct a Size structure as the parameter of constructor of class FontSelectPattern
@ -468,7 +469,7 @@ bool WinGlyphFallbackSubstititution::HasMissingChars( const PhysicalFontFace* pF
::DeleteFont( hNewFont );
// get the new charmap
pCharMap = pWinFont->GetImplFontCharMap();
pCharMap = pWinFont->GetFontCharMap();
}
// avoid fonts with unknown CMAP subtables for glyph fallback
@ -531,10 +532,10 @@ bool WinGlyphFallbackSubstititution::FindFontSubstitute( FontSelectPattern& rFon
// first level fallback:
// try use the locale specific default fonts defined in VCL.xcu
const PhysicalFontCollection* pFontCollection = ImplGetSVData()->maGDIData.mpScreenFontList;
/*const*/ PhysicalFontFamily* pFontFamily = findDevFontListByLocale(*pFontCollection, aLanguageTag);
PhysicalFontFamily* pFontFamily = findDevFontListByLocale(*pFontCollection, aLanguageTag);
if( pFontFamily )
{
const PhysicalFontFace* pFace = pFontFamily->FindBestFontFace( rFontSelData );
PhysicalFontFace* pFace = pFontFamily->FindBestFontFace( rFontSelData );
if( HasMissingChars( pFace, rMissingChars ) )
{
rFontSelData.maSearchName = pFontFamily->GetSearchName();
@ -550,7 +551,7 @@ bool WinGlyphFallbackSubstititution::FindFontSubstitute( FontSelectPattern& rFon
rFontSelData.maSearchName );
if( pFontFamily )
{
const PhysicalFontFace* pFace = pFontFamily->FindBestFontFace( rFontSelData );
PhysicalFontFace* pFace = pFontFamily->FindBestFontFace( rFontSelData );
if( HasMissingChars( pFace, rMissingChars ) )
{
rFontSelData.maSearchName = pFontFamily->GetSearchName();
@ -569,7 +570,7 @@ bool WinGlyphFallbackSubstititution::FindFontSubstitute( FontSelectPattern& rFon
bool bFound = false;
for( int i = 0; i < nTestFontCount; ++i )
{
const PhysicalFontFace* pFace = pTestFontList->Get( i );
PhysicalFontFace* pFace = pTestFontList->Get( i );
bFound = HasMissingChars( pFace, rMissingChars );
if( !bFound )
continue;
@ -1224,7 +1225,7 @@ bool ImplWinFontData::IsGSUBstituted( sal_UCS4 cChar ) const
return( maGsubTable.find( cChar ) != maGsubTable.end() );
}
const ImplFontCharMapPtr ImplWinFontData::GetImplFontCharMap() const
FontCharMapPtr ImplWinFontData::GetFontCharMap() const
{
if( !mpUnicodeMap )
return NULL;
@ -1299,13 +1300,15 @@ void ImplWinFontData::ReadCmapTable( HDC hDC ) const
aResult.mbSymbolic = bIsSymbolFont;
if( aResult.mnRangeCount > 0 )
{
ImplFontCharMapPtr pUnicodeMap( new ImplFontCharMap( aResult ) );
FontCharMapPtr pUnicodeMap(new FontCharMap(aResult));
mpUnicodeMap = pUnicodeMap;
}
}
if( !mpUnicodeMap )
mpUnicodeMap = ImplFontCharMap::GetDefaultMap( bIsSymbolFont );
{
mpUnicodeMap = FontCharMap::GetDefaultMap( bIsSymbolFont );
}
}
void ImplWinFontData::GetFontCapabilities( HDC hDC ) const
@ -1699,11 +1702,14 @@ sal_uLong WinSalGraphics::GetKernPairs()
return mnFontKernPairCount;
}
const ImplFontCharMapPtr WinSalGraphics::GetImplFontCharMap() const
const FontCharMapPtr WinSalGraphics::GetFontCharMap() const
{
if( !mpWinFontData[0] )
return ImplFontCharMap::GetDefaultMap();
return mpWinFontData[0]->GetImplFontCharMap();
{
FontCharMapPtr pDefFontCharMap( new FontCharMap() );
return pDefFontCharMap;
}
return mpWinFontData[0]->GetFontCharMap();
}
bool WinSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
@ -2482,7 +2488,7 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
if( aRawCffData.get() )
{
pWinFontData->UpdateFromHDC( getHDC() );
ImplFontCharMapPtr pCharMap = pWinFontData->GetImplFontCharMap();
FontCharMapPtr pCharMap = pWinFontData->GetFontCharMap();
sal_GlyphId aRealGlyphIds[ 256 ];
for( int i = 0; i < nGlyphCount; ++i )
@ -2732,7 +2738,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
rUnicodeEnc.clear();
}
const ImplWinFontData* pWinFont = static_cast<const ImplWinFontData*>(pFont);
ImplFontCharMapPtr pMap = pWinFont->GetImplFontCharMap();
FontCharMapPtr pMap = pWinFont->GetFontCharMap();
DBG_ASSERT( pMap && pMap->GetCharCount(), "no map" );
int nCharCount = pMap->GetCharCount();