Files
libreoffice/editeng/source/items/svxfont.cxx

740 lines
23 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
re-base on ALv2 code. Includes (at least) relevant parts of: linecap: Reintegrating finished LineCap feature Patch contributed by Regina Henschel http://svn.apache.org/viewvc?view=revision&revision=1232507 Patches contributed by Sven Jacobi impress212: #i81610# fixed animation export http://svn.apache.org/viewvc?view=revision&revision=1167620 impress212: drawinglayer gbuild environment changes http://svn.apache.org/viewvc?view=revision&revision=1167627 http://svn.apache.org/viewvc?view=revision&revision=1167628 impress212: DffPropSet -> minor code improvements, removing table http://svn.apache.org/viewvc?view=revision&revision=1167634 impress212: #158494# fixed excel import (text rotation) http://svn.apache.org/viewvc?view=revision&revision=1167638 Patches contributed by Armin Le Grand Svg: Reintegrated Svg replacement from /branches/alg/svgreplavement http://svn.apache.org/viewvc?view=revision&revision=1220836 #118728# changed indentifying definitions for Svg file detection http://svn.apache.org/viewvc?view=revision&revision=1229961 #118838# LineGeometry creation for complicated cases optimized to create single Polygons http://svn.apache.org/viewvc?view=revision&revision=1236232 #119176# corrected file type detection for SVG for svg files without xml header http://svn.apache.org/viewvc?view=revision&revision=1309445 #118728# Extended Svg file detection http://svn.apache.org/viewvc?view=revision&revision=1230531 #118529# solve break converters and convert commands for OLEs and images http://svn.apache.org/viewvc?view=revision&revision=1186168 svg: added WaE changes from branch svgreplacement to trunc http://svn.apache.org/viewvc?view=revision&revision=1222974 svg: corrected missing member initialization http://svn.apache.org/viewvc?view=revision&revision=1226134 fix for #118525#: Using primitives for chart sub-geometry visualisation http://svn.apache.org/viewvc?view=revision&revision=1226879 #118898# Adapted ImpGraphic::ImplGetBitmap to correctly convert metafiles to bitmapEx ... http://svn.apache.org/viewvc?view=revision&revision=1293316 fix for #118525#: removed no longer used variable maOriginalMapMode, one more exception eliminated http://svn.apache.org/viewvc?view=revision&revision=1227097 #16758# Added buffering to the VDev usages of the VclProcessor2D derivates... http://svn.apache.org/viewvc?view=revision&revision=1229521 #116758# Secured VDev buffer device to Vcl deinit http://svn.apache.org/viewvc?view=revision&revision=1230574 #116758# added remembering allocated VDevs for VDevBuffer to be able to also delete these when vcl goes down; it should never happen, but You never know http://svn.apache.org/viewvc?view=revision&revision=1230927 #118730# Changed SvgClipPathNode to use MaskPrimitive2D for primitive representation instead of TransparencePrimitive2D http://svn.apache.org/viewvc?view=revision&revision=1231198 #118822# secured 3D geometry creation (slices) by subdividing the 2D source polyPolygon early http://svn.apache.org/viewvc?view=revision&revision=1234749 #118829# enhanced Svg gradient quality, obstacles avoided http://svn.apache.org/viewvc?view=revision&revision=1235361 #118834# Unified usage of TextBreakupHelper as single tooling class for i18n text primitive breakup http://svn.apache.org/viewvc?view=revision&revision=1236110 #118853# added square pixel size limit to conversion of TransparencePrimitive2D to Metafile action http://svn.apache.org/viewvc?view=revision&revision=1237656 #118824# coreccted mirroring and boundrect when the graphicmanager is used for bitmap output http://svn.apache.org/viewvc?view=revision&revision=1240097 #115092# Corrected VclProcessor2D::RenderPolygonStrokePrimitive2D for various optimization scenarios http://svn.apache.org/viewvc?view=revision&revision=1241434 #118783# Corrected errors in ID strings, corrected Svg line/fill export, corrected polygon close state http://svn.apache.org/viewvc?view=revision&revision=1232006 #118796# corrected null-pointer usage in SVG text exporter http://svn.apache.org/viewvc?view=revision&revision=1240262 #118729# Use GraphicStreamUrl and GraphicUrl to allow multi image import with linked graphics, too http://svn.apache.org/viewvc?view=revision&revision=1229962 #118898# corrected error in GDIMetaFile::GetBoundRect in handling MetaFloatTransparentAction http://svn.apache.org/viewvc?view=revision&revision=1293349 #118855# Corrected handling of possibly created empty clipRegions after PolyPolygon clipping http://svn.apache.org/viewvc?view=revision&revision=1237725 #115962# Better (but not yet optimal, see comments in task) handling of MetaFloatTransparentAction in PDF export http://svn.apache.org/viewvc?view=revision&revision=1241078 IP clearance: #118466# This patch removes librsvg, libcroco, libgsf, ... http://svn.apache.org/viewvc?view=revision&revision=1200879 118779# Added svg content streaming in/out to ImpGraphic stream operators http://svn.apache.org/viewvc?view=revision&revision=1231908 linecap: correctons for WaE and mac drawing http://svn.apache.org/viewvc?view=revision&revision=1232793 svg: uses current system Dpi for Svg replacement image creation http://svn.apache.org/viewvc?view=revision&revision=1233948 Patches contributed by Mathias Bauer (and others) gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 http://svn.apache.org/viewvc?view=revision&revision=1394326 Remove duplicate header includes. cws mba34issues01: #i117720#: convert assertion into warning http://svn.apache.org/viewvc?view=revision&revision=1172352 118485 - Styles for OLEs are not saved. Submitted by Armin Le Grand. http://svn.apache.org/viewvc?view=revision&revision=1182166 cws mba34issues01: #i117714#: remove assertion http://svn.apache.org/viewvc?view=revision&revision=1172357 Patch contributed by Jurgen Schmidt add some additional checks to ensure proper reading operations http://svn.apache.org/viewvc?view=revision&revision=1209022 mostly prefer our stream / bounds checking work. Patches contributed by Herbert Duerr #i118816# add clarifying comment regarding Font::*Color*() methods http://svn.apache.org/viewvc?view=revision&revision=1233833 extend macro->string handling for empty strings http://svn.apache.org/viewvc?view=revision&revision=1175801 avoid magic constants for SALCOLOR_NONE http://svn.apache.org/viewvc?view=revision&revision=1177543 initialize slant properly in ImplFontMetricData constructor (author=iorsh) http://svn.apache.org/viewvc?view=revision&revision=1177551 #i118675# make check for extension updates more stable http://svn.apache.org/viewvc?view=revision&revision=1214797 #a118617# remove VBasicEventListener.dll binary There are no known users depending on its CLSID http://svn.apache.org/viewvc?view=revision&revision=1203697 Patches contributed by Ariel Constenla-Haile Fix build breaker on Linux/gcc http://svn.apache.org/viewvc?view=revision&revision=1221104 Fix crash when trying to instantiate css.graphic.GraphicRasterizer_RSVG http://svn.apache.org/viewvc?view=revision&revision=1215559 Patches contributed by Oliver-Rainer Wittmann sw34bf06: #i117962# - method <SwFlyFrm::IsPaint(..)> - consider instances of <SwFlyDrawObj> http://svn.apache.org/viewvc?view=revision&revision=1172120 sw34bf06: #i117783# - Writer's implementation of XPagePrintable - apply print settings to new printing routines http://svn.apache.org/viewvc?view=revision&revision=1172115 gnumake4 work variously from Hans-Joachim Lankenau http://svn.apache.org/viewvc?view=revision&revision=1397315 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1396782 http://svn.apache.org/viewvc?view=revision&revision=1394707 plus some amount of re-splitting of legacy headers. Patch contributed by Pavel Janik WaE: Remove unused variables. http://svn.apache.org/viewvc?view=revision&revision=1230697 Patches contributed by Takashi Ono mingwport35: i#117795: MinGW port fix for vcl2gnumake http://svn.apache.org/viewvc?view=revision&revision=1172091 mingwport35: i#117795: MinGW port fix for vcl2gnumake http://svn.apache.org/viewvc?view=revision&revision=1172091 Patch contributed by Christian Lippka impress212: #i98044# re enable Text menu for outline and title shapes http://svn.apache.org/viewvc?view=revision&revision=1167639 Patch contributed by Andre Fischer 118674: Made category B code optional and disabled by default. http://svn.apache.org/viewvc?view=revision&revision=1215131 118881: Ignore empty paragraphs after bullets. http://svn.apache.org/viewvc?view=revision&revision=1296205 Patches contributed by Philipp Lohmann ooo340fixes: #i117780# use rtl allocator http://svn.apache.org/viewvc?view=revision&revision=1172087 ooo34gsl02: #i117807# fix an off by one error (index actually inside the pfb section header) http://svn.apache.org/viewvc?view=revision&revision=1167576 various cleanups, related compilation fixes, warning cleanups, re-working of obsolete stl template pieces to use boost instead, changed string classes, re-adapt KDE about data, about dialog, fixing warnings, and other fixes & improvements. Disable svg import / render for about/ branding code-paths for now. Restore full icon theme set. Remove OS/2 conditionals and sources. Remove conflicting gtk/full-screen monitors support. Retain existing svg rasterizer files - temporarily disabled. Standardize stringificaiton and fixup dllpostfix issues. Rename SvgGradientHelper::== to equalTo to avoid overloading issues. Use the flat GdiPlus API for LineCaps calls.
2012-10-09 12:22:23 +01:00
/*
* 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/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
2000-09-18 16:07:07 +00:00
#include <comphelper/string.hxx>
2000-09-18 16:07:07 +00:00
#include <vcl/outdev.hxx>
#include <vcl/print.hxx>
#include <tools/gen.hxx>
#include <tools/poly.hxx>
#include <unotools/charclass.hxx>
#include <editeng/unolingu.hxx>
#include <com/sun/star/i18n/KCharacterType.hpp>
#include <editeng/svxfont.hxx>
#include <editeng/escapementitem.hxx>
2000-09-18 16:07:07 +00:00
SvxFont::SvxFont()
{
nKern = nEsc = 0;
nPropr = 100;
eCaseMap = SVX_CASEMAP_NOT_MAPPED;
SetLanguage(LANGUAGE_SYSTEM);
2000-09-18 16:07:07 +00:00
}
SvxFont::SvxFont( const vcl::Font &rFont )
2000-09-18 16:07:07 +00:00
: Font( rFont )
{
nKern = nEsc = 0;
nPropr = 100;
eCaseMap = SVX_CASEMAP_NOT_MAPPED;
SetLanguage(LANGUAGE_SYSTEM);
2000-09-18 16:07:07 +00:00
}
SvxFont::SvxFont( const SvxFont &rFont )
: Font( rFont )
{
nKern = rFont.GetFixKerning();
nEsc = rFont.GetEscapement();
nPropr = rFont.GetPropr();
eCaseMap = rFont.GetCaseMap();
SetLanguage(rFont.GetLanguage());
2000-09-18 16:07:07 +00:00
}
void SvxFont::DrawArrow( OutputDevice &rOut, const Rectangle& rRect,
const Size& rSize, const Color& rCol, bool bLeft )
2000-09-18 16:07:07 +00:00
{
long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2;
long nRight = nLeft + rSize.Width();
long nMid = ( rRect.Top() + rRect.Bottom() ) / 2;
long nTop = nMid - rSize.Height() / 2;
long nBottom = nTop + rSize.Height();
if( nLeft < rRect.Left() )
{
nLeft = rRect.Left();
nRight = rRect.Right();
}
if( nTop < rRect.Top() )
{
nTop = rRect.Top();
nBottom = rRect.Bottom();
}
tools::Polygon aPoly;
2000-09-18 16:07:07 +00:00
Point aTmp( bLeft ? nLeft : nRight, nMid );
Point aNxt( bLeft ? nRight : nLeft, nTop );
aPoly.Insert( 0, aTmp );
aPoly.Insert( 0, aNxt );
aNxt.Y() = nBottom;
aPoly.Insert( 0, aNxt );
aPoly.Insert( 0, aTmp );
Color aOldLineColor = rOut.GetLineColor();
Color aOldFillColor = rOut.GetFillColor();
rOut.SetFillColor( rCol );
rOut.SetLineColor( Color( COL_BLACK ) );
rOut.DrawPolygon( aPoly );
rOut.DrawLine( aTmp, aNxt );
rOut.SetLineColor( aOldLineColor );
rOut.SetFillColor( aOldFillColor );
}
OUString SvxFont::CalcCaseMap(const OUString &rTxt) const
2000-09-18 16:07:07 +00:00
{
if (!IsCaseMap() || rTxt.isEmpty())
return rTxt;
OUString aTxt(rTxt);
2011-02-16 16:34:02 -05:00
// I still have to get the language
const LanguageType eLang = LANGUAGE_DONTKNOW == GetLanguage()
? LANGUAGE_SYSTEM : GetLanguage();
LanguageTag aLanguageTag(eLang);
CharClass aCharClass( aLanguageTag );
2000-09-18 16:07:07 +00:00
switch( eCaseMap )
{
case SVX_CASEMAP_KAPITAELCHEN:
case SVX_CASEMAP_VERSALIEN:
{
aTxt = aCharClass.uppercase( aTxt );
2000-09-18 16:07:07 +00:00
break;
}
case SVX_CASEMAP_GEMEINE:
{
aTxt = aCharClass.lowercase( aTxt );
2000-09-18 16:07:07 +00:00
break;
}
case SVX_CASEMAP_TITEL:
{
2011-02-16 16:34:02 -05:00
// Every beginning of a word is capitalized, the rest of the word
// is taken over as is.
// Bug: if the attribute starts in the middle of the word.
bool bBlank = true;
2000-09-18 16:07:07 +00:00
for (sal_Int32 i = 0; i < aTxt.getLength(); ++i)
2000-09-18 16:07:07 +00:00
{
if( aTxt[i] == ' ' || aTxt[i] == '\t')
bBlank = true;
2000-09-18 16:07:07 +00:00
else
{
if (bBlank)
2000-09-18 16:07:07 +00:00
{
OUString sTitle(aCharClass.uppercase(OUString(aTxt[i])));
aTxt = aTxt.replaceAt(i, 1, sTitle);
2000-09-18 16:07:07 +00:00
}
bBlank = false;
2000-09-18 16:07:07 +00:00
}
}
break;
}
default:
{
DBG_ASSERT(false, "SvxFont::CaseMapTxt: unknown casemap");
2000-09-18 16:07:07 +00:00
break;
}
}
return aTxt;
}
/*************************************************************************
* class SvxDoCapitals
2011-02-16 16:34:02 -05:00
* The virtual Method Do si called by SvxFont::DoOnCapitals alternately
* the uppercase and lowercase parts. The derivate of SvxDoCapitals fills
* this method with life.
2000-09-18 16:07:07 +00:00
*************************************************************************/
class SvxDoCapitals
{
protected:
VclPtr<OutputDevice> pOut;
const OUString &rTxt;
const sal_Int32 nIdx;
const sal_Int32 nLen;
2000-09-18 16:07:07 +00:00
public:
SvxDoCapitals( OutputDevice *_pOut, const OUString &_rTxt,
const sal_Int32 _nIdx, const sal_Int32 _nLen )
: pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen)
2000-09-18 16:07:07 +00:00
{ }
virtual ~SvxDoCapitals() {}
virtual void DoSpace( const bool bDraw );
2000-09-18 16:07:07 +00:00
virtual void SetSpace();
virtual void Do( const OUString &rTxt,
const sal_Int32 nIdx, const sal_Int32 nLen,
const bool bUpper ) = 0;
2000-09-18 16:07:07 +00:00
const OUString &GetTxt() const { return rTxt; }
sal_Int32 GetIdx() const { return nIdx; }
sal_Int32 GetLen() const { return nLen; }
2000-09-18 16:07:07 +00:00
};
void SvxDoCapitals::DoSpace( const bool /*bDraw*/ ) { }
2000-09-18 16:07:07 +00:00
void SvxDoCapitals::SetSpace() { }
/*************************************************************************
* SvxFont::DoOnCapitals() const
2011-02-16 16:34:02 -05:00
* Decomposes the String into uppercase and lowercase letters and then
* calls the method SvxDoCapitals::Do( ).
2000-09-18 16:07:07 +00:00
*************************************************************************/
void SvxFont::DoOnCapitals(SvxDoCapitals &rDo) const
2000-09-18 16:07:07 +00:00
{
const OUString &rTxt = rDo.GetTxt();
const sal_Int32 nIdx = rDo.GetIdx();
const sal_Int32 nLen = rDo.GetLen();
2000-09-18 16:07:07 +00:00
const OUString aTxt( CalcCaseMap( rTxt ) );
const sal_Int32 nTxtLen = std::min( rTxt.getLength(), nLen );
sal_Int32 nPos = 0;
sal_Int32 nOldPos = nPos;
2000-09-18 16:07:07 +00:00
// Test if string length differ between original and CaseMapped
bool bCaseMapLengthDiffers(aTxt.getLength() != rTxt.getLength());
const LanguageType eLang = LANGUAGE_DONTKNOW == GetLanguage()
? LANGUAGE_SYSTEM : GetLanguage();
LanguageTag aLanguageTag(eLang);
CharClass aCharClass( aLanguageTag );
OUString aCharString;
2000-09-18 16:07:07 +00:00
while( nPos < nTxtLen )
{
// first in turn are the uppercase letters
2011-02-16 16:34:02 -05:00
// There are characters that are both upper- and lower-case L (eg blank)
// Such ambiguities lead to chaos, this is why these characters are
// allocated to the lowercase characters!
while( nPos < nTxtLen )
{
aCharString = rTxt.copy( nPos + nIdx, 1 );
sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
if ( nCharacterType & css::i18n::KCharacterType::LOWER )
break;
if ( ! ( nCharacterType & css::i18n::KCharacterType::UPPER ) )
break;
++nPos;
}
2000-09-18 16:07:07 +00:00
if( nOldPos != nPos )
{
if(bCaseMapLengthDiffers)
{
// If strings differ work preparing the necessary snippet to address that
// potential difference
const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos-nOldPos);
OUString aNewText = CalcCaseMap(aSnippet);
rDo.Do( aNewText, 0, aNewText.getLength(), true );
}
else
{
rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, true );
}
2000-09-18 16:07:07 +00:00
nOldPos = nPos;
}
2011-02-16 16:34:02 -05:00
// Now the lowercase are processed (without blanks)
while( nPos < nTxtLen )
{
sal_uInt32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
if ( ( nCharacterType & css::i18n::KCharacterType::UPPER ) )
break;
if ( aCharString == " " )
break;
if( ++nPos < nTxtLen )
aCharString = rTxt.copy( nPos + nIdx, 1 );
}
2000-09-18 16:07:07 +00:00
if( nOldPos != nPos )
{
if(bCaseMapLengthDiffers)
{
// If strings differ work preparing the necessary snippet to address that
// potential difference
const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos - nOldPos);
OUString aNewText = CalcCaseMap(aSnippet);
rDo.Do( aNewText, 0, aNewText.getLength(), false );
}
else
{
rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, false );
}
2000-09-18 16:07:07 +00:00
nOldPos = nPos;
}
2011-02-16 16:34:02 -05:00
// Now the blanks are<processed
while( nPos < nTxtLen && aCharString == " " && ++nPos < nTxtLen )
aCharString = rTxt.copy( nPos + nIdx, 1 );
2000-09-18 16:07:07 +00:00
if( nOldPos != nPos )
{
rDo.DoSpace( false );
if(bCaseMapLengthDiffers)
{
// If strings differ work preparing the necessary snippet to address that
// potential difference
const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos - nOldPos);
OUString aNewText = CalcCaseMap(aSnippet);
rDo.Do( aNewText, 0, aNewText.getLength(), false );
}
else
{
rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, false );
}
2000-09-18 16:07:07 +00:00
nOldPos = nPos;
rDo.SetSpace();
}
}
rDo.DoSpace( true );
2000-09-18 16:07:07 +00:00
}
void SvxFont::SetPhysFont( OutputDevice *pOut ) const
{
const vcl::Font& rCurrentFont = pOut->GetFont();
2000-09-18 16:07:07 +00:00
if ( nPropr == 100 )
{
if ( !rCurrentFont.IsSameInstance( *this ) )
pOut->SetFont( *this );
}
else
{
Font aNewFont( *this );
Size aSize( aNewFont.GetFontSize() );
aNewFont.SetFontSize( Size( aSize.Width() * nPropr / 100L,
2000-09-18 16:07:07 +00:00
aSize.Height() * nPropr / 100L ) );
if ( !rCurrentFont.IsSameInstance( aNewFont ) )
pOut->SetFont( aNewFont );
}
}
vcl::Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const
2000-09-18 16:07:07 +00:00
{
vcl::Font aOldFont( pOut->GetFont() );
2000-09-18 16:07:07 +00:00
SetPhysFont( pOut );
return aOldFont;
}
Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const OUString &rTxt,
const sal_Int32 nIdx, const sal_Int32 nLen ) const
2000-09-18 16:07:07 +00:00
{
if ( !IsCaseMap() && !IsKern() )
return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ),
pOut->GetTextHeight() );
Size aTxtSize;
aTxtSize.setHeight( pOut->GetTextHeight() );
if ( !IsCaseMap() )
aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) );
else
{
const OUString aNewText = CalcCaseMap(rTxt);
bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength());
sal_Int32 nWidth(0L);
if(bCaseMapLengthDiffers)
{
// If strings differ work preparing the necessary snippet to address that
// potential difference
const OUString aSnippet = rTxt.copy(nIdx, nLen);
OUString _aNewText = CalcCaseMap(aSnippet);
nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.getLength() );
}
else
{
nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen );
}
aTxtSize.setWidth(nWidth);
}
2000-09-18 16:07:07 +00:00
if( IsKern() && ( nLen > 1 ) )
aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
return aTxtSize;
}
Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const OUString &rTxt )
2000-09-18 16:07:07 +00:00
{
if ( !IsCaseMap() && !IsKern() )
return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() );
Size aTxtSize;
aTxtSize.setHeight( pOut->GetTextHeight() );
if ( !IsCaseMap() )
aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) );
else
aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) );
if( IsKern() && ( rTxt.getLength() > 1 ) )
aTxtSize.Width() += ( ( rTxt.getLength()-1 ) * long( nKern ) );
2000-09-18 16:07:07 +00:00
return aTxtSize;
}
Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt,
const sal_Int32 nIdx, const sal_Int32 nLen, long* pDXArray ) const
2000-09-18 16:07:07 +00:00
{
if ( !IsCaseMap() && !IsKern() )
return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ),
pOut->GetTextHeight() );
Size aTxtSize;
aTxtSize.setHeight( pOut->GetTextHeight() );
if ( !IsCaseMap() )
aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
else
aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
pDXArray, nIdx, nLen ) );
if( IsKern() && ( nLen > 1 ) )
{
aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
if ( pDXArray )
{
for ( sal_Int32 i = 0; i < nLen; i++ )
2000-09-18 16:07:07 +00:00
pDXArray[i] += ( (i+1) * long( nKern ) );
2011-02-16 16:34:02 -05:00
// The last one is a nKern too big:
2000-09-18 16:07:07 +00:00
pDXArray[nLen-1] -= nKern;
}
}
return aTxtSize;
}
Size SvxFont::GetTextSize( const OutputDevice *pOut, const OUString &rTxt,
const sal_Int32 nIdx, const sal_Int32 nLen ) const
2000-09-18 16:07:07 +00:00
{
sal_Int32 nTmp = nLen;
if ( nTmp == SAL_MAX_INT32 ) // already initialized?
nTmp = rTxt.getLength();
Font aOldFont( ChgPhysFont(const_cast<OutputDevice *>(pOut)) );
2000-09-18 16:07:07 +00:00
Size aTxtSize;
if( IsCapital() && !rTxt.isEmpty() )
2000-09-18 16:07:07 +00:00
{
aTxtSize = GetCapitalSize( pOut, rTxt, nIdx, nTmp );
}
else aTxtSize = GetPhysTxtSize(pOut,rTxt,nIdx,nTmp);
const_cast<OutputDevice *>(pOut)->SetFont( aOldFont );
2000-09-18 16:07:07 +00:00
return aTxtSize;
}
void SvxFont::QuickDrawText( OutputDevice *pOut,
const Point &rPos, const OUString &rTxt,
const sal_Int32 nIdx, const sal_Int32 nLen, const long* pDXArray ) const
2000-09-18 16:07:07 +00:00
{
2011-02-16 16:34:02 -05:00
// Font has to be selected in OutputDevice...
2000-09-18 16:07:07 +00:00
if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
{
pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen );
return;
}
Point aPos( rPos );
2001-08-10 05:06:00 +00:00
2000-09-18 16:07:07 +00:00
if ( nEsc )
2001-08-10 05:06:00 +00:00
{
long nDiff = GetFontSize().Height();
2001-08-10 05:06:00 +00:00
nDiff *= nEsc;
nDiff /= 100;
if ( !IsVertical() )
aPos.Y() -= nDiff;
else
aPos.X() += nDiff;
}
2000-09-18 16:07:07 +00:00
if( IsCapital() )
{
2011-02-16 16:34:02 -05:00
DBG_ASSERT( !pDXArray, "DrawCapital not for TextArray!" );
2000-09-18 16:07:07 +00:00
DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
}
else
{
if ( IsKern() && !pDXArray )
{
Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
if ( !IsCaseMap() )
pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
else
pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
}
else
{
if ( !IsCaseMap() )
pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
else
pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen );
}
}
}
void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter,
const Point &rPos, const OUString &rTxt,
const sal_Int32 nIdx, const sal_Int32 nLen ) const
2000-09-18 16:07:07 +00:00
{
if ( !nLen || rTxt.isEmpty() )
2000-09-18 16:07:07 +00:00
return;
sal_Int32 nTmp = nLen;
2000-09-18 16:07:07 +00:00
if ( nTmp == SAL_MAX_INT32 ) // already initialized?
nTmp = rTxt.getLength();
2000-09-18 16:07:07 +00:00
Point aPos( rPos );
if ( nEsc )
{
short nTmpEsc;
if( DFLT_ESC_AUTO_SUPER == nEsc )
nTmpEsc = 33;
else if( DFLT_ESC_AUTO_SUB == nEsc )
nTmpEsc = -20;
else
nTmpEsc = nEsc;
Size aSize = ( this->GetFontSize() );
2000-09-18 16:07:07 +00:00
aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L );
}
Font aOldFont( ChgPhysFont( pOut ) );
Font aOldPrnFont( ChgPhysFont( pPrinter ) );
if ( IsCapital() )
DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
else
{
Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
if ( !IsCaseMap() )
pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
else
{
const OUString aNewText = CalcCaseMap(rTxt);
bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength());
if(bCaseMapLengthDiffers)
{
// If strings differ work preparing the necessary snippet to address that
// potential difference
const OUString aSnippet(rTxt.copy( nIdx, nTmp));
OUString _aNewText = CalcCaseMap(aSnippet);
pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.getLength() );
}
else
{
pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp );
}
}
2000-09-18 16:07:07 +00:00
}
pOut->SetFont(aOldFont);
pPrinter->SetFont( aOldPrnFont );
}
SvxFont& SvxFont::operator=( const vcl::Font& rFont )
2000-09-18 16:07:07 +00:00
{
Font::operator=( rFont );
return *this;
}
SvxFont& SvxFont::operator=( const SvxFont& rFont )
{
Font::operator=( rFont );
eCaseMap = rFont.eCaseMap;
nEsc = rFont.nEsc;
nPropr = rFont.nPropr;
nKern = rFont.nKern;
return *this;
}
class SvxDoGetCapitalSize : public SvxDoCapitals
{
protected:
SvxFont* pFont;
Size aTxtSize;
short nKern;
public:
SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut,
const OUString &_rTxt, const sal_Int32 _nIdx,
const sal_Int32 _nLen, const short _nKrn )
: SvxDoCapitals( const_cast<OutputDevice*>(_pOut), _rTxt, _nIdx, _nLen ),
pFont( _pFnt ),
nKern( _nKrn )
2000-09-18 16:07:07 +00:00
{ }
virtual ~SvxDoGetCapitalSize() {}
virtual void Do( const OUString &rTxt, const sal_Int32 nIdx,
const sal_Int32 nLen, const bool bUpper ) override;
2000-09-18 16:07:07 +00:00
const Size &GetSize() const { return aTxtSize; };
2000-09-18 16:07:07 +00:00
};
void SvxDoGetCapitalSize::Do( const OUString &_rTxt, const sal_Int32 _nIdx,
const sal_Int32 _nLen, const bool bUpper )
2000-09-18 16:07:07 +00:00
{
Size aPartSize;
if ( !bUpper )
{
sal_uInt8 nProp = pFont->GetPropr();
pFont->SetProprRel( SMALL_CAPS_PERCENTAGE );
2000-09-18 16:07:07 +00:00
pFont->SetPhysFont( pOut );
aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
2000-09-18 16:07:07 +00:00
aPartSize.setHeight( pOut->GetTextHeight() );
aTxtSize.Height() = aPartSize.Height();
pFont->SetPropr( nProp );
pFont->SetPhysFont( pOut );
}
else
{
aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
2000-09-18 16:07:07 +00:00
aPartSize.setHeight( pOut->GetTextHeight() );
}
aTxtSize.Width() += aPartSize.Width();
aTxtSize.Width() += ( _nLen * long( nKern ) );
2000-09-18 16:07:07 +00:00
}
Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt,
const sal_Int32 nIdx, const sal_Int32 nLen) const
2000-09-18 16:07:07 +00:00
{
// Start:
SvxDoGetCapitalSize aDo( const_cast<SvxFont *>(this), pOut, rTxt, nIdx, nLen, nKern );
2000-09-18 16:07:07 +00:00
DoOnCapitals( aDo );
Size aTxtSize( aDo.GetSize() );
// End:
if( !aTxtSize.Height() )
{
aTxtSize.setWidth( 0 );
aTxtSize.setHeight( pOut->GetTextHeight() );
}
return aTxtSize;
}
class SvxDoDrawCapital : public SvxDoCapitals
{
protected:
SvxFont *pFont;
Point aPos;
Point aSpacePos;
short nKern;
public:
SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const OUString &_rTxt,
const sal_Int32 _nIdx, const sal_Int32 _nLen,
2000-09-18 16:07:07 +00:00
const Point &rPos, const short nKrn )
: SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ),
2000-09-18 16:07:07 +00:00
pFont( pFnt ),
aPos( rPos ),
aSpacePos( rPos ),
nKern( nKrn )
{ }
virtual void DoSpace( const bool bDraw ) override;
virtual void SetSpace() override;
virtual void Do( const OUString &rTxt, const sal_Int32 nIdx,
const sal_Int32 nLen, const bool bUpper ) override;
2000-09-18 16:07:07 +00:00
};
void SvxDoDrawCapital::DoSpace( const bool bDraw )
2000-09-18 16:07:07 +00:00
{
if ( bDraw || pFont->IsWordLineMode() )
{
sal_uLong nDiff = (sal_uLong)(aPos.X() - aSpacePos.X());
2000-09-18 16:07:07 +00:00
if ( nDiff )
{
bool bWordWise = pFont->IsWordLineMode();
bool bTrans = pFont->IsTransparent();
pFont->SetWordLineMode( false );
pFont->SetTransparent( true );
2000-09-18 16:07:07 +00:00
pFont->SetPhysFont( pOut );
pOut->DrawStretchText( aSpacePos, nDiff, " ", 0, 2 );
2000-09-18 16:07:07 +00:00
pFont->SetWordLineMode( bWordWise );
pFont->SetTransparent( bTrans );
pFont->SetPhysFont( pOut );
}
}
}
void SvxDoDrawCapital::SetSpace()
{
if ( pFont->IsWordLineMode() )
aSpacePos.X() = aPos.X();
}
void SvxDoDrawCapital::Do( const OUString &_rTxt, const sal_Int32 _nIdx,
const sal_Int32 _nLen, const bool bUpper)
2000-09-18 16:07:07 +00:00
{
sal_uInt8 nProp = 0;
2000-09-18 16:07:07 +00:00
Size aPartSize;
2011-02-16 16:34:02 -05:00
// Set the desired font
FontLineStyle eUnder = pFont->GetUnderline();
2000-09-18 16:07:07 +00:00
FontStrikeout eStrike = pFont->GetStrikeout();
pFont->SetUnderline( LINESTYLE_NONE );
2000-09-18 16:07:07 +00:00
pFont->SetStrikeout( STRIKEOUT_NONE );
if ( !bUpper )
{
nProp = pFont->GetPropr();
pFont->SetProprRel( SMALL_CAPS_PERCENTAGE );
2000-09-18 16:07:07 +00:00
}
pFont->SetPhysFont( pOut );
aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
2000-09-18 16:07:07 +00:00
aPartSize.setHeight( pOut->GetTextHeight() );
long nWidth = aPartSize.Width();
if ( nKern )
{
aPos.X() += (nKern/2);
if ( _nLen ) nWidth += (_nLen*long(nKern));
2000-09-18 16:07:07 +00:00
}
pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
2000-09-18 16:07:07 +00:00
2011-02-16 16:34:02 -05:00
// Restore Font
2000-09-18 16:07:07 +00:00
pFont->SetUnderline( eUnder );
pFont->SetStrikeout( eStrike );
if ( !bUpper )
pFont->SetPropr( nProp );
pFont->SetPhysFont( pOut );
aPos.X() += nWidth-(nKern/2);
}
/*************************************************************************
2011-02-16 16:34:02 -05:00
* SvxFont::DrawCapital() draws the uppercase letter.
2000-09-18 16:07:07 +00:00
*************************************************************************/
void SvxFont::DrawCapital( OutputDevice *pOut,
const Point &rPos, const OUString &rTxt,
const sal_Int32 nIdx, const sal_Int32 nLen ) const
2000-09-18 16:07:07 +00:00
{
SvxDoDrawCapital aDo( const_cast<SvxFont *>(this),pOut,rTxt,nIdx,nLen,rPos,nKern );
2000-09-18 16:07:07 +00:00
DoOnCapitals( aDo );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */