Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / source / font / font.cxx
blob4dc242e7abbd90c167fd8de8c09b890b4f3df9c5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/macros.h>
21 #include <tools/stream.hxx>
22 #include <tools/vcompat.hxx>
23 #include <tools/gen.hxx>
24 #include <unotools/fontcfg.hxx>
25 #include <unotools/fontdefs.hxx>
27 #include <vcl/font.hxx>
29 #include "impfont.hxx"
30 #include "fontinstance.hxx"
31 #include "fontattributes.hxx"
32 #include "sft.hxx"
34 #include <algorithm>
36 #include <rtl/instance.hxx>
38 using namespace vcl;
40 namespace
42 struct theGlobalDefault :
43 public rtl::Static< Font::ImplType, theGlobalDefault > {};
46 Font::Font() : mpImplFont(theGlobalDefault::get())
50 Font::Font( const vcl::Font& rFont ) : mpImplFont( rFont.mpImplFont )
54 Font::Font( vcl::Font&& rFont ) : mpImplFont( std::move(rFont.mpImplFont) )
58 Font::Font( const OUString& rFamilyName, const Size& rSize ) : mpImplFont()
60 mpImplFont->SetFamilyName( rFamilyName );
61 mpImplFont->SetFontSize( rSize );
64 Font::Font( const OUString& rFamilyName, const OUString& rStyleName, const Size& rSize ) : mpImplFont()
66 mpImplFont->SetFamilyName( rFamilyName );
67 mpImplFont->SetStyleName( rStyleName );
68 mpImplFont->SetFontSize( rSize );
71 Font::Font( FontFamily eFamily, const Size& rSize ) : mpImplFont()
73 mpImplFont->SetFamilyType( eFamily );
74 mpImplFont->SetFontSize( rSize );
77 Font::~Font()
81 void Font::SetColor( const Color& rColor )
83 if (const_cast<const ImplType&>(mpImplFont)->maColor != rColor)
85 mpImplFont->maColor = rColor;
89 void Font::SetFillColor( const Color& rColor )
91 mpImplFont->maFillColor = rColor;
92 if ( rColor.GetTransparency() )
93 mpImplFont->mbTransparent = true;
96 void Font::SetTransparent( bool bTransparent )
98 if (const_cast<const ImplType&>(mpImplFont)->mbTransparent != bTransparent)
99 mpImplFont->mbTransparent = bTransparent;
102 void Font::SetAlignment( FontAlign eAlign )
104 if (const_cast<const ImplType&>(mpImplFont)->meAlign != eAlign)
105 mpImplFont->SetAlignment(eAlign);
108 void Font::SetFamilyName( const OUString& rFamilyName )
110 mpImplFont->SetFamilyName( rFamilyName );
113 void Font::SetStyleName( const OUString& rStyleName )
115 mpImplFont->maStyleName = rStyleName;
118 void Font::SetFontSize( const Size& rSize )
120 if (const_cast<const ImplType&>(mpImplFont)->GetFontSize() != rSize)
121 mpImplFont->SetFontSize( rSize );
124 void Font::SetFamily( FontFamily eFamily )
126 if (const_cast<const ImplType&>(mpImplFont)->GetFamilyTypeNoAsk() != eFamily)
127 mpImplFont->SetFamilyType( eFamily );
130 void Font::SetCharSet( rtl_TextEncoding eCharSet )
132 if (const_cast<const ImplType&>(mpImplFont)->GetCharSet() != eCharSet)
134 mpImplFont->SetCharSet( eCharSet );
136 if ( eCharSet == RTL_TEXTENCODING_SYMBOL )
137 mpImplFont->SetSymbolFlag( true );
138 else
139 mpImplFont->SetSymbolFlag( false );
143 bool Font::IsSymbolFont() const
145 return mpImplFont->IsSymbolFont();
148 void Font::SetSymbolFlag( bool bSymbol )
150 mpImplFont->SetSymbolFlag( bSymbol );
152 if ( IsSymbolFont() )
154 mpImplFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
156 else
158 if ( mpImplFont->GetCharSet() == RTL_TEXTENCODING_SYMBOL )
159 mpImplFont->SetCharSet( RTL_TEXTENCODING_DONTKNOW );
163 void Font::SetLanguageTag( const LanguageTag& rLanguageTag )
165 if (const_cast<const ImplType&>(mpImplFont)->maLanguageTag != rLanguageTag)
166 mpImplFont->maLanguageTag = rLanguageTag;
169 void Font::SetCJKContextLanguageTag( const LanguageTag& rLanguageTag )
171 if (const_cast<const ImplType&>(mpImplFont)->maCJKLanguageTag != rLanguageTag)
172 mpImplFont->maCJKLanguageTag = rLanguageTag;
175 void Font::SetLanguage( LanguageType eLanguage )
177 if (const_cast<const ImplType&>(mpImplFont)->maLanguageTag.getLanguageType(false) != eLanguage)
178 mpImplFont->maLanguageTag.reset( eLanguage);
181 void Font::SetCJKContextLanguage( LanguageType eLanguage )
183 if (const_cast<const ImplType&>(mpImplFont)->maCJKLanguageTag.getLanguageType(false) != eLanguage)
184 mpImplFont->maCJKLanguageTag.reset( eLanguage);
187 void Font::SetPitch( FontPitch ePitch )
189 if (const_cast<const ImplType&>(mpImplFont)->GetPitchNoAsk() != ePitch)
190 mpImplFont->SetPitch( ePitch );
193 void Font::SetOrientation( short nOrientation )
195 if (const_cast<const ImplType&>(mpImplFont)->mnOrientation != nOrientation)
196 mpImplFont->mnOrientation = nOrientation;
199 void Font::SetVertical( bool bVertical )
201 if (const_cast<const ImplType&>(mpImplFont)->mbVertical != bVertical)
202 mpImplFont->mbVertical = bVertical;
205 void Font::SetKerning( FontKerning eKerning )
207 if (const_cast<const ImplType&>(mpImplFont)->meKerning != eKerning)
208 mpImplFont->meKerning = eKerning;
211 bool Font::IsKerning() const
213 return !(mpImplFont->meKerning == FontKerning::NONE);
216 void Font::SetWeight( FontWeight eWeight )
218 if (const_cast<const ImplType&>(mpImplFont)->GetWeightNoAsk() != eWeight)
219 mpImplFont->SetWeight( eWeight );
222 void Font::SetWidthType( FontWidth eWidth )
224 if (const_cast<const ImplType&>(mpImplFont)->GetWidthTypeNoAsk() != eWidth)
225 mpImplFont->SetWidthType( eWidth );
228 void Font::SetItalic( FontItalic eItalic )
230 if (const_cast<const ImplType&>(mpImplFont)->GetItalicNoAsk() != eItalic)
231 mpImplFont->SetItalic( eItalic );
234 void Font::SetOutline( bool bOutline )
236 if (const_cast<const ImplType&>(mpImplFont)->mbOutline != bOutline)
237 mpImplFont->mbOutline = bOutline;
240 void Font::SetShadow( bool bShadow )
242 if (const_cast<const ImplType&>(mpImplFont)->mbShadow != bShadow)
243 mpImplFont->mbShadow = bShadow;
246 void Font::SetUnderline( FontLineStyle eUnderline )
248 if (const_cast<const ImplType&>(mpImplFont)->meUnderline != eUnderline)
249 mpImplFont->meUnderline = eUnderline;
252 void Font::SetOverline( FontLineStyle eOverline )
254 if (const_cast<const ImplType&>(mpImplFont)->meOverline != eOverline)
255 mpImplFont->meOverline = eOverline;
258 void Font::SetStrikeout( FontStrikeout eStrikeout )
260 if (const_cast<const ImplType&>(mpImplFont)->meStrikeout != eStrikeout)
261 mpImplFont->meStrikeout = eStrikeout;
264 void Font::SetRelief( FontRelief eRelief )
266 if (const_cast<const ImplType&>(mpImplFont)->meRelief != eRelief)
267 mpImplFont->meRelief = eRelief;
270 void Font::SetEmphasisMark( FontEmphasisMark eEmphasisMark )
272 if (const_cast<const ImplType&>(mpImplFont)->meEmphasisMark != eEmphasisMark )
273 mpImplFont->meEmphasisMark = eEmphasisMark;
276 void Font::SetWordLineMode( bool bWordLine )
278 if (const_cast<const ImplType&>(mpImplFont)->mbWordLine != bWordLine)
279 mpImplFont->mbWordLine = bWordLine;
282 Font& Font::operator=( const vcl::Font& rFont )
284 mpImplFont = rFont.mpImplFont;
285 return *this;
288 Font& Font::operator=( vcl::Font&& rFont )
290 mpImplFont = std::move(rFont.mpImplFont);
291 return *this;
294 bool Font::operator==( const vcl::Font& rFont ) const
296 return mpImplFont == rFont.mpImplFont;
299 void Font::Merge( const vcl::Font& rFont )
301 if ( !rFont.GetFamilyName().isEmpty() )
303 SetFamilyName( rFont.GetFamilyName() );
304 SetStyleName( rFont.GetStyleName() );
305 SetCharSet( GetCharSet() );
306 SetLanguageTag( rFont.GetLanguageTag() );
307 SetCJKContextLanguageTag( rFont.GetCJKContextLanguageTag() );
308 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
309 SetFamily( rFont.mpImplFont->GetFamilyTypeNoAsk() );
310 SetPitch( rFont.mpImplFont->GetPitchNoAsk() );
313 // don't use access methods here, might lead to AskConfig(), if DONTKNOW
314 if ( rFont.mpImplFont->GetWeightNoAsk() != WEIGHT_DONTKNOW )
315 SetWeight( rFont.GetWeight() );
316 if ( rFont.mpImplFont->GetItalicNoAsk() != ITALIC_DONTKNOW )
317 SetItalic( rFont.GetItalic() );
318 if ( rFont.mpImplFont->GetWidthTypeNoAsk() != WIDTH_DONTKNOW )
319 SetWidthType( rFont.GetWidthType() );
321 if ( rFont.GetFontSize().Height() )
322 SetFontSize( rFont.GetFontSize() );
323 if ( rFont.GetUnderline() != LINESTYLE_DONTKNOW )
325 SetUnderline( rFont.GetUnderline() );
326 SetWordLineMode( rFont.IsWordLineMode() );
328 if ( rFont.GetOverline() != LINESTYLE_DONTKNOW )
330 SetOverline( rFont.GetOverline() );
331 SetWordLineMode( rFont.IsWordLineMode() );
333 if ( rFont.GetStrikeout() != STRIKEOUT_DONTKNOW )
335 SetStrikeout( rFont.GetStrikeout() );
336 SetWordLineMode( rFont.IsWordLineMode() );
339 // Defaults?
340 SetOrientation( rFont.GetOrientation() );
341 SetVertical( rFont.IsVertical() );
342 SetEmphasisMark( rFont.GetEmphasisMark() );
343 SetKerning( rFont.IsKerning() ? FontKerning::FontSpecific : FontKerning::NONE );
344 SetOutline( rFont.IsOutline() );
345 SetShadow( rFont.IsShadow() );
346 SetRelief( rFont.GetRelief() );
349 void Font::GetFontAttributes( FontAttributes& rAttrs ) const
351 rAttrs.SetFamilyName( mpImplFont->GetFamilyName() );
352 rAttrs.SetStyleName( mpImplFont->maStyleName );
353 rAttrs.SetFamilyType( mpImplFont->GetFamilyTypeNoAsk() );
354 rAttrs.SetPitch( mpImplFont->GetPitchNoAsk() );
355 rAttrs.SetItalic( mpImplFont->GetItalicNoAsk() );
356 rAttrs.SetWeight( mpImplFont->GetWeightNoAsk() );
357 rAttrs.SetWidthType( WIDTH_DONTKNOW );
358 rAttrs.SetSymbolFlag( mpImplFont->GetCharSet() == RTL_TEXTENCODING_SYMBOL );
361 SvStream& ReadImplFont( SvStream& rIStm, ImplFont& rImplFont )
363 VersionCompat aCompat( rIStm, StreamMode::READ );
364 sal_uInt16 nTmp16;
365 bool bTmp;
366 sal_uInt8 nTmp8;
368 rImplFont.SetFamilyName( rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet()) );
369 rImplFont.maStyleName = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
370 ReadPair( rIStm, rImplFont.maAverageFontSize );
372 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetCharSet( (rtl_TextEncoding) nTmp16 );
373 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetFamilyType( (FontFamily) nTmp16 );
374 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetPitch( (FontPitch) nTmp16 );
375 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetWeight( (FontWeight) nTmp16 );
376 rIStm.ReadUInt16( nTmp16 ); rImplFont.meUnderline = (FontLineStyle) nTmp16;
377 rIStm.ReadUInt16( nTmp16 ); rImplFont.meStrikeout = (FontStrikeout) nTmp16;
378 rIStm.ReadUInt16( nTmp16 ); rImplFont.SetItalic( (FontItalic) nTmp16 );
379 rIStm.ReadUInt16( nTmp16 ); rImplFont.maLanguageTag.reset( LanguageType(nTmp16) );
380 rIStm.ReadUInt16( nTmp16 ); rImplFont.meWidthType = (FontWidth) nTmp16;
382 rIStm.ReadInt16( rImplFont.mnOrientation );
384 rIStm.ReadCharAsBool( bTmp ); rImplFont.mbWordLine = bTmp;
385 rIStm.ReadCharAsBool( bTmp ); rImplFont.mbOutline = bTmp;
386 rIStm.ReadCharAsBool( bTmp ); rImplFont.mbShadow = bTmp;
387 rIStm.ReadUChar( nTmp8 ); rImplFont.meKerning = static_cast<FontKerning>(nTmp8);
389 if( aCompat.GetVersion() >= 2 )
391 rIStm.ReadUChar( nTmp8 ); rImplFont.meRelief = (FontRelief)nTmp8;
392 rIStm.ReadUInt16( nTmp16 ); rImplFont.maCJKLanguageTag.reset( LanguageType(nTmp16) );
393 rIStm.ReadCharAsBool( bTmp ); rImplFont.mbVertical = bTmp;
394 rIStm.ReadUInt16( nTmp16 ); rImplFont.meEmphasisMark = (FontEmphasisMark)nTmp16;
397 if( aCompat.GetVersion() >= 3 )
399 rIStm.ReadUInt16( nTmp16 ); rImplFont.meOverline = (FontLineStyle) nTmp16;
402 // Relief
403 // CJKContextLanguage
405 return rIStm;
408 SvStream& WriteImplFont( SvStream& rOStm, const ImplFont& rImplFont )
410 VersionCompat aCompat( rOStm, StreamMode::WRITE, 3 );
411 rOStm.WriteUniOrByteString( rImplFont.GetFamilyName(), rOStm.GetStreamCharSet() );
412 rOStm.WriteUniOrByteString( rImplFont.GetStyleName(), rOStm.GetStreamCharSet() );
413 WritePair( rOStm, rImplFont.maAverageFontSize );
415 rOStm.WriteUInt16( GetStoreCharSet( rImplFont.GetCharSet() ) );
416 rOStm.WriteUInt16( rImplFont.GetFamilyTypeNoAsk() );
417 rOStm.WriteUInt16( rImplFont.GetPitchNoAsk() );
418 rOStm.WriteUInt16( rImplFont.GetWeightNoAsk() );
419 rOStm.WriteUInt16( rImplFont.meUnderline );
420 rOStm.WriteUInt16( rImplFont.meStrikeout );
421 rOStm.WriteUInt16( rImplFont.GetItalicNoAsk() );
422 rOStm.WriteUInt16( (sal_uInt16)rImplFont.maLanguageTag.getLanguageType( false) );
423 rOStm.WriteUInt16( rImplFont.GetWidthTypeNoAsk() );
425 rOStm.WriteInt16( rImplFont.mnOrientation );
427 rOStm.WriteBool( rImplFont.mbWordLine );
428 rOStm.WriteBool( rImplFont.mbOutline );
429 rOStm.WriteBool( rImplFont.mbShadow );
430 rOStm.WriteUChar( static_cast<sal_uInt8>(rImplFont.meKerning) );
432 // new in version 2
433 rOStm.WriteUChar( (sal_uChar)rImplFont.meRelief );
434 rOStm.WriteUInt16( (sal_uInt16)rImplFont.maCJKLanguageTag.getLanguageType( false) );
435 rOStm.WriteBool( rImplFont.mbVertical );
436 rOStm.WriteUInt16( (sal_uInt16)rImplFont.meEmphasisMark );
438 // new in version 3
439 rOStm.WriteUInt16( rImplFont.meOverline );
441 return rOStm;
444 SvStream& ReadFont( SvStream& rIStm, vcl::Font& rFont )
446 return ReadImplFont( rIStm, *rFont.mpImplFont );
449 SvStream& WriteFont( SvStream& rOStm, const vcl::Font& rFont )
451 return WriteImplFont( rOStm, *rFont.mpImplFont );
454 namespace
456 bool identifyTrueTypeFont( const void* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
458 bool bResult = false;
459 TrueTypeFont* pTTF = nullptr;
460 if( OpenTTFontBuffer( i_pBuffer, i_nSize, 0, &pTTF ) == SF_OK )
462 TTGlobalFontInfo aInfo;
463 GetTTGlobalFontInfo( pTTF, &aInfo );
464 // most importantly: the family name
465 if( aInfo.ufamily )
466 o_rResult.SetFamilyName( aInfo.ufamily );
467 else if( aInfo.family )
468 o_rResult.SetFamilyName( OStringToOUString( aInfo.family, RTL_TEXTENCODING_ASCII_US ) );
469 // set weight
470 if( aInfo.weight )
472 if( aInfo.weight < FW_EXTRALIGHT )
473 o_rResult.SetWeight( WEIGHT_THIN );
474 else if( aInfo.weight < FW_LIGHT )
475 o_rResult.SetWeight( WEIGHT_ULTRALIGHT );
476 else if( aInfo.weight < FW_NORMAL )
477 o_rResult.SetWeight( WEIGHT_LIGHT );
478 else if( aInfo.weight < FW_MEDIUM )
479 o_rResult.SetWeight( WEIGHT_NORMAL );
480 else if( aInfo.weight < FW_SEMIBOLD )
481 o_rResult.SetWeight( WEIGHT_MEDIUM );
482 else if( aInfo.weight < FW_BOLD )
483 o_rResult.SetWeight( WEIGHT_SEMIBOLD );
484 else if( aInfo.weight < FW_EXTRABOLD )
485 o_rResult.SetWeight( WEIGHT_BOLD );
486 else if( aInfo.weight < FW_BLACK )
487 o_rResult.SetWeight( WEIGHT_ULTRABOLD );
488 else
489 o_rResult.SetWeight( WEIGHT_BLACK );
491 else
492 o_rResult.SetWeight( (aInfo.macStyle & 1) ? WEIGHT_BOLD : WEIGHT_NORMAL );
493 // set width
494 if( aInfo.width )
496 if( aInfo.width == FWIDTH_ULTRA_CONDENSED )
497 o_rResult.SetAverageFontWidth( WIDTH_ULTRA_CONDENSED );
498 else if( aInfo.width == FWIDTH_EXTRA_CONDENSED )
499 o_rResult.SetAverageFontWidth( WIDTH_EXTRA_CONDENSED );
500 else if( aInfo.width == FWIDTH_CONDENSED )
501 o_rResult.SetAverageFontWidth( WIDTH_CONDENSED );
502 else if( aInfo.width == FWIDTH_SEMI_CONDENSED )
503 o_rResult.SetAverageFontWidth( WIDTH_SEMI_CONDENSED );
504 else if( aInfo.width == FWIDTH_NORMAL )
505 o_rResult.SetAverageFontWidth( WIDTH_NORMAL );
506 else if( aInfo.width == FWIDTH_SEMI_EXPANDED )
507 o_rResult.SetAverageFontWidth( WIDTH_SEMI_EXPANDED );
508 else if( aInfo.width == FWIDTH_EXPANDED )
509 o_rResult.SetAverageFontWidth( WIDTH_EXPANDED );
510 else if( aInfo.width == FWIDTH_EXTRA_EXPANDED )
511 o_rResult.SetAverageFontWidth( WIDTH_EXTRA_EXPANDED );
512 else if( aInfo.width >= FWIDTH_ULTRA_EXPANDED )
513 o_rResult.SetAverageFontWidth( WIDTH_ULTRA_EXPANDED );
515 // set italic
516 o_rResult.SetItalic( (aInfo.italicAngle != 0) ? ITALIC_NORMAL : ITALIC_NONE );
518 // set pitch
519 o_rResult.SetPitch( (aInfo.pitch == 0) ? PITCH_VARIABLE : PITCH_FIXED );
521 // set style name
522 if( aInfo.usubfamily )
523 o_rResult.SetStyleName( OUString( aInfo.usubfamily ) );
524 else if( aInfo.subfamily )
525 o_rResult.SetStyleName( OUString::createFromAscii( aInfo.subfamily ) );
527 // cleanup
528 CloseTTFont( pTTF );
529 // success
530 bResult = true;
532 return bResult;
535 struct WeightSearchEntry
537 const char* string;
538 int string_len;
539 FontWeight weight;
541 bool operator<( const WeightSearchEntry& rRight ) const
543 return rtl_str_compareIgnoreAsciiCase_WithLength( string, string_len, rRight.string, rRight.string_len ) < 0;
546 weight_table[] =
548 { "black", 5, WEIGHT_BLACK },
549 { "bold", 4, WEIGHT_BOLD },
550 { "book", 4, WEIGHT_LIGHT },
551 { "demi", 4, WEIGHT_SEMIBOLD },
552 { "heavy", 5, WEIGHT_BLACK },
553 { "light", 5, WEIGHT_LIGHT },
554 { "medium", 6, WEIGHT_MEDIUM },
555 { "regular", 7, WEIGHT_NORMAL },
556 { "super", 5, WEIGHT_ULTRABOLD },
557 { "thin", 4, WEIGHT_THIN }
560 bool identifyType1Font( const char* i_pBuffer, sal_uInt32 i_nSize, Font& o_rResult )
562 bool bResult = false;
563 // might be a type1, find eexec
564 const char* pStream = i_pBuffer;
565 const char* const pExec = "eexec";
566 const char* pExecPos = std::search( pStream, pStream+i_nSize, pExec, pExec+5 );
567 if( pExecPos != pStream+i_nSize)
569 // find /FamilyName entry
570 static const char* const pFam = "/FamilyName";
571 const char* pFamPos = std::search( pStream, pExecPos, pFam, pFam+11 );
572 if( pFamPos != pExecPos )
574 // extract the string value behind /FamilyName
575 const char* pOpen = pFamPos+11;
576 while( pOpen < pExecPos && *pOpen != '(' )
577 pOpen++;
578 const char* pClose = pOpen;
579 while( pClose < pExecPos && *pClose != ')' )
580 pClose++;
581 if( pClose - pOpen > 1 )
583 o_rResult.SetFamilyName( OStringToOUString( OString( pOpen+1, pClose-pOpen-1 ), RTL_TEXTENCODING_ASCII_US ) );
587 // parse /ItalicAngle
588 static const char* const pItalic = "/ItalicAngle";
589 const char* pItalicPos = std::search( pStream, pExecPos, pItalic, pItalic+12 );
590 if( pItalicPos != pExecPos )
592 sal_Int32 nItalic = rtl_str_toInt32( pItalicPos+12, 10 );
593 o_rResult.SetItalic( (nItalic != 0) ? ITALIC_NORMAL : ITALIC_NONE );
596 // parse /Weight
597 static const char* const pWeight = "/Weight";
598 const char* pWeightPos = std::search( pStream, pExecPos, pWeight, pWeight+7 );
599 if( pWeightPos != pExecPos )
601 // extract the string value behind /Weight
602 const char* pOpen = pWeightPos+7;
603 while( pOpen < pExecPos && *pOpen != '(' )
604 pOpen++;
605 const char* pClose = pOpen;
606 while( pClose < pExecPos && *pClose != ')' )
607 pClose++;
608 if( pClose - pOpen > 1 )
610 WeightSearchEntry aEnt;
611 aEnt.string = pOpen+1;
612 aEnt.string_len = (pClose-pOpen)-1;
613 aEnt.weight = WEIGHT_NORMAL;
614 const int nEnt = SAL_N_ELEMENTS( weight_table );
615 WeightSearchEntry* pFound = std::lower_bound( weight_table, weight_table+nEnt, aEnt );
616 if( pFound != (weight_table+nEnt) )
617 o_rResult.SetWeight( pFound->weight );
621 // parse isFixedPitch
622 static const char* const pFixed = "/isFixedPitch";
623 const char* pFixedPos = std::search( pStream, pExecPos, pFixed, pFixed+13 );
624 if( pFixedPos != pExecPos )
626 // skip whitespace
627 while( pFixedPos < pExecPos-4 &&
628 ( *pFixedPos == ' ' ||
629 *pFixedPos == '\t' ||
630 *pFixedPos == '\r' ||
631 *pFixedPos == '\n' ) )
633 pFixedPos++;
635 // find "true" value
636 if( rtl_str_compareIgnoreAsciiCase_WithLength( pFixedPos, 4, "true", 4 ) == 0 )
637 o_rResult.SetPitch( PITCH_FIXED );
638 else
639 o_rResult.SetPitch( PITCH_VARIABLE );
642 return bResult;
646 Font Font::identifyFont( const void* i_pBuffer, sal_uInt32 i_nSize )
648 Font aResult;
649 if( ! identifyTrueTypeFont( i_pBuffer, i_nSize, aResult ) )
651 const char* pStream = static_cast<const char*>(i_pBuffer);
652 if( pStream && i_nSize > 100 &&
653 *pStream == '%' && pStream[1] == '!' )
655 identifyType1Font( pStream, i_nSize, aResult );
659 return aResult;
662 // The inlines from the font.hxx header are now instantiated for pImpl-ification
663 const Color& Font::GetColor() const { return mpImplFont->maColor; }
664 const Color& Font::GetFillColor() const { return mpImplFont->maFillColor; }
665 bool Font::IsTransparent() const { return mpImplFont->mbTransparent; }
667 FontAlign Font::GetAlignment() const { return mpImplFont->GetAlignment(); }
669 const OUString& Font::GetFamilyName() const { return mpImplFont->GetFamilyName(); }
670 const OUString& Font::GetStyleName() const { return mpImplFont->maStyleName; }
672 const Size& Font::GetFontSize() const { return mpImplFont->GetFontSize(); }
673 void Font::SetFontHeight( long nHeight ) { SetFontSize( Size( mpImplFont->GetFontSize().Width(), nHeight ) ); }
674 long Font::GetFontHeight() const { return mpImplFont->GetFontSize().Height(); }
675 void Font::SetAverageFontWidth( long nWidth ) { SetFontSize( Size( nWidth, mpImplFont->GetFontSize().Height() ) ); }
676 long Font::GetAverageFontWidth() const { return mpImplFont->GetFontSize().Width(); }
678 rtl_TextEncoding Font::GetCharSet() const { return mpImplFont->GetCharSet(); }
680 const LanguageTag& Font::GetLanguageTag() const { return mpImplFont->maLanguageTag; }
681 const LanguageTag& Font::GetCJKContextLanguageTag() const { return mpImplFont->maCJKLanguageTag; }
682 LanguageType Font::GetLanguage() const { return mpImplFont->maLanguageTag.getLanguageType( false); }
683 LanguageType Font::GetCJKContextLanguage() const { return mpImplFont->maCJKLanguageTag.getLanguageType( false); }
685 short Font::GetOrientation() const { return mpImplFont->mnOrientation; }
686 bool Font::IsVertical() const { return mpImplFont->mbVertical; }
687 FontKerning Font::GetKerning() const { return mpImplFont->meKerning; }
689 FontPitch Font::GetPitch() { return mpImplFont->GetPitch(); }
690 FontWeight Font::GetWeight() { return mpImplFont->GetWeight(); }
691 FontWidth Font::GetWidthType() { return mpImplFont->GetWidthType(); }
692 FontItalic Font::GetItalic() { return mpImplFont->GetItalic(); }
693 FontFamily Font::GetFamilyType() { return mpImplFont->GetFamilyType(); }
695 FontPitch Font::GetPitch() const { return mpImplFont->GetPitchNoAsk(); }
696 FontWeight Font::GetWeight() const { return mpImplFont->GetWeightNoAsk(); }
697 FontWidth Font::GetWidthType() const { return mpImplFont->GetWidthTypeNoAsk(); }
698 FontItalic Font::GetItalic() const { return mpImplFont->GetItalicNoAsk(); }
699 FontFamily Font::GetFamilyType() const { return mpImplFont->GetFamilyTypeNoAsk(); }
701 int Font::GetQuality() const { return mpImplFont->GetQuality(); }
702 void Font::SetQuality( int nQuality ) { mpImplFont->SetQuality( nQuality ); }
703 void Font::IncreaseQualityBy( int nQualityAmount ) { mpImplFont->IncreaseQualityBy( nQualityAmount ); }
704 void Font::DecreaseQualityBy( int nQualityAmount ) { mpImplFont->DecreaseQualityBy( nQualityAmount ); }
706 void Font::SetMapNames( OUString const & aMapNames ) { mpImplFont->SetMapNames(aMapNames); }
708 bool Font::IsOutline() const { return mpImplFont->mbOutline; }
709 bool Font::IsShadow() const { return mpImplFont->mbShadow; }
710 FontRelief Font::GetRelief() const { return mpImplFont->meRelief; }
711 FontLineStyle Font::GetUnderline() const { return mpImplFont->meUnderline; }
712 FontLineStyle Font::GetOverline() const { return mpImplFont->meOverline; }
713 FontStrikeout Font::GetStrikeout() const { return mpImplFont->meStrikeout; }
714 FontEmphasisMark Font::GetEmphasisMark() const { return mpImplFont->meEmphasisMark; }
715 bool Font::IsWordLineMode() const { return mpImplFont->mbWordLine; }
716 bool Font::IsSameInstance( const vcl::Font& rFont ) const { return (mpImplFont == rFont.mpImplFont); }
719 ImplFont::ImplFont() :
720 meWeight( WEIGHT_DONTKNOW ),
721 meFamily( FAMILY_DONTKNOW ),
722 mePitch( PITCH_DONTKNOW ),
723 meWidthType( WIDTH_DONTKNOW ),
724 meItalic( ITALIC_NONE ),
725 meAlign( ALIGN_TOP ),
726 meUnderline( LINESTYLE_NONE ),
727 meOverline( LINESTYLE_NONE ),
728 meStrikeout( STRIKEOUT_NONE ),
729 meRelief( FontRelief::NONE ),
730 meEmphasisMark( FontEmphasisMark::NONE ),
731 meKerning( FontKerning::FontSpecific ),
732 meCharSet( RTL_TEXTENCODING_DONTKNOW ),
733 maLanguageTag( LANGUAGE_DONTKNOW ),
734 maCJKLanguageTag( LANGUAGE_DONTKNOW ),
735 mbSymbolFlag( false ),
736 mbOutline( false ),
737 mbConfigLookup( false ),
738 mbShadow( false ),
739 mbVertical( false ),
740 mbTransparent( true ),
741 maColor( COL_TRANSPARENT ),
742 maFillColor( COL_TRANSPARENT ),
743 mbWordLine( false ),
744 mnOrientation( 0 ),
745 mnQuality( 0 )
748 ImplFont::ImplFont( const ImplFont& rImplFont ) :
749 maFamilyName( rImplFont.maFamilyName ),
750 maStyleName( rImplFont.maStyleName ),
751 meWeight( rImplFont.meWeight ),
752 meFamily( rImplFont.meFamily ),
753 mePitch( rImplFont.mePitch ),
754 meWidthType( rImplFont.meWidthType ),
755 meItalic( rImplFont.meItalic ),
756 meAlign( rImplFont.meAlign ),
757 meUnderline( rImplFont.meUnderline ),
758 meOverline( rImplFont.meOverline ),
759 meStrikeout( rImplFont.meStrikeout ),
760 meRelief( rImplFont.meRelief ),
761 meEmphasisMark( rImplFont.meEmphasisMark ),
762 meKerning( rImplFont.meKerning ),
763 maAverageFontSize( rImplFont.maAverageFontSize ),
764 meCharSet( rImplFont.meCharSet ),
765 maLanguageTag( rImplFont.maLanguageTag ),
766 maCJKLanguageTag( rImplFont.maCJKLanguageTag ),
767 mbSymbolFlag( rImplFont.mbSymbolFlag ),
768 mbOutline( rImplFont.mbOutline ),
769 mbConfigLookup( rImplFont.mbConfigLookup ),
770 mbShadow( rImplFont.mbShadow ),
771 mbVertical( rImplFont.mbVertical ),
772 mbTransparent( rImplFont.mbTransparent ),
773 maColor( rImplFont.maColor ),
774 maFillColor( rImplFont.maFillColor ),
775 maMapNames( rImplFont.maMapNames ),
776 mbWordLine( rImplFont.mbWordLine ),
777 mnOrientation( rImplFont.mnOrientation ),
778 mnQuality( rImplFont.mnQuality )
781 bool ImplFont::operator==( const ImplFont& rOther ) const
783 // equality tests split up for easier debugging
784 if( (meWeight != rOther.meWeight)
785 || (meItalic != rOther.meItalic)
786 || (meFamily != rOther.meFamily)
787 || (mePitch != rOther.mePitch) )
788 return false;
790 if( (meCharSet != rOther.meCharSet)
791 || (maLanguageTag != rOther.maLanguageTag)
792 || (maCJKLanguageTag != rOther.maCJKLanguageTag)
793 || (meAlign != rOther.meAlign) )
794 return false;
796 if( (maAverageFontSize != rOther.maAverageFontSize)
797 || (mnOrientation != rOther.mnOrientation)
798 || (mbVertical != rOther.mbVertical) )
799 return false;
801 if( (maFamilyName != rOther.maFamilyName)
802 || (maStyleName != rOther.maStyleName) )
803 return false;
805 if( (maColor != rOther.maColor)
806 || (maFillColor != rOther.maFillColor) )
807 return false;
809 if( (meUnderline != rOther.meUnderline)
810 || (meOverline != rOther.meOverline)
811 || (meStrikeout != rOther.meStrikeout)
812 || (meRelief != rOther.meRelief)
813 || (meEmphasisMark != rOther.meEmphasisMark)
814 || (mbWordLine != rOther.mbWordLine)
815 || (mbOutline != rOther.mbOutline)
816 || (mbShadow != rOther.mbShadow)
817 || (meKerning != rOther.meKerning)
818 || (mbTransparent != rOther.mbTransparent) )
819 return false;
821 return true;
824 void ImplFont::AskConfig()
826 if( mbConfigLookup )
827 return;
829 mbConfigLookup = true;
831 // prepare the FontSubst configuration lookup
832 const utl::FontSubstConfiguration& rFontSubst = utl::FontSubstConfiguration::get();
834 OUString aShortName;
835 OUString aFamilyName;
836 ImplFontAttrs nType = ImplFontAttrs::None;
837 FontWeight eWeight = WEIGHT_DONTKNOW;
838 FontWidth eWidthType = WIDTH_DONTKNOW;
839 OUString aMapName = GetEnglishSearchFontName( maFamilyName );
841 utl::FontSubstConfiguration::getMapName( aMapName,
842 aShortName, aFamilyName, eWeight, eWidthType, nType );
844 // lookup the font name in the configuration
845 const utl::FontNameAttr* pFontAttr = rFontSubst.getSubstInfo( aMapName );
847 // if the direct lookup failed try again with an alias name
848 if ( !pFontAttr && (aShortName != aMapName) )
849 pFontAttr = rFontSubst.getSubstInfo( aShortName );
851 if( pFontAttr )
853 // the font was found in the configuration
854 if( meFamily == FAMILY_DONTKNOW )
856 if ( pFontAttr->Type & ImplFontAttrs::Serif )
857 meFamily = FAMILY_ROMAN;
858 else if ( pFontAttr->Type & ImplFontAttrs::SansSerif )
859 meFamily = FAMILY_SWISS;
860 else if ( pFontAttr->Type & ImplFontAttrs::Typewriter )
861 meFamily = FAMILY_MODERN;
862 else if ( pFontAttr->Type & ImplFontAttrs::Italic )
863 meFamily = FAMILY_SCRIPT;
864 else if ( pFontAttr->Type & ImplFontAttrs::Decorative )
865 meFamily = FAMILY_DECORATIVE;
868 if( mePitch == PITCH_DONTKNOW )
870 if ( pFontAttr->Type & ImplFontAttrs::Fixed )
871 mePitch = PITCH_FIXED;
875 // if some attributes are still unknown then use the FontSubst magic
876 if( meFamily == FAMILY_DONTKNOW )
878 if( nType & ImplFontAttrs::Serif )
879 meFamily = FAMILY_ROMAN;
880 else if( nType & ImplFontAttrs::SansSerif )
881 meFamily = FAMILY_SWISS;
882 else if( nType & ImplFontAttrs::Typewriter )
883 meFamily = FAMILY_MODERN;
884 else if( nType & ImplFontAttrs::Italic )
885 meFamily = FAMILY_SCRIPT;
886 else if( nType & ImplFontAttrs::Decorative )
887 meFamily = FAMILY_DECORATIVE;
890 if( GetWeight() == WEIGHT_DONTKNOW )
891 SetWeight( eWeight );
892 if( meWidthType == WIDTH_DONTKNOW )
893 meWidthType = eWidthType;
896 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */