vcl: add symbol and charset accessors and mutators to Font

Rules for the vcl::Font class for setting character set and
the symbol flag:

If the characterset changes to anything other than
RTL_TEXTENCODING_SYMBOL then the symbol flag should be off.

If the characterset changes to RTL_TEXTENCODING_SYMBOL then
the symbol flag should be on.

If the symbol flag is set to false and the characterset is
already RTL_TEXTENCODING_SYMBOL then set the characterset to
RTL_TEXTENCODING_DONTKNOW and set the symbol flag to false.
However, if we are setting the symbol flag from false to
false (i.e. we know the characterset) then we can keep the
characterset as it is.

Unit test written in this commit to test this is working.

Change-Id: Iced44659ab88ff66b711c560cb68bd4681ecb537
This commit is contained in:
Chris Sherlock
2016-01-15 17:33:17 +11:00
parent 1ea4f371f8
commit 9a790ca414
6 changed files with 285 additions and 185 deletions

View File

@@ -81,6 +81,9 @@ public:
FontFamily GetFamily() const;
void SetCharSet( rtl_TextEncoding );
rtl_TextEncoding GetCharSet() const;
void SetSymbolFlag( bool );
bool IsSymbolFont() const;
// Prefer LanguageTag over LanguageType
void SetLanguageTag( const LanguageTag & );
const LanguageTag& GetLanguageTag() const;

View File

@@ -0,0 +1,53 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_CppunitTest_CppunitTest,vcl_font))
$(eval $(call gb_CppunitTest_set_include,vcl_font,\
$$(INCLUDE) \
-I$(SRCDIR)/vcl/inc \
))
$(eval $(call gb_CppunitTest_add_exception_objects,vcl_font, \
vcl/qa/cppunit/font \
))
$(eval $(call gb_CppunitTest_use_externals,vcl_font,boost_headers))
$(eval $(call gb_CppunitTest_use_libraries,vcl_font, \
comphelper \
cppu \
cppuhelper \
sal \
svt \
test \
tl \
tk \
unotest \
vcl \
$(gb_UWINAPI) \
))
$(eval $(call gb_CppunitTest_use_api,vcl_font,\
udkapi \
offapi \
))
$(eval $(call gb_CppunitTest_use_ure,vcl_font))
$(eval $(call gb_CppunitTest_use_vcl,vcl_font))
$(eval $(call gb_CppunitTest_use_components,vcl_font,\
configmgr/source/configmgr \
i18npool/util/i18npool \
ucb/source/core/ucb1 \
))
$(eval $(call gb_CppunitTest_use_configuration,vcl_font))
# vim: set noet sw=4 ts=4:

View File

@@ -97,6 +97,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\
CppunitTest_vcl_lifecycle \
CppunitTest_vcl_bitmap_test \
CppunitTest_vcl_fontcharmap \
CppunitTest_vcl_font \
CppunitTest_vcl_fontmetric \
CppunitTest_vcl_complextext \
CppunitTest_vcl_filters_test \

View File

@@ -117,9 +117,22 @@ inline void FontAttributes::SetSymbolFlag( const bool bSymbolFlag )
{
mbSymbolFlag = bSymbolFlag;
if ( bSymbolFlag )
{
meCharSet = RTL_TEXTENCODING_SYMBOL;
}
else
{
// if the symbol flag is unset, but it was a symbol font before then
// until the character set encoding is set via SetCharSet then we
// can't know what the characterset is!
if ( meCharSet == RTL_TEXTENCODING_SYMBOL )
{
meCharSet = RTL_TEXTENCODING_DONTKNOW;
}
}
}
inline void FontAttributes::SetCharSet( const rtl_TextEncoding aEncoding )
{
meCharSet = aEncoding;

View File

@@ -52,6 +52,7 @@ private:
Color maColor; // compatibility, now on output device
Color maFillColor; // compatibility, now on output device
rtl_TextEncoding meCharSet;
bool mbSymbol;
LanguageTag maLanguageTag;
LanguageTag maCJKLanguageTag;
FontFamily meFamily;

View File

@@ -37,191 +37,6 @@
using namespace vcl;
ImplFont::ImplFont() :
mnRefCount( 1 ),
maColor( COL_TRANSPARENT ),
maFillColor( COL_TRANSPARENT ),
meCharSet( RTL_TEXTENCODING_DONTKNOW ),
maLanguageTag( LANGUAGE_DONTKNOW ),
maCJKLanguageTag( LANGUAGE_DONTKNOW ),
meFamily( FAMILY_DONTKNOW ),
mePitch( PITCH_DONTKNOW ),
meAlign( ALIGN_TOP ),
meWeight( WEIGHT_DONTKNOW ),
meWidthType( WIDTH_DONTKNOW ),
meItalic( ITALIC_NONE ),
meUnderline( UNDERLINE_NONE ),
meOverline( UNDERLINE_NONE ),
meStrikeout( STRIKEOUT_NONE ),
meRelief( RELIEF_NONE ),
meEmphasisMark( EMPHASISMARK_NONE ),
mnOrientation( 0 ),
mnKerning( FontKerning::NONE ),
mbWordLine( false ),
mbOutline( false ),
mbConfigLookup( false ),
mbShadow( false ),
mbVertical( false ),
mbTransparent( true )
{}
ImplFont::ImplFont( const ImplFont& rImplFont ) :
mnRefCount( 1 ),
maFamilyName( rImplFont.maFamilyName ),
maStyleName( rImplFont.maStyleName ),
maSize( rImplFont.maSize ),
maColor( rImplFont.maColor ),
maFillColor( rImplFont.maFillColor ),
meCharSet( rImplFont.meCharSet ),
maLanguageTag( rImplFont.maLanguageTag ),
maCJKLanguageTag( rImplFont.maCJKLanguageTag ),
meFamily( rImplFont.meFamily ),
mePitch( rImplFont.mePitch ),
meAlign( rImplFont.meAlign ),
meWeight( rImplFont.meWeight ),
meWidthType( rImplFont.meWidthType ),
meItalic( rImplFont.meItalic ),
meUnderline( rImplFont.meUnderline ),
meOverline( rImplFont.meOverline ),
meStrikeout( rImplFont.meStrikeout ),
meRelief( rImplFont.meRelief ),
meEmphasisMark( rImplFont.meEmphasisMark ),
mnOrientation( rImplFont.mnOrientation ),
mnKerning( rImplFont.mnKerning ),
mbWordLine( rImplFont.mbWordLine ),
mbOutline( rImplFont.mbOutline ),
mbConfigLookup( rImplFont.mbConfigLookup ),
mbShadow( rImplFont.mbShadow ),
mbVertical( rImplFont.mbVertical ),
mbTransparent( rImplFont.mbTransparent )
{}
bool ImplFont::operator==( const ImplFont& rOther ) const
{
// equality tests split up for easier debugging
if( (meWeight != rOther.meWeight)
|| (meItalic != rOther.meItalic)
|| (meFamily != rOther.meFamily)
|| (mePitch != rOther.mePitch) )
return false;
if( (meCharSet != rOther.meCharSet)
|| (maLanguageTag != rOther.maLanguageTag)
|| (maCJKLanguageTag != rOther.maCJKLanguageTag)
|| (meAlign != rOther.meAlign) )
return false;
if( (maSize != rOther.maSize)
|| (mnOrientation != rOther.mnOrientation)
|| (mbVertical != rOther.mbVertical) )
return false;
if( (maFamilyName != rOther.maFamilyName)
|| (maStyleName != rOther.maStyleName) )
return false;
if( (maColor != rOther.maColor)
|| (maFillColor != rOther.maFillColor) )
return false;
if( (meUnderline != rOther.meUnderline)
|| (meOverline != rOther.meOverline)
|| (meStrikeout != rOther.meStrikeout)
|| (meRelief != rOther.meRelief)
|| (meEmphasisMark != rOther.meEmphasisMark)
|| (mbWordLine != rOther.mbWordLine)
|| (mbOutline != rOther.mbOutline)
|| (mbShadow != rOther.mbShadow)
|| (mnKerning != rOther.mnKerning)
|| (mbTransparent != rOther.mbTransparent) )
return false;
return true;
}
void ImplFont::AskConfig()
{
if( mbConfigLookup )
return;
mbConfigLookup = true;
// prepare the FontSubst configuration lookup
const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
OUString aShortName;
OUString aFamilyName;
ImplFontAttrs nType = ImplFontAttrs::None;
FontWeight eWeight = WEIGHT_DONTKNOW;
FontWidth eWidthType = WIDTH_DONTKNOW;
OUString aMapName = GetEnglishSearchFontName( maFamilyName );
utl::FontSubstConfiguration::getMapName( aMapName,
aShortName, aFamilyName, eWeight, eWidthType, nType );
// lookup the font name in the configuration
const utl::FontNameAttr* pFontAttr = rFontSubst.getSubstInfo( aMapName );
// if the direct lookup failed try again with an alias name
if ( !pFontAttr && (aShortName != aMapName) )
pFontAttr = rFontSubst.getSubstInfo( aShortName );
if( pFontAttr )
{
// the font was found in the configuration
if( meFamily == FAMILY_DONTKNOW )
{
if ( pFontAttr->Type & ImplFontAttrs::Serif )
meFamily = FAMILY_ROMAN;
else if ( pFontAttr->Type & ImplFontAttrs::SansSerif )
meFamily = FAMILY_SWISS;
else if ( pFontAttr->Type & ImplFontAttrs::Typewriter )
meFamily = FAMILY_MODERN;
else if ( pFontAttr->Type & ImplFontAttrs::Italic )
meFamily = FAMILY_SCRIPT;
else if ( pFontAttr->Type & ImplFontAttrs::Decorative )
meFamily = FAMILY_DECORATIVE;
}
if( mePitch == PITCH_DONTKNOW )
{
if ( pFontAttr->Type & ImplFontAttrs::Fixed )
mePitch = PITCH_FIXED;
}
}
// if some attributes are still unknown then use the FontSubst magic
if( meFamily == FAMILY_DONTKNOW )
{
if( nType & ImplFontAttrs::Serif )
meFamily = FAMILY_ROMAN;
else if( nType & ImplFontAttrs::SansSerif )
meFamily = FAMILY_SWISS;
else if( nType & ImplFontAttrs::Typewriter )
meFamily = FAMILY_MODERN;
else if( nType & ImplFontAttrs::Italic )
meFamily = FAMILY_SCRIPT;
else if( nType & ImplFontAttrs::Decorative )
meFamily = FAMILY_DECORATIVE;
}
if( meWeight == WEIGHT_DONTKNOW )
meWeight = eWeight;
if( meWidthType == WIDTH_DONTKNOW )
meWidthType = eWidthType;
}
void Font::MakeUnique()
{
// create a copy if others still reference it
if ( mpImplFont->mnRefCount != 1 )
{
if ( mpImplFont->mnRefCount )
mpImplFont->mnRefCount--;
mpImplFont = new ImplFont( *mpImplFont );
}
}
Font::Font()
{
static ImplFont aStaticImplFont;
@@ -276,6 +91,17 @@ Font::~Font()
}
}
void Font::MakeUnique()
{
// create a copy if others still reference it
if ( mpImplFont->mnRefCount != 1 )
{
if ( mpImplFont->mnRefCount )
mpImplFont->mnRefCount--;
mpImplFont = new ImplFont( *mpImplFont );
}
}
void Font::SetColor( const Color& rColor )
{
if( mpImplFont->maColor != rColor )
@@ -347,6 +173,31 @@ void Font::SetCharSet( rtl_TextEncoding eCharSet )
{
MakeUnique();
mpImplFont->meCharSet = eCharSet;
if ( eCharSet == RTL_TEXTENCODING_SYMBOL )
mpImplFont->mbSymbol = true;
else
mpImplFont->mbSymbol = false;
}
}
bool Font::IsSymbolFont() const
{
return mpImplFont->mbSymbol;
}
void Font::SetSymbolFlag( bool bSymbol )
{
mpImplFont->mbSymbol = bSymbol;
if ( bSymbol )
{
mpImplFont->meCharSet = RTL_TEXTENCODING_SYMBOL;
}
else
{
if ( mpImplFont->meCharSet == RTL_TEXTENCODING_SYMBOL )
mpImplFont->meCharSet = RTL_TEXTENCODING_DONTKNOW;
}
}
@@ -985,4 +836,182 @@ bool Font::IsWordLineMode() const { return mpImplFont->mbWordLine; }
bool Font::IsSameInstance( const vcl::Font& rFont ) const { return (mpImplFont == rFont.mpImplFont); }
ImplFont::ImplFont() :
mnRefCount( 1 ),
maColor( COL_TRANSPARENT ),
maFillColor( COL_TRANSPARENT ),
meCharSet( RTL_TEXTENCODING_DONTKNOW ),
mbSymbol( false ),
maLanguageTag( LANGUAGE_DONTKNOW ),
maCJKLanguageTag( LANGUAGE_DONTKNOW ),
meFamily( FAMILY_DONTKNOW ),
mePitch( PITCH_DONTKNOW ),
meAlign( ALIGN_TOP ),
meWeight( WEIGHT_DONTKNOW ),
meWidthType( WIDTH_DONTKNOW ),
meItalic( ITALIC_NONE ),
meUnderline( UNDERLINE_NONE ),
meOverline( UNDERLINE_NONE ),
meStrikeout( STRIKEOUT_NONE ),
meRelief( RELIEF_NONE ),
meEmphasisMark( EMPHASISMARK_NONE ),
mnOrientation( 0 ),
mnKerning( FontKerning::NONE ),
mbWordLine( false ),
mbOutline( false ),
mbConfigLookup( false ),
mbShadow( false ),
mbVertical( false ),
mbTransparent( true )
{}
ImplFont::ImplFont( const ImplFont& rImplFont ) :
mnRefCount( 1 ),
maFamilyName( rImplFont.maFamilyName ),
maStyleName( rImplFont.maStyleName ),
maSize( rImplFont.maSize ),
maColor( rImplFont.maColor ),
maFillColor( rImplFont.maFillColor ),
meCharSet( rImplFont.meCharSet ),
mbSymbol( false ),
maLanguageTag( rImplFont.maLanguageTag ),
maCJKLanguageTag( rImplFont.maCJKLanguageTag ),
meFamily( rImplFont.meFamily ),
mePitch( rImplFont.mePitch ),
meAlign( rImplFont.meAlign ),
meWeight( rImplFont.meWeight ),
meWidthType( rImplFont.meWidthType ),
meItalic( rImplFont.meItalic ),
meUnderline( rImplFont.meUnderline ),
meOverline( rImplFont.meOverline ),
meStrikeout( rImplFont.meStrikeout ),
meRelief( rImplFont.meRelief ),
meEmphasisMark( rImplFont.meEmphasisMark ),
mnOrientation( rImplFont.mnOrientation ),
mnKerning( rImplFont.mnKerning ),
mbWordLine( rImplFont.mbWordLine ),
mbOutline( rImplFont.mbOutline ),
mbConfigLookup( rImplFont.mbConfigLookup ),
mbShadow( rImplFont.mbShadow ),
mbVertical( rImplFont.mbVertical ),
mbTransparent( rImplFont.mbTransparent )
{}
bool ImplFont::operator==( const ImplFont& rOther ) const
{
// equality tests split up for easier debugging
if( (meWeight != rOther.meWeight)
|| (meItalic != rOther.meItalic)
|| (meFamily != rOther.meFamily)
|| (mePitch != rOther.mePitch) )
return false;
if( (meCharSet != rOther.meCharSet)
|| (maLanguageTag != rOther.maLanguageTag)
|| (maCJKLanguageTag != rOther.maCJKLanguageTag)
|| (meAlign != rOther.meAlign) )
return false;
if( (maSize != rOther.maSize)
|| (mnOrientation != rOther.mnOrientation)
|| (mbVertical != rOther.mbVertical) )
return false;
if( (maFamilyName != rOther.maFamilyName)
|| (maStyleName != rOther.maStyleName) )
return false;
if( (maColor != rOther.maColor)
|| (maFillColor != rOther.maFillColor) )
return false;
if( (meUnderline != rOther.meUnderline)
|| (meOverline != rOther.meOverline)
|| (meStrikeout != rOther.meStrikeout)
|| (meRelief != rOther.meRelief)
|| (meEmphasisMark != rOther.meEmphasisMark)
|| (mbWordLine != rOther.mbWordLine)
|| (mbOutline != rOther.mbOutline)
|| (mbShadow != rOther.mbShadow)
|| (mnKerning != rOther.mnKerning)
|| (mbTransparent != rOther.mbTransparent) )
return false;
return true;
}
void ImplFont::AskConfig()
{
if( mbConfigLookup )
return;
mbConfigLookup = true;
// prepare the FontSubst configuration lookup
const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
OUString aShortName;
OUString aFamilyName;
ImplFontAttrs nType = ImplFontAttrs::None;
FontWeight eWeight = WEIGHT_DONTKNOW;
FontWidth eWidthType = WIDTH_DONTKNOW;
OUString aMapName = GetEnglishSearchFontName( maFamilyName );
utl::FontSubstConfiguration::getMapName( aMapName,
aShortName, aFamilyName, eWeight, eWidthType, nType );
// lookup the font name in the configuration
const utl::FontNameAttr* pFontAttr = rFontSubst.getSubstInfo( aMapName );
// if the direct lookup failed try again with an alias name
if ( !pFontAttr && (aShortName != aMapName) )
pFontAttr = rFontSubst.getSubstInfo( aShortName );
if( pFontAttr )
{
// the font was found in the configuration
if( meFamily == FAMILY_DONTKNOW )
{
if ( pFontAttr->Type & ImplFontAttrs::Serif )
meFamily = FAMILY_ROMAN;
else if ( pFontAttr->Type & ImplFontAttrs::SansSerif )
meFamily = FAMILY_SWISS;
else if ( pFontAttr->Type & ImplFontAttrs::Typewriter )
meFamily = FAMILY_MODERN;
else if ( pFontAttr->Type & ImplFontAttrs::Italic )
meFamily = FAMILY_SCRIPT;
else if ( pFontAttr->Type & ImplFontAttrs::Decorative )
meFamily = FAMILY_DECORATIVE;
}
if( mePitch == PITCH_DONTKNOW )
{
if ( pFontAttr->Type & ImplFontAttrs::Fixed )
mePitch = PITCH_FIXED;
}
}
// if some attributes are still unknown then use the FontSubst magic
if( meFamily == FAMILY_DONTKNOW )
{
if( nType & ImplFontAttrs::Serif )
meFamily = FAMILY_ROMAN;
else if( nType & ImplFontAttrs::SansSerif )
meFamily = FAMILY_SWISS;
else if( nType & ImplFontAttrs::Typewriter )
meFamily = FAMILY_MODERN;
else if( nType & ImplFontAttrs::Italic )
meFamily = FAMILY_SCRIPT;
else if( nType & ImplFontAttrs::Decorative )
meFamily = FAMILY_DECORATIVE;
}
if( meWeight == WEIGHT_DONTKNOW )
meWeight = eWeight;
if( meWidthType == WIDTH_DONTKNOW )
meWidthType = eWidthType;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */