summaryrefslogtreecommitdiffstats
path: root/svx/source/dialog/fntctrl.cxx
diff options
context:
space:
mode:
authorAndreas Martens <ama@openoffice.org>2001-07-19 06:43:19 +0000
committerAndreas Martens <ama@openoffice.org>2001-07-19 06:43:19 +0000
commitd15d274d631c9ab827a464ff9ccf63b6a4036b25 (patch)
treefee0cf5ae7a6a215337f60fdd8f6a5bd587e143e /svx/source/dialog/fntctrl.cxx
parent#87966# EE_FORMAT_XML (diff)
downloadcore-d15d274d631c9ab827a464ff9ccf63b6a4036b25.tar.gz
core-d15d274d631c9ab827a464ff9ccf63b6a4036b25.zip
Fix #86705#: Preview for Asian and Latin Unicode characters
Diffstat (limited to 'svx/source/dialog/fntctrl.cxx')
-rw-r--r--svx/source/dialog/fntctrl.cxx315
1 files changed, 280 insertions, 35 deletions
diff --git a/svx/source/dialog/fntctrl.cxx b/svx/source/dialog/fntctrl.cxx
index a96fff3f289f..1c287caa2c72 100644
--- a/svx/source/dialog/fntctrl.cxx
+++ b/svx/source/dialog/fntctrl.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: fntctrl.cxx,v $
*
- * $Revision: 1.5 $
+ * $Revision: 1.6 $
*
- * last change: $Author: os $ $Date: 2001-07-10 11:22:24 $
+ * last change: $Author: ama $ $Date: 2001-07-19 07:42:36 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -73,32 +73,265 @@
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
+
+#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
+#include <com/sun/star/uno/Reference.h>
+#endif
+
+#ifndef _COM_SUN_STAR_I18N_XBREAKITERATOR_HPP_
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#endif
+
+#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
+#include <comphelper/processfactory.hxx>
+#endif
+
+#ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
+#include <com/sun/star/i18n/ScriptType.hdl>
+#endif
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_USHORTS
+#define _SVSTDARR_ULONGS
+#define _SVSTDARR_XUB_STRLEN
+#include <svtools/svstdarr.hxx>
+#endif
+
#pragma hdrstop
#include "fntctrl.hxx"
#include "dialogs.hrc"
-// struct FontPrevWin_Impl -----------------------------------------------
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::i18n;
+
+// class FontPrevWin_Impl -----------------------------------------------
-struct FontPrevWin_Impl
+class FontPrevWin_Impl
{
- BOOL bSelection : 1,
- bGetSelection : 1,
- bUseResText : 1;
+ friend class SvxFontPrevWindow;
+ Reference < XBreakIterator > xBreak;
+ SvULongs aTextWidth;
+ SvXub_StrLens aScriptChg;
+ SvUShorts aScriptType;
+ SvxFont aCJKFont;
+ String aText;
+ String aScriptText;
Color* pColor;
Color* pBackColor;
- String aText;
-
- BOOL bTwoLines;
+ long nAscent;
sal_Unicode cStartBracket;
sal_Unicode cEndBracket;
-
+ BOOL bSelection : 1,
+ bGetSelection : 1,
+ bUseResText : 1,
+ bTwoLines : 1;
+ void _CheckScript();
+public:
FontPrevWin_Impl() :
- bSelection( FALSE ), bGetSelection( FALSE ), bUseResText( FALSE ), pColor( NULL ),
- pBackColor( 0 ),
- bTwoLines(FALSE), cStartBracket(0), cEndBracket(0) {}
+ cStartBracket(0), cEndBracket(0), pColor( NULL ), pBackColor( 0 ),
+ bSelection( FALSE ), bGetSelection( FALSE ), bUseResText( FALSE ),
+ bTwoLines( FALSE ) {}
+ void CheckScript() { if( aText != aScriptText ) _CheckScript(); }
+ Size CalcTextSize( OutputDevice* pWin, OutputDevice* pPrt, SvxFont &rFont );
+ void DrawPrev( OutputDevice* pWin, Printer* pPrt, Point &rPt,
+ SvxFont &rFont );
};
+// class FontPrevWin_Impl -----------------------------------------------
+
+/*-----------------19.7.2001 08:44------------------
+ * void FontPrevWin_Impl::_CheckScript()
+ * evalutates the scripttypes of the actual string.
+ * Afterwards the positions of script change are notified in aScriptChg,
+ * the scripttypes in aScriptType.
+ * The aTextWidth array will be filled with zero.
+ * --------------------------------------------------*/
+
+void FontPrevWin_Impl::_CheckScript()
+{
+ aScriptText = aText;
+ USHORT nCnt = aScriptChg.Count();
+ if( nCnt )
+ {
+ aScriptChg.Remove( 0, nCnt );
+ aScriptType.Remove( 0, nCnt );
+ aTextWidth.Remove( 0, nCnt );
+ nCnt = 0;
+ }
+ if( !xBreak.is() )
+ {
+ Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
+ Reference < XInterface > xI = xMSF->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) );
+ if ( xI.is() )
+ {
+ Any x = xI->queryInterface( ::getCppuType((const Reference< XBreakIterator >*)0) );
+ x >>= xBreak;
+ }
+ }
+ if( xBreak.is() )
+ {
+ USHORT nScript = xBreak->getScriptType( aText, 0 );
+ USHORT nChg = 0;
+ if( ScriptType::WEAK == nScript )
+ {
+ nChg = (xub_StrLen)xBreak->endOfScript( aText, nChg, nScript );
+ if( nChg < aText.Len() )
+ nScript = xBreak->getScriptType( aText, nChg );
+ else
+ nScript = ScriptType::LATIN;
+ }
+
+ do
+ {
+ nChg = (xub_StrLen)xBreak->endOfScript( aText, nChg, nScript );
+ aScriptChg.Insert( nChg, nCnt );
+ aScriptType.Insert( nScript, nCnt );
+ aTextWidth.Insert( ULONG(0), nCnt++ );
+
+ if( nChg < aText.Len() )
+ nScript = xBreak->getScriptType( aText, nChg );
+ else
+ break;
+ } while( TRUE );
+ }
+}
+
+/*-----------------19.7.2001 08:48------------------
+ * Size FontPrevWin_Impl::CalcTextSize(..)
+ * fills the aTextWidth array with the text width of every part
+ * of the actual string without a script change inside.
+ * For Latin parts the given rFont will be used,
+ * for Asian parts the aCJKFont.
+ * The returned size contains the whole string.
+ * The member nAscent is calculated to the maximal ascent of all used fonts.
+ * --------------------------------------------------*/
+
+Size FontPrevWin_Impl::CalcTextSize( OutputDevice* pWin, OutputDevice* pPrinter,
+ SvxFont &rFont )
+{
+ USHORT nScript;
+ USHORT nIdx = 0;
+ xub_StrLen nStart = 0;
+ xub_StrLen nEnd;
+ USHORT nCnt = aScriptChg.Count();
+ if( nCnt )
+ {
+ nEnd = aScriptChg[ nIdx ];
+ nScript = aScriptType[ nIdx ];
+ }
+ else
+ {
+ nEnd = aText.Len();
+ nScript = ScriptType::LATIN;
+ }
+ long nTxtWidth = 0;
+ long nCJKHeight = 0;
+ long nHeight = 0;
+ nAscent = 0;
+ long nCJKAscent = 0;
+ do
+ {
+ SvxFont& rFnt = (nScript==ScriptType::ASIAN) ? aCJKFont : rFont;
+ ULONG nWidth = rFnt.GetTxtSize( pPrinter, aText, nStart, nEnd-nStart ).
+ Width();
+ aTextWidth[ nIdx++ ] = nWidth;
+ nTxtWidth += nWidth;
+ if( nScript==ScriptType::ASIAN )
+ {
+ if( !nCJKHeight )
+ {
+ pWin->SetFont( aCJKFont );
+ FontMetric aMetric( pWin->GetFontMetric() );
+ nCJKHeight = aMetric.GetLineHeight();
+ nCJKAscent = aMetric.GetAscent();
+ }
+ }
+ else
+ {
+ if( !nHeight )
+ {
+ pWin->SetFont( rFont );
+ FontMetric aMetric( pWin->GetFontMetric() );
+ nHeight = aMetric.GetLineHeight();
+ nAscent = aMetric.GetAscent();
+ }
+ }
+ if( nEnd < aText.Len() && nIdx < nCnt )
+ {
+ nStart = nEnd;
+ nEnd = aScriptChg[ nIdx ];
+ nScript = aScriptType[ nIdx ];
+ }
+ else
+ break;
+ }
+ while( TRUE );
+ nHeight -= nAscent;
+ nCJKHeight -= nCJKAscent;
+ if( nHeight < nCJKHeight )
+ nHeight = nCJKHeight;
+ if( nAscent < nCJKAscent )
+ nAscent = nCJKAscent;
+ nHeight += nAscent;
+
+ Size aTxtSize( nTxtWidth, nHeight );
+ return aTxtSize;
+}
+
+/*-----------------19.7.2001 08:54------------------
+ * void FontPrevWin_Impl::DrawPrev(..)
+ * calls SvxFont::DrawPrev(..) for every part of the string without a script
+ * change inside, for Asian parts the aCJKFont will be used, otherwise the
+ * given rFont.
+ * --------------------------------------------------*/
+
+void FontPrevWin_Impl::DrawPrev( OutputDevice* pWin, Printer* pPrinter,
+ Point &rPt, SvxFont &rFont )
+{
+ Font aOldFont = pPrinter->GetFont();
+ USHORT nScript;
+ USHORT nIdx = 0;
+ xub_StrLen nStart = 0;
+ xub_StrLen nEnd;
+ USHORT nCnt = aScriptChg.Count();
+ if( nCnt )
+ {
+ nEnd = aScriptChg[ nIdx ];
+ nScript = aScriptType[ nIdx ];
+ }
+ else
+ {
+ nEnd = aText.Len();
+ nScript = ScriptType::LATIN;
+ }
+ do
+ {
+ SvxFont& rFnt = (nScript==ScriptType::ASIAN) ? aCJKFont : rFont;
+ pPrinter->SetFont( rFnt );
+
+ rFnt.DrawPrev( pWin, pPrinter, rPt, aText, nStart, nEnd - nStart );
+
+ rPt.X() += aTextWidth[ nIdx++ ];
+ if( nEnd < aText.Len() && nIdx < nCnt )
+ {
+ nStart = nEnd;
+ nEnd = aScriptChg[ nIdx ];
+ nScript = aScriptType[ nIdx ];
+ }
+ else
+ break;
+ }
+ while( TRUE );
+ pPrinter->SetFont( aOldFont );
+}
+
// class SvxFontPrevWindow -----------------------------------------------
void SvxFontPrevWindow::InitSettings( BOOL bForeground, BOOL bBackground )
@@ -145,7 +378,9 @@ SvxFontPrevWindow::SvxFontPrevWindow( Window* pParent, const ResId& rId ) :
}
SetMapMode( MapMode( MAP_TWIP ) );
aFont.SetTransparent(TRUE);
+ pImpl->aCJKFont.SetTransparent(TRUE);
aFont.SetAlign(ALIGN_BASELINE);
+ pImpl->aCJKFont.SetAlign(ALIGN_BASELINE);
InitSettings( TRUE, TRUE );
SetBorderStyle( WINDOW_BORDER_MONO );
}
@@ -164,6 +399,13 @@ SvxFontPrevWindow::~SvxFontPrevWindow()
// -----------------------------------------------------------------------
+SvxFont& SvxFontPrevWindow::GetCJKFont()
+{
+ return pImpl->aCJKFont;
+}
+
+// -----------------------------------------------------------------------
+
void SvxFontPrevWindow::StateChanged( StateChangedType nType )
{
if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
@@ -245,20 +487,17 @@ void SvxFontPrevWindow::Paint( const Rectangle& rRect )
if ( pImpl->aText.Len() > 15 )
pImpl->aText.Erase( pImpl->aText.Search( sal_Unicode( ' ' ), 16 ) );
}
- Window::SetFont(aFont);
- Font aOldFont = pPrinter->GetFont();
- pPrinter->SetFont( aFont );
- Size aTxtSize( aFont.GetTxtSize( pPrinter, pImpl->aText ) );
- pPrinter->SetFont( aOldFont );
+
+ pImpl->CheckScript();
+ Size aTxtSize = pImpl->CalcTextSize( this, pPrinter, aFont );
+
const Size aLogSize( GetOutputSize() );
- FontMetric aMetric(GetFontMetric());
- aTxtSize.Height() = aMetric.GetLineHeight();
long nX = aLogSize.Width() / 2 - aTxtSize.Width() / 2;
long nY = aLogSize.Height() / 2 - aTxtSize.Height() / 2;
- if ( nY + aMetric.GetAscent() > aLogSize.Height() )
- nY = aLogSize.Height() - aMetric.GetAscent();
+ if ( nY + pImpl->nAscent > aLogSize.Height() )
+ nY = aLogSize.Height() - pImpl->nAscent;
if ( pImpl->pBackColor )
{
@@ -283,13 +522,23 @@ void SvxFontPrevWindow::Paint( const Rectangle& rRect )
SetFillColor( aFillCol );
}
- long nStdAscent = aMetric.GetAscent();
+ long nStdAscent = pImpl->nAscent;
nY += nStdAscent;
if(pImpl->bTwoLines)
{
SvxFont aSmallFont(aFont);
- aSmallFont.SetHeight(aSmallFont.GetHeight() * 60 / 100);
+ Size aSize( aSmallFont.GetSize() );
+ aSize.Height() = ( aSize.Height() * 3 ) / 5;
+ aSize.Width() = ( aSize.Width() * 3 ) / 5;
+ aSmallFont.SetSize( aSize );
+ aSize = pImpl->aCJKFont.GetSize();
+ {
+ Size aTmpSize;
+ aTmpSize.Height() = ( aSize.Height() * 3 ) / 5;
+ aTmpSize.Width() = ( aSize.Width() * 3 ) / 5;
+ pImpl->aCJKFont.SetSize( aTmpSize );
+ }
long nStartBracketWidth = 0;
long nEndBracketWidth = 0;
@@ -304,7 +553,7 @@ void SvxFontPrevWindow::Paint( const Rectangle& rRect )
String sBracket(pImpl->cEndBracket);
nEndBracketWidth = aFont.GetTxtSize( pPrinter, sBracket ).Width();
}
- nTextWidth = aSmallFont.GetTxtSize( pPrinter, pImpl->aText ).Width();
+ nTextWidth = pImpl->CalcTextSize( this, pPrinter, aSmallFont ).Width();
long nResultWidth = nStartBracketWidth;
nResultWidth += nEndBracketWidth;
nResultWidth += nTextWidth;
@@ -313,9 +562,7 @@ void SvxFontPrevWindow::Paint( const Rectangle& rRect )
DrawLine( Point( 0, nY ), Point( nX, nY ) );
DrawLine( Point( nX + nResultWidth, nY ), Point( aLogSize.Width(), nY ) );
- Window::SetFont(aSmallFont);
- FontMetric aSmallMetric(GetFontMetric());
- long nSmallAscent = aSmallMetric.GetAscent();
+ long nSmallAscent = pImpl->nAscent;
long nOffset = (nStdAscent - nSmallAscent ) / 2;
if(pImpl->cStartBracket)
@@ -325,24 +572,22 @@ void SvxFontPrevWindow::Paint( const Rectangle& rRect )
nX += nStartBracketWidth;
}
- Window::SetFont(aFont);
-
- aSmallFont.DrawPrev( this, pPrinter, Point( nX, nY - nSmallAscent - 2 ), pImpl->aText );
- aSmallFont.DrawPrev( this, pPrinter, Point( nX, nY ), pImpl->aText );
+ pImpl->DrawPrev( this, pPrinter, Point( nX, nY - nSmallAscent - 2 ), aSmallFont );
+ pImpl->DrawPrev( this, pPrinter, Point( nX, nY ), aSmallFont );
nX += nTextWidth;
- Window::SetFont(aFont);
if(pImpl->cEndBracket)
{
String sBracket(pImpl->cEndBracket);
aFont.DrawPrev( this, pPrinter, Point( nX + 1, nY - nOffset - 4), sBracket );
}
+ pImpl->aCJKFont.SetSize( aSize );
}
else
{
DrawLine( Point( 0, nY ), Point( nX, nY ) );
DrawLine( Point( nX + aTxtSize.Width(), nY ), Point( aLogSize.Width(), nY ) );
- aFont.DrawPrev( this, pPrinter, Point( nX, nY ), pImpl->aText );
+ pImpl->DrawPrev( this, pPrinter, Point( nX, nY ), aFont );
}
}
/* -----------------------------04.12.00 16:26--------------------------------