1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_svx.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir // include --------------------------------------------------------------- 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include <stdio.h> 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #define _SVX_CHARMAP_CXX_ 36*cdf0e10cSrcweir #include <vcl/svapp.hxx> 37*cdf0e10cSrcweir #include <svtools/colorcfg.hxx> 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #include <rtl/textenc.h> 40*cdf0e10cSrcweir #include <svx/ucsubset.hxx> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <svx/dialogs.hrc> 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir #include <svx/charmap.hxx> 45*cdf0e10cSrcweir #include <svx/dialmgr.hxx> 46*cdf0e10cSrcweir #include <svx/svxdlg.hxx> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir #include "charmapacc.hxx" 49*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventObject.hpp> 50*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp> 51*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp> 52*cdf0e10cSrcweir #include <comphelper/types.hxx> 53*cdf0e10cSrcweir #include <svl/itemset.hxx> 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir using namespace ::com::sun::star::accessibility; 58*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 59*cdf0e10cSrcweir using namespace ::com::sun::star; 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir // ----------------------------------------------------------------------- 62*cdf0e10cSrcweir sal_uInt32& SvxShowCharSet::getSelectedChar() 63*cdf0e10cSrcweir { 64*cdf0e10cSrcweir static sal_uInt32 cSelectedChar = ' '; // keeps selected character over app livetime 65*cdf0e10cSrcweir return cSelectedChar; 66*cdf0e10cSrcweir } 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir // class SvxShowCharSet ================================================== 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir #define SBWIDTH 16 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir SvxShowCharSet::SvxShowCharSet( Window* pParent, const ResId& rResId ) : 73*cdf0e10cSrcweir Control( pParent, rResId ) 74*cdf0e10cSrcweir ,m_pAccessible(NULL) 75*cdf0e10cSrcweir ,aVscrollSB( this, WB_VERT) 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir nSelectedIndex = -1; // TODO: move into init list when it is no longer static 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir aOrigSize = GetOutputSizePixel(); 80*cdf0e10cSrcweir aOrigPos = GetPosPixel(); 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir SetStyle( GetStyle() | WB_CLIPCHILDREN ); 83*cdf0e10cSrcweir aVscrollSB.SetScrollHdl( LINK( this, SvxShowCharSet, VscrollHdl ) ); 84*cdf0e10cSrcweir aVscrollSB.EnableDrag( sal_True ); 85*cdf0e10cSrcweir // other settings like aVscroll depend on selected font => see SetFont 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir bDrag = sal_False; 88*cdf0e10cSrcweir InitSettings( sal_True, sal_True ); 89*cdf0e10cSrcweir } 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir // ----------------------------------------------------------------------- 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir void SvxShowCharSet::GetFocus() 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir Control::GetFocus(); 96*cdf0e10cSrcweir SelectIndex( nSelectedIndex, sal_True ); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir // ----------------------------------------------------------------------- 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir void SvxShowCharSet::LoseFocus() 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir Control::LoseFocus(); 104*cdf0e10cSrcweir SelectIndex( nSelectedIndex, sal_False ); 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir // ----------------------------------------------------------------------- 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir void SvxShowCharSet::StateChanged( StateChangedType nType ) 110*cdf0e10cSrcweir { 111*cdf0e10cSrcweir if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 112*cdf0e10cSrcweir InitSettings( sal_True, sal_False ); 113*cdf0e10cSrcweir else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 114*cdf0e10cSrcweir InitSettings( sal_False, sal_True ); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir Control::StateChanged( nType ); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir // ----------------------------------------------------------------------- 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir void SvxShowCharSet::DataChanged( const DataChangedEvent& rDCEvt ) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir if ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) 124*cdf0e10cSrcweir && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) ) 125*cdf0e10cSrcweir InitSettings( sal_True, sal_True ); 126*cdf0e10cSrcweir else 127*cdf0e10cSrcweir Control::DataChanged( rDCEvt ); 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir // ----------------------------------------------------------------------- 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir void SvxShowCharSet::MouseButtonDown( const MouseEvent& rMEvt ) 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir if ( rMEvt.IsLeft() ) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir if ( rMEvt.GetClicks() == 1 ) 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir GrabFocus(); 139*cdf0e10cSrcweir bDrag = sal_True; 140*cdf0e10cSrcweir CaptureMouse(); 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir int nIndex = PixelToMapIndex( rMEvt.GetPosPixel() ); 143*cdf0e10cSrcweir SelectIndex( nIndex ); 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir if ( !(rMEvt.GetClicks() % 2) ) 147*cdf0e10cSrcweir aDoubleClkHdl.Call( this ); 148*cdf0e10cSrcweir } 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir // ----------------------------------------------------------------------- 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir void SvxShowCharSet::MouseButtonUp( const MouseEvent& rMEvt ) 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir if ( bDrag && rMEvt.IsLeft() ) 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir // released mouse over character map 158*cdf0e10cSrcweir if ( Rectangle(Point(), GetOutputSize()).IsInside(rMEvt.GetPosPixel())) 159*cdf0e10cSrcweir aSelectHdl.Call( this ); 160*cdf0e10cSrcweir ReleaseMouse(); 161*cdf0e10cSrcweir bDrag = sal_False; 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir // ----------------------------------------------------------------------- 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir void SvxShowCharSet::MouseMove( const MouseEvent& rMEvt ) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir if ( rMEvt.IsLeft() && bDrag ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir Point aPos = rMEvt.GetPosPixel(); 172*cdf0e10cSrcweir Size aSize = GetSizePixel(); 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir if ( aPos.X() < 0 ) 175*cdf0e10cSrcweir aPos.X() = 0; 176*cdf0e10cSrcweir else if ( aPos.X() > aSize.Width()-5 ) 177*cdf0e10cSrcweir aPos.X() = aSize.Width()-5; 178*cdf0e10cSrcweir if ( aPos.Y() < 0 ) 179*cdf0e10cSrcweir aPos.Y() = 0; 180*cdf0e10cSrcweir else if ( aPos.Y() > aSize.Height()-5 ) 181*cdf0e10cSrcweir aPos.Y() = aSize.Height()-5; 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir int nIndex = PixelToMapIndex( aPos ); 184*cdf0e10cSrcweir SelectIndex( nIndex ); 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir // ----------------------------------------------------------------------- 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir void SvxShowCharSet::Command( const CommandEvent& rCEvt ) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir if( !HandleScrollCommand( rCEvt, 0, &aVscrollSB ) ) 193*cdf0e10cSrcweir Control::Command( rCEvt ); 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir sal_uInt16 SvxShowCharSet::GetRowPos(sal_uInt16 _nPos) const 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir return _nPos / COLUMN_COUNT ; 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir sal_uInt16 SvxShowCharSet::GetColumnPos(sal_uInt16 _nPos) const 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir return _nPos % COLUMN_COUNT ; 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir // ----------------------------------------------------------------------- 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir int SvxShowCharSet::FirstInView( void ) const 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir int nIndex = 0; 215*cdf0e10cSrcweir if( aVscrollSB.IsVisible() ) 216*cdf0e10cSrcweir nIndex += aVscrollSB.GetThumbPos() * COLUMN_COUNT; 217*cdf0e10cSrcweir return nIndex; 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir // ----------------------------------------------------------------------- 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir int SvxShowCharSet::LastInView( void ) const 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir sal_uIntPtr nIndex = FirstInView(); 225*cdf0e10cSrcweir nIndex += ROW_COUNT * COLUMN_COUNT - 1; 226*cdf0e10cSrcweir sal_uIntPtr nCompare = sal::static_int_cast<sal_uIntPtr>( maFontCharMap.GetCharCount() - 1 ); 227*cdf0e10cSrcweir if( nIndex > nCompare ) 228*cdf0e10cSrcweir nIndex = nCompare; 229*cdf0e10cSrcweir return nIndex; 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir // ----------------------------------------------------------------------- 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir inline Point SvxShowCharSet::MapIndexToPixel( int nIndex ) const 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir const int nBase = FirstInView(); 237*cdf0e10cSrcweir int x = ((nIndex - nBase) % COLUMN_COUNT) * nX; 238*cdf0e10cSrcweir int y = ((nIndex - nBase) / COLUMN_COUNT) * nY; 239*cdf0e10cSrcweir return Point( x, y ); 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir int SvxShowCharSet::PixelToMapIndex( const Point& point) const 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir int nBase = FirstInView(); 246*cdf0e10cSrcweir return (nBase + (point.X()/nX) + (point.Y()/nY) * COLUMN_COUNT); 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir // ----------------------------------------------------------------------- 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir void SvxShowCharSet::KeyInput( const KeyEvent& rKEvt ) 252*cdf0e10cSrcweir { 253*cdf0e10cSrcweir KeyCode aCode = rKEvt.GetKeyCode(); 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir if( aCode.GetModifier() ) 256*cdf0e10cSrcweir { 257*cdf0e10cSrcweir Control::KeyInput( rKEvt ); 258*cdf0e10cSrcweir return; 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir int tmpSelected = nSelectedIndex; 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir switch ( aCode.GetCode() ) 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir case KEY_SPACE: 266*cdf0e10cSrcweir aSelectHdl.Call( this ); 267*cdf0e10cSrcweir break; 268*cdf0e10cSrcweir case KEY_LEFT: 269*cdf0e10cSrcweir --tmpSelected; 270*cdf0e10cSrcweir break; 271*cdf0e10cSrcweir case KEY_RIGHT: 272*cdf0e10cSrcweir ++tmpSelected; 273*cdf0e10cSrcweir break; 274*cdf0e10cSrcweir case KEY_UP: 275*cdf0e10cSrcweir tmpSelected -= COLUMN_COUNT; 276*cdf0e10cSrcweir break; 277*cdf0e10cSrcweir case KEY_DOWN: 278*cdf0e10cSrcweir tmpSelected += COLUMN_COUNT; 279*cdf0e10cSrcweir break; 280*cdf0e10cSrcweir case KEY_PAGEUP: 281*cdf0e10cSrcweir tmpSelected -= ROW_COUNT * COLUMN_COUNT; 282*cdf0e10cSrcweir break; 283*cdf0e10cSrcweir case KEY_PAGEDOWN: 284*cdf0e10cSrcweir tmpSelected += ROW_COUNT * COLUMN_COUNT; 285*cdf0e10cSrcweir break; 286*cdf0e10cSrcweir case KEY_HOME: 287*cdf0e10cSrcweir tmpSelected = 0; 288*cdf0e10cSrcweir break; 289*cdf0e10cSrcweir case KEY_END: 290*cdf0e10cSrcweir tmpSelected = maFontCharMap.GetCharCount() - 1; 291*cdf0e10cSrcweir break; 292*cdf0e10cSrcweir case KEY_TAB: // some fonts have a character at these unicode control codes 293*cdf0e10cSrcweir case KEY_ESCAPE: 294*cdf0e10cSrcweir case KEY_RETURN: 295*cdf0e10cSrcweir Control::KeyInput( rKEvt ); 296*cdf0e10cSrcweir tmpSelected = - 1; // mark as invalid 297*cdf0e10cSrcweir break; 298*cdf0e10cSrcweir default: 299*cdf0e10cSrcweir { 300*cdf0e10cSrcweir sal_UCS4 cChar = rKEvt.GetCharCode(); 301*cdf0e10cSrcweir sal_UCS4 cNext = maFontCharMap.GetNextChar( cChar - 1 ); 302*cdf0e10cSrcweir tmpSelected = maFontCharMap.GetIndexFromChar( cNext ); 303*cdf0e10cSrcweir if( tmpSelected < 0 || (cChar != cNext) ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir Control::KeyInput( rKEvt ); 306*cdf0e10cSrcweir tmpSelected = - 1; // mark as invalid 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir } 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir if ( tmpSelected >= 0 ) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir SelectIndex( tmpSelected, sal_True ); 314*cdf0e10cSrcweir aPreSelectHdl.Call( this ); 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir } 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir // ----------------------------------------------------------------------- 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir void SvxShowCharSet::Paint( const Rectangle& ) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir DrawChars_Impl( FirstInView(), LastInView() ); 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 325*cdf0e10cSrcweir void SvxShowCharSet::DeSelect() 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir DrawChars_Impl(nSelectedIndex,nSelectedIndex); 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir // ----------------------------------------------------------------------- 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir void SvxShowCharSet::DrawChars_Impl( int n1, int n2 ) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir if( n1 > LastInView() || n2 < FirstInView() ) 334*cdf0e10cSrcweir return; 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir Size aOutputSize = GetOutputSizePixel(); 337*cdf0e10cSrcweir if( aVscrollSB.IsVisible() ) 338*cdf0e10cSrcweir aOutputSize.setWidth( aOutputSize.Width() - SBWIDTH ); 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir int i; 341*cdf0e10cSrcweir for ( i = 1; i < COLUMN_COUNT; ++i ) 342*cdf0e10cSrcweir DrawLine( Point( nX * i, 0 ), Point( nX * i, aOutputSize.Height() ) ); 343*cdf0e10cSrcweir for ( i = 1; i < ROW_COUNT; ++i ) 344*cdf0e10cSrcweir DrawLine( Point( 0, nY * i ), Point( aOutputSize.Width(), nY * i ) ); 345*cdf0e10cSrcweir 346*cdf0e10cSrcweir const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 347*cdf0e10cSrcweir const Color aWindowTextColor( rStyleSettings.GetFieldTextColor() ); 348*cdf0e10cSrcweir Color aHighlightColor( rStyleSettings.GetHighlightColor() ); 349*cdf0e10cSrcweir Color aHighlightTextColor( rStyleSettings.GetHighlightTextColor() ); 350*cdf0e10cSrcweir Color aFaceColor( rStyleSettings.GetFaceColor() ); 351*cdf0e10cSrcweir Color aLightColor( rStyleSettings.GetLightColor() ); 352*cdf0e10cSrcweir Color aShadowColor( rStyleSettings.GetShadowColor() ); 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir int nTextHeight = GetTextHeight(); 355*cdf0e10cSrcweir Rectangle aBoundRect; 356*cdf0e10cSrcweir for( i = n1; i <= n2; ++i ) 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir Point pix = MapIndexToPixel( i ); 359*cdf0e10cSrcweir int x = pix.X(); 360*cdf0e10cSrcweir int y = pix.Y(); 361*cdf0e10cSrcweir 362*cdf0e10cSrcweir rtl::OUStringBuffer buf; 363*cdf0e10cSrcweir buf.appendUtf32( maFontCharMap.GetCharFromIndex( i ) ); 364*cdf0e10cSrcweir String aCharStr(buf.makeStringAndClear()); 365*cdf0e10cSrcweir int nTextWidth = GetTextWidth(aCharStr); 366*cdf0e10cSrcweir int tx = x + (nX - nTextWidth + 1) / 2; 367*cdf0e10cSrcweir int ty = y + (nY - nTextHeight + 1) / 2; 368*cdf0e10cSrcweir Point aPointTxTy( tx, ty ); 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir // adjust position before it gets out of bounds 371*cdf0e10cSrcweir if( GetTextBoundRect( aBoundRect, aCharStr ) && !aBoundRect.IsEmpty() ) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir // zero advance width => use ink width to center glyph 374*cdf0e10cSrcweir if( !nTextWidth ) 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir aPointTxTy.X() = x - aBoundRect.Left() 377*cdf0e10cSrcweir + (nX - aBoundRect.GetWidth() + 1) / 2; 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir aBoundRect += aPointTxTy; 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir // shift back vertically if needed 383*cdf0e10cSrcweir int nYLDelta = aBoundRect.Top() - y; 384*cdf0e10cSrcweir int nYHDelta = (y + nY) - aBoundRect.Bottom(); 385*cdf0e10cSrcweir if( nYLDelta <= 0 ) 386*cdf0e10cSrcweir aPointTxTy.Y() -= nYLDelta - 1; 387*cdf0e10cSrcweir else if( nYHDelta <= 0 ) 388*cdf0e10cSrcweir aPointTxTy.Y() += nYHDelta - 1; 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir // shift back horizontally if needed 391*cdf0e10cSrcweir int nXLDelta = aBoundRect.Left() - x; 392*cdf0e10cSrcweir int nXHDelta = (x + nX) - aBoundRect.Right(); 393*cdf0e10cSrcweir if( nXLDelta <= 0 ) 394*cdf0e10cSrcweir aPointTxTy.X() -= nXLDelta - 1; 395*cdf0e10cSrcweir else if( nXHDelta <= 0 ) 396*cdf0e10cSrcweir aPointTxTy.X() += nXHDelta - 1; 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir Color aTextCol = GetTextColor(); 400*cdf0e10cSrcweir if ( i != nSelectedIndex ) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir SetTextColor( aWindowTextColor ); 403*cdf0e10cSrcweir DrawText( aPointTxTy, aCharStr ); 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir else 406*cdf0e10cSrcweir { 407*cdf0e10cSrcweir Color aLineCol = GetLineColor(); 408*cdf0e10cSrcweir Color aFillCol = GetFillColor(); 409*cdf0e10cSrcweir SetLineColor(); 410*cdf0e10cSrcweir Point aPointUL( x + 1, y + 1 ); 411*cdf0e10cSrcweir if( HasFocus() ) 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir SetFillColor( aHighlightColor ); 414*cdf0e10cSrcweir DrawRect( Rectangle( aPointUL, Size(nX-1,nY-1) ) ); 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir SetTextColor( aHighlightTextColor ); 417*cdf0e10cSrcweir DrawText( aPointTxTy, aCharStr ); 418*cdf0e10cSrcweir } 419*cdf0e10cSrcweir else 420*cdf0e10cSrcweir { 421*cdf0e10cSrcweir SetFillColor( aFaceColor ); 422*cdf0e10cSrcweir DrawRect( Rectangle( aPointUL, Size( nX-1, nY-1) ) ); 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir SetLineColor( aLightColor ); 425*cdf0e10cSrcweir DrawLine( aPointUL, Point( x+nX-1, y+1) ); 426*cdf0e10cSrcweir DrawLine( aPointUL, Point( x+1, y+nY-1) ); 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir SetLineColor( aShadowColor ); 429*cdf0e10cSrcweir DrawLine( Point( x+1, y+nY-1), Point( x+nX-1, y+nY-1) ); 430*cdf0e10cSrcweir DrawLine( Point( x+nX-1, y+nY-1), Point( x+nX-1, y+1) ); 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir DrawText( aPointTxTy, aCharStr ); 433*cdf0e10cSrcweir } 434*cdf0e10cSrcweir SetLineColor( aLineCol ); 435*cdf0e10cSrcweir SetFillColor( aFillCol ); 436*cdf0e10cSrcweir } 437*cdf0e10cSrcweir SetTextColor( aTextCol ); 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir // ----------------------------------------------------------------------- 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir void SvxShowCharSet::InitSettings( sal_Bool bForeground, sal_Bool bBackground ) 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir if ( bForeground ) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir Color aTextColor( rStyleSettings.GetDialogTextColor() ); 450*cdf0e10cSrcweir 451*cdf0e10cSrcweir if ( IsControlForeground() ) 452*cdf0e10cSrcweir aTextColor = GetControlForeground(); 453*cdf0e10cSrcweir SetTextColor( aTextColor ); 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir if ( bBackground ) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir if ( IsControlBackground() ) 459*cdf0e10cSrcweir SetBackground( GetControlBackground() ); 460*cdf0e10cSrcweir else 461*cdf0e10cSrcweir SetBackground( rStyleSettings.GetWindowColor() ); 462*cdf0e10cSrcweir } 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir Invalidate(); 465*cdf0e10cSrcweir } 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir // ----------------------------------------------------------------------- 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir sal_UCS4 SvxShowCharSet::GetSelectCharacter() const 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir if( nSelectedIndex >= 0 ) 472*cdf0e10cSrcweir getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex ); 473*cdf0e10cSrcweir return getSelectedChar(); 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir // ----------------------------------------------------------------------- 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir void SvxShowCharSet::SetFont( const Font& rFont ) 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir // save last selected unicode 481*cdf0e10cSrcweir if( nSelectedIndex >= 0 ) 482*cdf0e10cSrcweir getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex ); 483*cdf0e10cSrcweir 484*cdf0e10cSrcweir Font aFont = rFont; 485*cdf0e10cSrcweir aFont.SetWeight( WEIGHT_LIGHT ); 486*cdf0e10cSrcweir aFont.SetAlign( ALIGN_TOP ); 487*cdf0e10cSrcweir int nFontHeight = (aOrigSize.Height() - 5) * 2 / (3 * ROW_COUNT); 488*cdf0e10cSrcweir aFont.SetSize( PixelToLogic( Size( 0, nFontHeight ) ) ); 489*cdf0e10cSrcweir aFont.SetTransparent( sal_True ); 490*cdf0e10cSrcweir Control::SetFont( aFont ); 491*cdf0e10cSrcweir GetFontCharMap( maFontCharMap ); 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir // hide scrollbar when there is nothing to scroll 494*cdf0e10cSrcweir sal_Bool bNeedVscroll = (maFontCharMap.GetCharCount() > ROW_COUNT*COLUMN_COUNT); 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir nX = (aOrigSize.Width() - (bNeedVscroll ? SBWIDTH : 0)) / COLUMN_COUNT; 497*cdf0e10cSrcweir nY = aOrigSize.Height() / ROW_COUNT; 498*cdf0e10cSrcweir 499*cdf0e10cSrcweir if( bNeedVscroll) 500*cdf0e10cSrcweir { 501*cdf0e10cSrcweir aVscrollSB.SetPosSizePixel( nX * COLUMN_COUNT, 0, SBWIDTH, nY * ROW_COUNT ); 502*cdf0e10cSrcweir aVscrollSB.SetRangeMin( 0 ); 503*cdf0e10cSrcweir int nLastRow = (maFontCharMap.GetCharCount() - 1 + COLUMN_COUNT) / COLUMN_COUNT; 504*cdf0e10cSrcweir aVscrollSB.SetRangeMax( nLastRow ); 505*cdf0e10cSrcweir aVscrollSB.SetPageSize( ROW_COUNT-1 ); 506*cdf0e10cSrcweir aVscrollSB.SetVisibleSize( ROW_COUNT ); 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir // restore last selected unicode 510*cdf0e10cSrcweir int nMapIndex = maFontCharMap.GetIndexFromChar( getSelectedChar() ); 511*cdf0e10cSrcweir SelectIndex( nMapIndex ); 512*cdf0e10cSrcweir 513*cdf0e10cSrcweir // rearrange CharSet element in sync with nX- and nY-multiples 514*cdf0e10cSrcweir Size aNewSize( nX * COLUMN_COUNT + (bNeedVscroll ? SBWIDTH : 0), nY * ROW_COUNT ); 515*cdf0e10cSrcweir Point aNewPos = aOrigPos + Point( (aOrigSize.Width() - aNewSize.Width()) / 2, 0 ); 516*cdf0e10cSrcweir SetPosPixel( aNewPos ); 517*cdf0e10cSrcweir SetOutputSizePixel( aNewSize ); 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir aVscrollSB.Show( bNeedVscroll ); 520*cdf0e10cSrcweir Invalidate(); 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir // ----------------------------------------------------------------------- 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir void SvxShowCharSet::SelectIndex( int nNewIndex, sal_Bool bFocus ) 526*cdf0e10cSrcweir { 527*cdf0e10cSrcweir if( nNewIndex < 0 ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir // need to scroll see closest unicode 530*cdf0e10cSrcweir sal_uInt32 cPrev = maFontCharMap.GetPrevChar( getSelectedChar() ); 531*cdf0e10cSrcweir int nMapIndex = maFontCharMap.GetIndexFromChar( cPrev ); 532*cdf0e10cSrcweir int nNewPos = nMapIndex / COLUMN_COUNT; 533*cdf0e10cSrcweir aVscrollSB.SetThumbPos( nNewPos ); 534*cdf0e10cSrcweir nSelectedIndex = bFocus ? nMapIndex+1 : -1; 535*cdf0e10cSrcweir Invalidate(); 536*cdf0e10cSrcweir Update(); 537*cdf0e10cSrcweir } 538*cdf0e10cSrcweir else if( nNewIndex < FirstInView() ) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir // need to scroll up to see selected item 541*cdf0e10cSrcweir int nOldPos = aVscrollSB.GetThumbPos(); 542*cdf0e10cSrcweir int nDelta = (FirstInView() - nNewIndex + COLUMN_COUNT-1) / COLUMN_COUNT; 543*cdf0e10cSrcweir aVscrollSB.SetThumbPos( nOldPos - nDelta ); 544*cdf0e10cSrcweir nSelectedIndex = nNewIndex; 545*cdf0e10cSrcweir Invalidate(); 546*cdf0e10cSrcweir if( nDelta ) 547*cdf0e10cSrcweir Update(); 548*cdf0e10cSrcweir } 549*cdf0e10cSrcweir else if( nNewIndex > LastInView() ) 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir // need to scroll down to see selected item 552*cdf0e10cSrcweir int nOldPos = aVscrollSB.GetThumbPos(); 553*cdf0e10cSrcweir int nDelta = (nNewIndex - LastInView() + COLUMN_COUNT) / COLUMN_COUNT; 554*cdf0e10cSrcweir aVscrollSB.SetThumbPos( nOldPos + nDelta ); 555*cdf0e10cSrcweir if( nNewIndex < maFontCharMap.GetCharCount() ) 556*cdf0e10cSrcweir { 557*cdf0e10cSrcweir nSelectedIndex = nNewIndex; 558*cdf0e10cSrcweir Invalidate(); 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir if( nOldPos != aVscrollSB.GetThumbPos() ) 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir Invalidate(); 563*cdf0e10cSrcweir Update(); 564*cdf0e10cSrcweir } 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir else 567*cdf0e10cSrcweir { 568*cdf0e10cSrcweir // remove highlighted view 569*cdf0e10cSrcweir Color aLineCol = GetLineColor(); 570*cdf0e10cSrcweir Color aFillCol = GetFillColor(); 571*cdf0e10cSrcweir SetLineColor(); 572*cdf0e10cSrcweir SetFillColor( GetBackground().GetColor() ); 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir Point aOldPixel = MapIndexToPixel( nSelectedIndex ); 575*cdf0e10cSrcweir aOldPixel.Move( +1, +1); 576*cdf0e10cSrcweir DrawRect( Rectangle( aOldPixel, Size( nX-1, nY-1 ) ) ); 577*cdf0e10cSrcweir SetLineColor( aLineCol ); 578*cdf0e10cSrcweir SetFillColor( aFillCol ); 579*cdf0e10cSrcweir 580*cdf0e10cSrcweir int nOldIndex = nSelectedIndex; 581*cdf0e10cSrcweir nSelectedIndex = nNewIndex; 582*cdf0e10cSrcweir DrawChars_Impl( nOldIndex, nOldIndex ); 583*cdf0e10cSrcweir DrawChars_Impl( nNewIndex, nNewIndex ); 584*cdf0e10cSrcweir } 585*cdf0e10cSrcweir 586*cdf0e10cSrcweir if( nSelectedIndex >= 0 ) 587*cdf0e10cSrcweir { 588*cdf0e10cSrcweir getSelectedChar() = maFontCharMap.GetCharFromIndex( nSelectedIndex ); 589*cdf0e10cSrcweir if( m_pAccessible ) 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir ::svx::SvxShowCharSetItem* pItem = ImplGetItem(nSelectedIndex); 592*cdf0e10cSrcweir m_pAccessible->fireEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), makeAny(pItem->GetAccessible()) ); // this call asures that m_pItem is set 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir OSL_ENSURE(pItem->m_pItem,"No accessible created!"); 595*cdf0e10cSrcweir Any aOldAny, aNewAny; 596*cdf0e10cSrcweir aNewAny <<= AccessibleStateType::FOCUSED; 597*cdf0e10cSrcweir pItem->m_pItem->fireEvent( AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny ); 598*cdf0e10cSrcweir 599*cdf0e10cSrcweir aNewAny <<= AccessibleStateType::SELECTED; 600*cdf0e10cSrcweir pItem->m_pItem->fireEvent( AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny ); 601*cdf0e10cSrcweir } 602*cdf0e10cSrcweir } 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir aHighHdl.Call( this ); 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir // ----------------------------------------------------------------------- 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir void SvxShowCharSet::SelectCharacter( sal_UCS4 cNew, sal_Bool bFocus ) 611*cdf0e10cSrcweir { 612*cdf0e10cSrcweir // get next available char of current font 613*cdf0e10cSrcweir sal_UCS4 cNext = maFontCharMap.GetNextChar( cNew - 1 ); 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir int nMapIndex = maFontCharMap.GetIndexFromChar( cNext ); 616*cdf0e10cSrcweir SelectIndex( nMapIndex, bFocus ); 617*cdf0e10cSrcweir if( !bFocus ) 618*cdf0e10cSrcweir { 619*cdf0e10cSrcweir // move selected item to top row if not in focus 620*cdf0e10cSrcweir aVscrollSB.SetThumbPos( nMapIndex / COLUMN_COUNT ); 621*cdf0e10cSrcweir Invalidate(); 622*cdf0e10cSrcweir } 623*cdf0e10cSrcweir } 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir // ----------------------------------------------------------------------- 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir IMPL_LINK( SvxShowCharSet, VscrollHdl, ScrollBar *, EMPTYARG ) 628*cdf0e10cSrcweir { 629*cdf0e10cSrcweir if( nSelectedIndex < FirstInView() ) 630*cdf0e10cSrcweir { 631*cdf0e10cSrcweir SelectIndex( FirstInView() + (nSelectedIndex % COLUMN_COUNT) ); 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir else if( nSelectedIndex > LastInView() ) 634*cdf0e10cSrcweir { 635*cdf0e10cSrcweir if( m_pAccessible ) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir ::com::sun::star::uno::Any aOldAny, aNewAny; 638*cdf0e10cSrcweir int nLast = LastInView(); 639*cdf0e10cSrcweir for ( ; nLast != nSelectedIndex; ++nLast) 640*cdf0e10cSrcweir { 641*cdf0e10cSrcweir aOldAny <<= ImplGetItem(nLast)->GetAccessible(); 642*cdf0e10cSrcweir m_pAccessible ->fireEvent( AccessibleEventId::CHILD, aOldAny, aNewAny ); 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir SelectIndex( (LastInView() - COLUMN_COUNT + 1) + (nSelectedIndex % COLUMN_COUNT) ); 646*cdf0e10cSrcweir } 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir Invalidate(); 649*cdf0e10cSrcweir return 0; 650*cdf0e10cSrcweir } 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir // ----------------------------------------------------------------------- 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir SvxShowCharSet::~SvxShowCharSet() 655*cdf0e10cSrcweir { 656*cdf0e10cSrcweir if ( m_pAccessible ) 657*cdf0e10cSrcweir ReleaseAccessible(); 658*cdf0e10cSrcweir } 659*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 660*cdf0e10cSrcweir void SvxShowCharSet::ReleaseAccessible() 661*cdf0e10cSrcweir { 662*cdf0e10cSrcweir m_aItems.clear(); 663*cdf0e10cSrcweir m_pAccessible = NULL; 664*cdf0e10cSrcweir m_xAccessible = NULL; 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 667*cdf0e10cSrcweir ::com::sun::star::uno::Reference< XAccessible > SvxShowCharSet::CreateAccessible() 668*cdf0e10cSrcweir { 669*cdf0e10cSrcweir OSL_ENSURE(!m_pAccessible,"Accessible already created!"); 670*cdf0e10cSrcweir m_pAccessible = new ::svx::SvxShowCharSetVirtualAcc(this); 671*cdf0e10cSrcweir m_xAccessible = m_pAccessible; 672*cdf0e10cSrcweir return m_xAccessible; 673*cdf0e10cSrcweir } 674*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 675*cdf0e10cSrcweir ::svx::SvxShowCharSetItem* SvxShowCharSet::ImplGetItem( int _nPos ) 676*cdf0e10cSrcweir { 677*cdf0e10cSrcweir ItemsMap::iterator aFind = m_aItems.find(_nPos); 678*cdf0e10cSrcweir if ( aFind == m_aItems.end() ) 679*cdf0e10cSrcweir { 680*cdf0e10cSrcweir OSL_ENSURE(m_pAccessible,"Who wants to create a child of my table without a parent?"); 681*cdf0e10cSrcweir aFind = m_aItems.insert(ItemsMap::value_type(_nPos,new ::svx::SvxShowCharSetItem(*this,m_pAccessible->getTable(),sal::static_int_cast< sal_uInt16 >(_nPos)))).first; 682*cdf0e10cSrcweir rtl::OUStringBuffer buf; 683*cdf0e10cSrcweir buf.appendUtf32( maFontCharMap.GetCharFromIndex( _nPos ) ); 684*cdf0e10cSrcweir aFind->second->maText = buf.makeStringAndClear(); 685*cdf0e10cSrcweir Point pix = MapIndexToPixel( _nPos ); 686*cdf0e10cSrcweir aFind->second->maRect = Rectangle( Point( pix.X() + 1, pix.Y() + 1 ), Size(nX-1,nY-1) ); 687*cdf0e10cSrcweir } 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir return aFind->second; 690*cdf0e10cSrcweir } 691*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 692*cdf0e10cSrcweir void SvxShowCharSet::ImplFireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ) 693*cdf0e10cSrcweir { 694*cdf0e10cSrcweir if( m_pAccessible ) 695*cdf0e10cSrcweir m_pAccessible->fireEvent( nEventId, rOldValue, rNewValue ); 696*cdf0e10cSrcweir } 697*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 698*cdf0e10cSrcweir ScrollBar* SvxShowCharSet::getScrollBar() 699*cdf0e10cSrcweir { 700*cdf0e10cSrcweir return &aVscrollSB; 701*cdf0e10cSrcweir } 702*cdf0e10cSrcweir // ----------------------------------------------------------------------- 703*cdf0e10cSrcweir sal_Int32 SvxShowCharSet::getMaxCharCount() const 704*cdf0e10cSrcweir { 705*cdf0e10cSrcweir return maFontCharMap.GetCharCount(); 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir // class SubsetMap ======================================================= 710*cdf0e10cSrcweir // TODO: should be moved into Font Attributes stuff 711*cdf0e10cSrcweir // we let it mature here though because it is currently the only use 712*cdf0e10cSrcweir 713*cdf0e10cSrcweir SubsetMap::SubsetMap( const FontCharMap* pFontCharMap ) 714*cdf0e10cSrcweir : Resource( SVX_RES(RID_SUBSETMAP) ) 715*cdf0e10cSrcweir { 716*cdf0e10cSrcweir InitList(); 717*cdf0e10cSrcweir ApplyCharMap( pFontCharMap ); 718*cdf0e10cSrcweir FreeResource(); 719*cdf0e10cSrcweir } 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir const Subset* SubsetMap::GetNextSubset( bool bFirst ) const 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir if( bFirst ) 724*cdf0e10cSrcweir maSubsetIterator = maSubsets.begin(); 725*cdf0e10cSrcweir if( maSubsetIterator == maSubsets.end() ) 726*cdf0e10cSrcweir return NULL; 727*cdf0e10cSrcweir const Subset* s = &*(maSubsetIterator++); 728*cdf0e10cSrcweir return s; 729*cdf0e10cSrcweir } 730*cdf0e10cSrcweir 731*cdf0e10cSrcweir const Subset* SubsetMap::GetSubsetByUnicode( sal_UCS4 cChar ) const 732*cdf0e10cSrcweir { 733*cdf0e10cSrcweir // TODO: is it worth to avoid a linear search? 734*cdf0e10cSrcweir for( const Subset* s = GetNextSubset( true ); s; s = GetNextSubset( false ) ) 735*cdf0e10cSrcweir if( (s->GetRangeMin() <= cChar) && (cChar <= s->GetRangeMax()) ) 736*cdf0e10cSrcweir return s; 737*cdf0e10cSrcweir return NULL; 738*cdf0e10cSrcweir } 739*cdf0e10cSrcweir 740*cdf0e10cSrcweir inline Subset::Subset( sal_UCS4 nMin, sal_UCS4 nMax, int resId) 741*cdf0e10cSrcweir : mnRangeMin(nMin), mnRangeMax(nMax), maRangeName( SVX_RES(resId) ) 742*cdf0e10cSrcweir {} 743*cdf0e10cSrcweir 744*cdf0e10cSrcweir void SubsetMap::InitList() 745*cdf0e10cSrcweir { 746*cdf0e10cSrcweir static SubsetList aAllSubsets; 747*cdf0e10cSrcweir static bool bInit = true; 748*cdf0e10cSrcweir if( bInit ) 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir bInit = false; 751*cdf0e10cSrcweir 752*cdf0e10cSrcweir // TODO: eventually merge or split unicode subranges 753*cdf0e10cSrcweir // a "native writer" should decide for his subsets 754*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0020, 0x007F, RID_SUBSETSTR_BASIC_LATIN ) ); 755*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0080, 0x00FF, RID_SUBSETSTR_LATIN_1 ) ); 756*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0100, 0x017F, RID_SUBSETSTR_LATIN_EXTENDED_A ) ); 757*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0180, 0x024F, RID_SUBSETSTR_LATIN_EXTENDED_B ) ); 758*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0250, 0x02AF, RID_SUBSETSTR_IPA_EXTENSIONS ) ); 759*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x02B0, 0x02FF, RID_SUBSETSTR_SPACING_MODIFIERS ) ); 760*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0300, 0x036F, RID_SUBSETSTR_COMB_DIACRITICAL ) ); 761*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0370, 0x03FF, RID_SUBSETSTR_BASIC_GREEK ) ); 762*cdf0e10cSrcweir // aAllSubsets.push_back( Subset( 0x03D0, 0x03F3, RID_SUBSETSTR_GREEK_SYMS_COPTIC ) ); 763*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0400, 0x04FF, RID_SUBSETSTR_CYRILLIC ) ); 764*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0530, 0x058F, RID_SUBSETSTR_ARMENIAN ) ); 765*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0590, 0x05FF, RID_SUBSETSTR_BASIC_HEBREW ) ); 766*cdf0e10cSrcweir // aAllSubsets.push_back( Subset( 0x0591, 0x05C4, RID_SUBSETSTR_HEBREW_EXTENDED ) ); 767*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0600, 0x065F, RID_SUBSETSTR_BASIC_ARABIC ) ); 768*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0660, 0x06FF, RID_SUBSETSTR_ARABIC_EXTENDED ) ); 769*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0700, 0x074F, RID_SUBSETSTR_SYRIAC ) ); 770*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0780, 0x07BF, RID_SUBSETSTR_THAANA ) ); 771*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0900, 0x097F, RID_SUBSETSTR_DEVANAGARI ) ); 772*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0980, 0x09FF, RID_SUBSETSTR_BENGALI ) ); 773*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0A00, 0x0A7F, RID_SUBSETSTR_GURMUKHI ) ); 774*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0A80, 0x0AFF, RID_SUBSETSTR_GUJARATI ) ); 775*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0B00, 0x0B7F, RID_SUBSETSTR_ORIYA ) ); 776*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0B80, 0x0BFF, RID_SUBSETSTR_TAMIL ) ); 777*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0C00, 0x0C7F, RID_SUBSETSTR_TELUGU ) ); 778*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0C80, 0x0CFF, RID_SUBSETSTR_KANNADA ) ); 779*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0D00, 0x0D7F, RID_SUBSETSTR_MALAYALAM ) ); 780*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0D80, 0x0DFF, RID_SUBSETSTR_SINHALA ) ); 781*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0E00, 0x0E7F, RID_SUBSETSTR_THAI ) ); 782*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0E80, 0x0EFF, RID_SUBSETSTR_LAO ) ); 783*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x0F00, 0x0FBF, RID_SUBSETSTR_TIBETAN ) ); 784*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1000, 0x109F, RID_SUBSETSTR_MYANMAR ) ); 785*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x10A0, 0x10FF, RID_SUBSETSTR_BASIC_GEORGIAN ) ); 786*cdf0e10cSrcweir // aAllSubsets.push_back( Subset( 0x10A0, 0x10C5, RID_SUBSETSTR_GEORGIAN_EXTENDED ) ); 787*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1100, 0x11FF, RID_SUBSETSTR_HANGUL_JAMO ) ); 788*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1200, 0x137F, RID_SUBSETSTR_ETHIOPIC ) ); 789*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x13A0, 0x13FF, RID_SUBSETSTR_CHEROKEE ) ); 790*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1400, 0x167F, RID_SUBSETSTR_CANADIAN_ABORIGINAL ) ); 791*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1680, 0x169F, RID_SUBSETSTR_OGHAM ) ); 792*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x16A0, 0x16F0, RID_SUBSETSTR_RUNIC ) ); 793*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1700, 0x171F, RID_SUBSETSTR_TAGALOG ) ); 794*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1720, 0x173F, RID_SUBSETSTR_HANUNOO ) ); 795*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1740, 0x175F, RID_SUBSETSTR_BUHID ) ); 796*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1760, 0x177F, RID_SUBSETSTR_TAGBANWA ) ); 797*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1780, 0x17FF, RID_SUBSETSTR_KHMER ) ); 798*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1800, 0x18AF, RID_SUBSETSTR_MONGOLIAN ) ); 799*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1E00, 0x1EFF, RID_SUBSETSTR_LATIN_EXTENDED_ADDS ) ); 800*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x1F00, 0x1FFF, RID_SUBSETSTR_GREEK_EXTENDED ) ); 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2000, 0x206F, RID_SUBSETSTR_GENERAL_PUNCTUATION ) ); 803*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2070, 0x209F, RID_SUBSETSTR_SUB_SUPER_SCRIPTS ) ); 804*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x20A0, 0x20CF, RID_SUBSETSTR_CURRENCY_SYMBOLS ) ); 805*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x20D0, 0x20FF, RID_SUBSETSTR_COMB_DIACRITIC_SYMS ) ); 806*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2100, 0x214F, RID_SUBSETSTR_LETTERLIKE_SYMBOLS ) ); 807*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2150, 0x218F, RID_SUBSETSTR_NUMBER_FORMS ) ); 808*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2190, 0x21FF, RID_SUBSETSTR_ARROWS ) ); 809*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2200, 0x22FF, RID_SUBSETSTR_MATH_OPERATORS ) ); 810*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2300, 0x23FF, RID_SUBSETSTR_MISC_TECHNICAL ) ); 811*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2400, 0x243F, RID_SUBSETSTR_CONTROL_PICTURES ) ); 812*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2440, 0x245F, RID_SUBSETSTR_OPTICAL_CHAR_REC ) ); 813*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2460, 0x24FF, RID_SUBSETSTR_ENCLOSED_ALPHANUM ) ); 814*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2500, 0x257F, RID_SUBSETSTR_BOX_DRAWING ) ); 815*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2580, 0x259F, RID_SUBSETSTR_BLOCK_ELEMENTS ) ); 816*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x25A0, 0x25FF, RID_SUBSETSTR_GEOMETRIC_SHAPES ) ); 817*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2600, 0x26FF, RID_SUBSETSTR_MISC_DINGBATS ) ); 818*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2700, 0x27BF, RID_SUBSETSTR_DINGBATS ) ); 819*cdf0e10cSrcweir 820*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x27C0, 0x27FF, RID_SUBSETSTR_MISC_MATH_SYMS_A ) ); 821*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x27F0, 0x27FF, RID_SUBSETSTR_SUPPL_ARROWS_A ) ); 822*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2800, 0x28FF, RID_SUBSETSTR_BRAILLE_PATTERNS ) ); 823*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2900, 0x297F, RID_SUBSETSTR_SUPPL_ARROWS_B ) ); 824*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2980, 0x29FF, RID_SUBSETSTR_MISC_MATH_SYMS_B ) ); 825*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2E80, 0x2EFF, RID_SUBSETSTR_CJK_RADICAL_SUPPL ) ); 826*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2F00, 0x2FDF, RID_SUBSETSTR_KANXI_RADICALS ) ); 827*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x2FF0, 0x2FFF, RID_SUBSETSTR_IDEO_DESC_CHARS ) ); 828*cdf0e10cSrcweir 829*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x3000, 0x303F, RID_SUBSETSTR_CJK_SYMS_PUNCTUATION ) ); 830*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x3040, 0x309F, RID_SUBSETSTR_HIRAGANA ) ); 831*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x30A0, 0x30FF, RID_SUBSETSTR_KATAKANA ) ); 832*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x3100, 0x312F, RID_SUBSETSTR_BOPOMOFO ) ); 833*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x3130, 0x318F, RID_SUBSETSTR_HANGUL_COMPAT_JAMO ) ); 834*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x3190, 0x319F, RID_SUBSETSTR_KANBUN ) ); 835*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x31A0, 0x31BF, RID_SUBSETSTR_BOPOMOFO_EXTENDED ) ); 836*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x31C0, 0x31FF, RID_SUBSETSTR_KATAKANA_PHONETIC ) ); 837*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x3200, 0x32FF, RID_SUBSETSTR_ENCLOSED_CJK_LETTERS ) ); 838*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x3300, 0x33FF, RID_SUBSETSTR_CJK_COMPATIBILITY ) ); 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x3400, 0x4DFF, RID_SUBSETSTR_CJK_EXT_A_UNIFIED_IDGRAPH ) ); 841*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0x4E00, 0x9FA5, RID_SUBSETSTR_CJK_UNIFIED_IDGRAPH ) ); 842*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xA000, 0xA4CF, RID_SUBSETSTR_YI ) ); 843*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xAC00, 0xB097, RID_SUBSETSTR_HANGUL_GA ) ); 844*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xB098, 0xB2E3, RID_SUBSETSTR_HANGUL_NA ) ); 845*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xB2E4, 0xB77B, RID_SUBSETSTR_HANGUL_DA ) ); 846*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xB77C, 0xB9C7, RID_SUBSETSTR_HANGUL_RA ) ); 847*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xB9C8, 0xBC13, RID_SUBSETSTR_HANGUL_MA ) ); 848*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xBC14, 0xC0AB, RID_SUBSETSTR_HANGUL_BA ) ); 849*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xC0AC, 0xC543, RID_SUBSETSTR_HANGUL_SA ) ); 850*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xC544, 0xC78F, RID_SUBSETSTR_HANGUL_AH ) ); 851*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xC790, 0xCC27, RID_SUBSETSTR_HANGUL_JA ) ); 852*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xCC28, 0xCE73, RID_SUBSETSTR_HANGUL_CHA ) ); 853*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xCE74, 0xD0BF, RID_SUBSETSTR_HANGUL_KA ) ); 854*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xD0C0, 0xD30B, RID_SUBSETSTR_HANGUL_TA ) ); 855*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xD30C, 0xD557, RID_SUBSETSTR_HANGUL_PA ) ); 856*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xD558, 0xD7A3, RID_SUBSETSTR_HANGUL_HA ) ); 857*cdf0e10cSrcweir // aAllSubsets.push_back( Subset( 0xAC00, 0xD7AF, RID_SUBSETSTR_HANGUL ) ); 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir // aAllSubsets.push_back( Subset( 0xD800, 0xDFFF, RID_SUBSETSTR_SURROGATE ) ); 860*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xE000, 0xF8FF, RID_SUBSETSTR_PRIVATE_USE_AREA ) ); 861*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xF900, 0xFAFF, RID_SUBSETSTR_CJK_COMPAT_IDGRAPHS ) ); 862*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xFB00, 0xFB4F, RID_SUBSETSTR_ALPHA_PRESENTATION ) ); 863*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xFB50, 0xFDFF, RID_SUBSETSTR_ARABIC_PRESENT_A ) ); 864*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xFE20, 0xFE2F, RID_SUBSETSTR_COMBINING_HALF_MARKS ) ); 865*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xFE30, 0xFE4F, RID_SUBSETSTR_CJK_COMPAT_FORMS ) ); 866*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xFE50, 0xFE6F, RID_SUBSETSTR_SMALL_FORM_VARIANTS ) ); 867*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xFE70, 0xFEFF, RID_SUBSETSTR_ARABIC_PRESENT_B ) ); 868*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xFF00, 0xFFEF, RID_SUBSETSTR_HALFW_FULLW_FORMS ) ); 869*cdf0e10cSrcweir aAllSubsets.push_back( Subset( 0xFFF0, 0xFFFF, RID_SUBSETSTR_SPECIALS ) ); 870*cdf0e10cSrcweir } 871*cdf0e10cSrcweir 872*cdf0e10cSrcweir maSubsets = aAllSubsets; 873*cdf0e10cSrcweir } 874*cdf0e10cSrcweir 875*cdf0e10cSrcweir void SubsetMap::ApplyCharMap( const FontCharMap* pFontCharMap ) 876*cdf0e10cSrcweir { 877*cdf0e10cSrcweir if( !pFontCharMap ) 878*cdf0e10cSrcweir return; 879*cdf0e10cSrcweir 880*cdf0e10cSrcweir // remove subsets that are not matched in any range 881*cdf0e10cSrcweir SubsetList::iterator it_next = maSubsets.begin(); 882*cdf0e10cSrcweir while( it_next != maSubsets.end() ) 883*cdf0e10cSrcweir { 884*cdf0e10cSrcweir SubsetList::iterator it = it_next++; 885*cdf0e10cSrcweir const Subset& rSubset = *it; 886*cdf0e10cSrcweir sal_uInt32 cMin = rSubset.GetRangeMin(); 887*cdf0e10cSrcweir sal_uInt32 cMax = rSubset.GetRangeMax(); 888*cdf0e10cSrcweir 889*cdf0e10cSrcweir int nCount = pFontCharMap->CountCharsInRange( cMin, cMax ); 890*cdf0e10cSrcweir if( nCount <= 0 ) 891*cdf0e10cSrcweir maSubsets.erase( it ); 892*cdf0e10cSrcweir } 893*cdf0e10cSrcweir } 894