1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: charmap.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 // include ---------------------------------------------------------------
38 #define _SVX_CHARMAP_CXX_
39 #include <vcl/svapp.hxx>
40 #include <svtools/colorcfg.hxx>
42 #include <rtl/textenc.h>
43 #include <svx/ucsubset.hxx>
45 #include <svx/dialogs.hrc>
47 #include <svx/charmap.hxx>
48 #include <svx/dialmgr.hxx>
49 #include <svx/svxdlg.hxx>
51 #include "charmapacc.hxx"
52 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
53 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
54 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
55 #include <comphelper/types.hxx>
56 #include <svtools/itemset.hxx>
58 #include "rtl/ustrbuf.hxx"
60 using namespace ::com::sun::star::accessibility
;
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star
;
64 // -----------------------------------------------------------------------
65 sal_uInt32
& SvxShowCharSet::getSelectedChar()
67 static sal_uInt32 cSelectedChar
= ' '; // keeps selected character over app livetime
71 // class SvxShowCharSet ==================================================
75 SvxShowCharSet::SvxShowCharSet( Window
* pParent
, const ResId
& rResId
) :
76 Control( pParent
, rResId
)
78 ,aVscrollSB( this, WB_VERT
)
80 nSelectedIndex
= -1; // TODO: move into init list when it is no longer static
82 aOrigSize
= GetOutputSizePixel();
83 aOrigPos
= GetPosPixel();
85 SetStyle( GetStyle() | WB_CLIPCHILDREN
);
86 aVscrollSB
.SetScrollHdl( LINK( this, SvxShowCharSet
, VscrollHdl
) );
87 aVscrollSB
.EnableDrag( TRUE
);
88 // other settings like aVscroll depend on selected font => see SetFont
91 InitSettings( TRUE
, TRUE
);
94 // -----------------------------------------------------------------------
96 void SvxShowCharSet::GetFocus()
99 SelectIndex( nSelectedIndex
, TRUE
);
102 // -----------------------------------------------------------------------
104 void SvxShowCharSet::LoseFocus()
106 Control::LoseFocus();
107 SelectIndex( nSelectedIndex
, FALSE
);
110 // -----------------------------------------------------------------------
112 void SvxShowCharSet::StateChanged( StateChangedType nType
)
114 if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
115 InitSettings( TRUE
, FALSE
);
116 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
117 InitSettings( FALSE
, TRUE
);
119 Control::StateChanged( nType
);
122 // -----------------------------------------------------------------------
124 void SvxShowCharSet::DataChanged( const DataChangedEvent
& rDCEvt
)
126 if ( ( rDCEvt
.GetType() == DATACHANGED_SETTINGS
)
127 && ( rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
128 InitSettings( TRUE
, TRUE
);
130 Control::DataChanged( rDCEvt
);
133 // -----------------------------------------------------------------------
135 void SvxShowCharSet::MouseButtonDown( const MouseEvent
& rMEvt
)
137 if ( rMEvt
.IsLeft() )
139 if ( rMEvt
.GetClicks() == 1 )
145 int nIndex
= PixelToMapIndex( rMEvt
.GetPosPixel() );
146 SelectIndex( nIndex
);
149 if ( !(rMEvt
.GetClicks() % 2) )
150 aDoubleClkHdl
.Call( this );
154 // -----------------------------------------------------------------------
156 void SvxShowCharSet::MouseButtonUp( const MouseEvent
& rMEvt
)
158 if ( bDrag
&& rMEvt
.IsLeft() )
160 // released mouse over character map
161 if ( Rectangle(Point(), GetOutputSize()).IsInside(rMEvt
.GetPosPixel()))
162 aSelectHdl
.Call( this );
168 // -----------------------------------------------------------------------
170 void SvxShowCharSet::MouseMove( const MouseEvent
& rMEvt
)
172 if ( rMEvt
.IsLeft() && bDrag
)
174 Point aPos
= rMEvt
.GetPosPixel();
175 Size aSize
= GetSizePixel();
179 else if ( aPos
.X() > aSize
.Width()-5 )
180 aPos
.X() = aSize
.Width()-5;
183 else if ( aPos
.Y() > aSize
.Height()-5 )
184 aPos
.Y() = aSize
.Height()-5;
186 int nIndex
= PixelToMapIndex( aPos
);
187 SelectIndex( nIndex
);
191 // -----------------------------------------------------------------------
193 void SvxShowCharSet::Command( const CommandEvent
& rCEvt
)
195 if( !HandleScrollCommand( rCEvt
, 0, &aVscrollSB
) )
196 Control::Command( rCEvt
);
199 // -----------------------------------------------------------------------------
201 USHORT
SvxShowCharSet::GetRowPos(USHORT _nPos
) const
203 return _nPos
/ COLUMN_COUNT
;
206 // -----------------------------------------------------------------------------
208 USHORT
SvxShowCharSet::GetColumnPos(USHORT _nPos
) const
210 return _nPos
% COLUMN_COUNT
;
213 // -----------------------------------------------------------------------
215 int SvxShowCharSet::FirstInView( void ) const
218 if( aVscrollSB
.IsVisible() )
219 nIndex
+= aVscrollSB
.GetThumbPos() * COLUMN_COUNT
;
223 // -----------------------------------------------------------------------
225 int SvxShowCharSet::LastInView( void ) const
227 ULONG nIndex
= FirstInView();
228 nIndex
+= ROW_COUNT
* COLUMN_COUNT
- 1;
229 ULONG nCompare
= sal::static_int_cast
<ULONG
>( maFontCharMap
.GetCharCount() - 1 );
230 if( nIndex
> nCompare
)
235 // -----------------------------------------------------------------------
237 inline Point
SvxShowCharSet::MapIndexToPixel( int nIndex
) const
239 const int nBase
= FirstInView();
240 int x
= ((nIndex
- nBase
) % COLUMN_COUNT
) * nX
;
241 int y
= ((nIndex
- nBase
) / COLUMN_COUNT
) * nY
;
242 return Point( x
, y
);
244 // -----------------------------------------------------------------------------
246 int SvxShowCharSet::PixelToMapIndex( const Point
& point
) const
248 int nBase
= FirstInView();
249 return (nBase
+ (point
.X()/nX
) + (point
.Y()/nY
) * COLUMN_COUNT
);
252 // -----------------------------------------------------------------------
254 void SvxShowCharSet::KeyInput( const KeyEvent
& rKEvt
)
256 KeyCode aCode
= rKEvt
.GetKeyCode();
258 if( aCode
.GetModifier() )
260 Control::KeyInput( rKEvt
);
264 int tmpSelected
= nSelectedIndex
;
266 switch ( aCode
.GetCode() )
269 aSelectHdl
.Call( this );
278 tmpSelected
-= COLUMN_COUNT
;
281 tmpSelected
+= COLUMN_COUNT
;
284 tmpSelected
-= ROW_COUNT
* COLUMN_COUNT
;
287 tmpSelected
+= ROW_COUNT
* COLUMN_COUNT
;
293 tmpSelected
= maFontCharMap
.GetCharCount() - 1;
295 case KEY_TAB
: // some fonts have a character at these unicode control codes
298 Control::KeyInput( rKEvt
);
299 tmpSelected
= - 1; // mark as invalid
303 sal_UCS4 cChar
= rKEvt
.GetCharCode();
304 sal_UCS4 cNext
= maFontCharMap
.GetNextChar( cChar
- 1 );
305 tmpSelected
= maFontCharMap
.GetIndexFromChar( cNext
);
306 if( tmpSelected
< 0 || (cChar
!= cNext
) )
308 Control::KeyInput( rKEvt
);
309 tmpSelected
= - 1; // mark as invalid
314 if ( tmpSelected
>= 0 )
316 SelectIndex( tmpSelected
, TRUE
);
317 aPreSelectHdl
.Call( this );
321 // -----------------------------------------------------------------------
323 void SvxShowCharSet::Paint( const Rectangle
& )
325 DrawChars_Impl( FirstInView(), LastInView() );
327 // -----------------------------------------------------------------------------
328 void SvxShowCharSet::DeSelect()
330 DrawChars_Impl(nSelectedIndex
,nSelectedIndex
);
332 // -----------------------------------------------------------------------
334 void SvxShowCharSet::DrawChars_Impl( int n1
, int n2
)
336 if( n1
> LastInView() || n2
< FirstInView() )
339 Size aOutputSize
= GetOutputSizePixel();
340 if( aVscrollSB
.IsVisible() )
341 aOutputSize
.setWidth( aOutputSize
.Width() - SBWIDTH
);
344 for ( i
= 1; i
< COLUMN_COUNT
; ++i
)
345 DrawLine( Point( nX
* i
, 0 ), Point( nX
* i
, aOutputSize
.Height() ) );
346 for ( i
= 1; i
< ROW_COUNT
; ++i
)
347 DrawLine( Point( 0, nY
* i
), Point( aOutputSize
.Width(), nY
* i
) );
349 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
350 const Color
aWindowTextColor( rStyleSettings
.GetFieldTextColor() );
351 Color
aHighlightColor( rStyleSettings
.GetHighlightColor() );
352 Color
aHighlightTextColor( rStyleSettings
.GetHighlightTextColor() );
353 Color
aFaceColor( rStyleSettings
.GetFaceColor() );
354 Color
aLightColor( rStyleSettings
.GetLightColor() );
355 Color
aShadowColor( rStyleSettings
.GetShadowColor() );
357 int nTextHeight
= GetTextHeight();
358 Rectangle aBoundRect
;
359 for( i
= n1
; i
<= n2
; ++i
)
361 Point pix
= MapIndexToPixel( i
);
365 rtl::OUStringBuffer buf
;
366 buf
.appendUtf32( maFontCharMap
.GetCharFromIndex( i
) );
367 String
aCharStr(buf
.makeStringAndClear());
368 int nTextWidth
= GetTextWidth(aCharStr
);
369 int tx
= x
+ (nX
- nTextWidth
+ 1) / 2;
370 int ty
= y
+ (nY
- nTextHeight
+ 1) / 2;
371 Point
aPointTxTy( tx
, ty
);
373 // adjust position before it gets out of bounds
374 if( GetTextBoundRect( aBoundRect
, aCharStr
) && !aBoundRect
.IsEmpty() )
376 // zero advance width => use ink width to center glyph
379 aPointTxTy
.X() = x
- aBoundRect
.Left()
380 + (nX
- aBoundRect
.GetWidth() + 1) / 2;
383 aBoundRect
+= aPointTxTy
;
385 // shift back vertically if needed
386 int nYLDelta
= aBoundRect
.Top() - y
;
387 int nYHDelta
= (y
+ nY
) - aBoundRect
.Bottom();
389 aPointTxTy
.Y() -= nYLDelta
- 1;
390 else if( nYHDelta
<= 0 )
391 aPointTxTy
.Y() += nYHDelta
- 1;
393 // shift back horizontally if needed
394 int nXLDelta
= aBoundRect
.Left() - x
;
395 int nXHDelta
= (x
+ nX
) - aBoundRect
.Right();
397 aPointTxTy
.X() -= nXLDelta
- 1;
398 else if( nXHDelta
<= 0 )
399 aPointTxTy
.X() += nXHDelta
- 1;
402 Color aTextCol
= GetTextColor();
403 if ( i
!= nSelectedIndex
)
405 SetTextColor( aWindowTextColor
);
406 DrawText( aPointTxTy
, aCharStr
);
410 Color aLineCol
= GetLineColor();
411 Color aFillCol
= GetFillColor();
413 Point
aPointUL( x
+ 1, y
+ 1 );
416 SetFillColor( aHighlightColor
);
417 DrawRect( Rectangle( aPointUL
, Size(nX
-1,nY
-1) ) );
419 SetTextColor( aHighlightTextColor
);
420 DrawText( aPointTxTy
, aCharStr
);
424 SetFillColor( aFaceColor
);
425 DrawRect( Rectangle( aPointUL
, Size( nX
-1, nY
-1) ) );
427 SetLineColor( aLightColor
);
428 DrawLine( aPointUL
, Point( x
+nX
-1, y
+1) );
429 DrawLine( aPointUL
, Point( x
+1, y
+nY
-1) );
431 SetLineColor( aShadowColor
);
432 DrawLine( Point( x
+1, y
+nY
-1), Point( x
+nX
-1, y
+nY
-1) );
433 DrawLine( Point( x
+nX
-1, y
+nY
-1), Point( x
+nX
-1, y
+1) );
435 DrawText( aPointTxTy
, aCharStr
);
437 SetLineColor( aLineCol
);
438 SetFillColor( aFillCol
);
440 SetTextColor( aTextCol
);
444 // -----------------------------------------------------------------------
446 void SvxShowCharSet::InitSettings( BOOL bForeground
, BOOL bBackground
)
448 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
452 Color
aTextColor( rStyleSettings
.GetDialogTextColor() );
454 if ( IsControlForeground() )
455 aTextColor
= GetControlForeground();
456 SetTextColor( aTextColor
);
461 if ( IsControlBackground() )
462 SetBackground( GetControlBackground() );
464 SetBackground( rStyleSettings
.GetWindowColor() );
470 // -----------------------------------------------------------------------
472 sal_UCS4
SvxShowCharSet::GetSelectCharacter() const
474 if( nSelectedIndex
>= 0 )
475 getSelectedChar() = maFontCharMap
.GetCharFromIndex( nSelectedIndex
);
476 return getSelectedChar();
479 // -----------------------------------------------------------------------
481 void SvxShowCharSet::SetFont( const Font
& rFont
)
483 // save last selected unicode
484 if( nSelectedIndex
>= 0 )
485 getSelectedChar() = maFontCharMap
.GetCharFromIndex( nSelectedIndex
);
488 aFont
.SetWeight( WEIGHT_LIGHT
);
489 aFont
.SetAlign( ALIGN_TOP
);
490 int nFontHeight
= (aOrigSize
.Height() - 5) * 2 / (3 * ROW_COUNT
);
491 aFont
.SetSize( PixelToLogic( Size( 0, nFontHeight
) ) );
492 aFont
.SetTransparent( TRUE
);
493 Control::SetFont( aFont
);
494 GetFontCharMap( maFontCharMap
);
496 // hide scrollbar when there is nothing to scroll
497 BOOL bNeedVscroll
= (maFontCharMap
.GetCharCount() > ROW_COUNT
*COLUMN_COUNT
);
499 nX
= (aOrigSize
.Width() - (bNeedVscroll
? SBWIDTH
: 0)) / COLUMN_COUNT
;
500 nY
= aOrigSize
.Height() / ROW_COUNT
;
504 aVscrollSB
.SetPosSizePixel( nX
* COLUMN_COUNT
, 0, SBWIDTH
, nY
* ROW_COUNT
);
505 aVscrollSB
.SetRangeMin( 0 );
506 int nLastRow
= (maFontCharMap
.GetCharCount() - 1 + COLUMN_COUNT
) / COLUMN_COUNT
;
507 aVscrollSB
.SetRangeMax( nLastRow
);
508 aVscrollSB
.SetPageSize( ROW_COUNT
-1 );
509 aVscrollSB
.SetVisibleSize( ROW_COUNT
);
512 // restore last selected unicode
513 int nMapIndex
= maFontCharMap
.GetIndexFromChar( getSelectedChar() );
514 SelectIndex( nMapIndex
);
516 // rearrange CharSet element in sync with nX- and nY-multiples
517 Size
aNewSize( nX
* COLUMN_COUNT
+ (bNeedVscroll
? SBWIDTH
: 0), nY
* ROW_COUNT
);
518 Point aNewPos
= aOrigPos
+ Point( (aOrigSize
.Width() - aNewSize
.Width()) / 2, 0 );
519 SetPosPixel( aNewPos
);
520 SetOutputSizePixel( aNewSize
);
522 aVscrollSB
.Show( bNeedVscroll
);
526 // -----------------------------------------------------------------------
528 void SvxShowCharSet::SelectIndex( int nNewIndex
, BOOL bFocus
)
532 // need to scroll see closest unicode
533 sal_uInt32 cPrev
= maFontCharMap
.GetPrevChar( getSelectedChar() );
534 int nMapIndex
= maFontCharMap
.GetIndexFromChar( cPrev
);
535 int nNewPos
= nMapIndex
/ COLUMN_COUNT
;
536 aVscrollSB
.SetThumbPos( nNewPos
);
537 nSelectedIndex
= bFocus
? nMapIndex
+1 : -1;
541 else if( nNewIndex
< FirstInView() )
543 // need to scroll up to see selected item
544 int nOldPos
= aVscrollSB
.GetThumbPos();
545 int nDelta
= (FirstInView() - nNewIndex
+ COLUMN_COUNT
-1) / COLUMN_COUNT
;
546 aVscrollSB
.SetThumbPos( nOldPos
- nDelta
);
547 nSelectedIndex
= nNewIndex
;
552 else if( nNewIndex
> LastInView() )
554 // need to scroll down to see selected item
555 int nOldPos
= aVscrollSB
.GetThumbPos();
556 int nDelta
= (nNewIndex
- LastInView() + COLUMN_COUNT
) / COLUMN_COUNT
;
557 aVscrollSB
.SetThumbPos( nOldPos
+ nDelta
);
558 if( nNewIndex
< maFontCharMap
.GetCharCount() )
560 nSelectedIndex
= nNewIndex
;
563 if( nOldPos
!= aVscrollSB
.GetThumbPos() )
571 // remove highlighted view
572 Color aLineCol
= GetLineColor();
573 Color aFillCol
= GetFillColor();
575 SetFillColor( GetBackground().GetColor() );
577 Point aOldPixel
= MapIndexToPixel( nSelectedIndex
);
578 aOldPixel
.Move( +1, +1);
579 DrawRect( Rectangle( aOldPixel
, Size( nX
-1, nY
-1 ) ) );
580 SetLineColor( aLineCol
);
581 SetFillColor( aFillCol
);
583 int nOldIndex
= nSelectedIndex
;
584 nSelectedIndex
= nNewIndex
;
585 DrawChars_Impl( nOldIndex
, nOldIndex
);
586 DrawChars_Impl( nNewIndex
, nNewIndex
);
589 if( nSelectedIndex
>= 0 )
591 getSelectedChar() = maFontCharMap
.GetCharFromIndex( nSelectedIndex
);
594 ::svx::SvxShowCharSetItem
* pItem
= ImplGetItem(nSelectedIndex
);
595 m_pAccessible
->fireEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
, Any(), makeAny(pItem
->GetAccessible()) ); // this call asures that m_pItem is set
597 OSL_ENSURE(pItem
->m_pItem
,"No accessible created!");
598 Any aOldAny
, aNewAny
;
599 aNewAny
<<= AccessibleStateType::FOCUSED
;
600 pItem
->m_pItem
->fireEvent( AccessibleEventId::STATE_CHANGED
, aOldAny
, aNewAny
);
602 aNewAny
<<= AccessibleStateType::SELECTED
;
603 pItem
->m_pItem
->fireEvent( AccessibleEventId::STATE_CHANGED
, aOldAny
, aNewAny
);
608 aHighHdl
.Call( this );
611 // -----------------------------------------------------------------------
613 void SvxShowCharSet::SelectCharacter( sal_UCS4 cNew
, BOOL bFocus
)
615 // get next available char of current font
616 sal_UCS4 cNext
= maFontCharMap
.GetNextChar( cNew
- 1 );
618 int nMapIndex
= maFontCharMap
.GetIndexFromChar( cNext
);
619 SelectIndex( nMapIndex
, bFocus
);
622 // move selected item to top row if not in focus
623 aVscrollSB
.SetThumbPos( nMapIndex
/ COLUMN_COUNT
);
628 // -----------------------------------------------------------------------
630 IMPL_LINK( SvxShowCharSet
, VscrollHdl
, ScrollBar
*, EMPTYARG
)
632 if( nSelectedIndex
< FirstInView() )
634 SelectIndex( FirstInView() + (nSelectedIndex
% COLUMN_COUNT
) );
636 else if( nSelectedIndex
> LastInView() )
640 ::com::sun::star::uno::Any aOldAny
, aNewAny
;
641 int nLast
= LastInView();
642 for ( ; nLast
!= nSelectedIndex
; ++nLast
)
644 aOldAny
<<= ImplGetItem(nLast
)->GetAccessible();
645 m_pAccessible
->fireEvent( AccessibleEventId::CHILD
, aOldAny
, aNewAny
);
648 SelectIndex( (LastInView() - COLUMN_COUNT
+ 1) + (nSelectedIndex
% COLUMN_COUNT
) );
655 // -----------------------------------------------------------------------
657 SvxShowCharSet::~SvxShowCharSet()
662 // -----------------------------------------------------------------------------
663 void SvxShowCharSet::ReleaseAccessible()
666 m_pAccessible
= NULL
;
667 m_xAccessible
= NULL
;
669 // -----------------------------------------------------------------------------
670 ::com::sun::star::uno::Reference
< XAccessible
> SvxShowCharSet::CreateAccessible()
672 OSL_ENSURE(!m_pAccessible
,"Accessible already created!");
673 m_pAccessible
= new ::svx::SvxShowCharSetVirtualAcc(this);
674 m_xAccessible
= m_pAccessible
;
675 return m_xAccessible
;
677 // -----------------------------------------------------------------------------
678 ::svx::SvxShowCharSetItem
* SvxShowCharSet::ImplGetItem( int _nPos
)
680 ItemsMap::iterator aFind
= m_aItems
.find(_nPos
);
681 if ( aFind
== m_aItems
.end() )
683 OSL_ENSURE(m_pAccessible
,"Who wants to create a child of my table without a parent?");
684 aFind
= m_aItems
.insert(ItemsMap::value_type(_nPos
,new ::svx::SvxShowCharSetItem(*this,m_pAccessible
->getTable(),sal::static_int_cast
< USHORT
>(_nPos
)))).first
;
685 rtl::OUStringBuffer buf
;
686 buf
.appendUtf32( maFontCharMap
.GetCharFromIndex( _nPos
) );
687 aFind
->second
->maText
= buf
.makeStringAndClear();
688 Point pix
= MapIndexToPixel( _nPos
);
689 aFind
->second
->maRect
= Rectangle( Point( pix
.X() + 1, pix
.Y() + 1 ), Size(nX
-1,nY
-1) );
692 return aFind
->second
;
694 // -----------------------------------------------------------------------------
695 void SvxShowCharSet::ImplFireAccessibleEvent( short nEventId
, const ::com::sun::star::uno::Any
& rOldValue
, const ::com::sun::star::uno::Any
& rNewValue
)
698 m_pAccessible
->fireEvent( nEventId
, rOldValue
, rNewValue
);
700 // -----------------------------------------------------------------------------
701 ScrollBar
* SvxShowCharSet::getScrollBar()
705 // -----------------------------------------------------------------------
706 sal_Int32
SvxShowCharSet::getMaxCharCount() const
708 return maFontCharMap
.GetCharCount();
712 // class SubsetMap =======================================================
713 // TODO: should be moved into Font Attributes stuff
714 // we let it mature here though because it is currently the only use
716 SubsetMap::SubsetMap( const FontCharMap
* pFontCharMap
)
717 : Resource( SVX_RES(RID_SUBSETMAP
) )
720 ApplyCharMap( pFontCharMap
);
724 const Subset
* SubsetMap::GetNextSubset( bool bFirst
) const
727 maSubsetIterator
= maSubsets
.begin();
728 if( maSubsetIterator
== maSubsets
.end() )
730 const Subset
* s
= &*(maSubsetIterator
++);
734 const Subset
* SubsetMap::GetSubsetByUnicode( sal_UCS4 cChar
) const
736 // TODO: is it worth to avoid a linear search?
737 for( const Subset
* s
= GetNextSubset( true ); s
; s
= GetNextSubset( false ) )
738 if( (s
->GetRangeMin() <= cChar
) && (cChar
<= s
->GetRangeMax()) )
743 inline Subset::Subset( sal_UCS4 nMin
, sal_UCS4 nMax
, int resId
)
744 : mnRangeMin(nMin
), mnRangeMax(nMax
), maRangeName( SVX_RES(resId
) )
747 void SubsetMap::InitList()
749 static SubsetList aAllSubsets
;
750 static bool bInit
= true;
755 // TODO: eventually merge or split unicode subranges
756 // a "native writer" should decide for his subsets
757 aAllSubsets
.push_back( Subset( 0x0020, 0x007F, RID_SUBSETSTR_BASIC_LATIN
) );
758 aAllSubsets
.push_back( Subset( 0x0080, 0x00FF, RID_SUBSETSTR_LATIN_1
) );
759 aAllSubsets
.push_back( Subset( 0x0100, 0x017F, RID_SUBSETSTR_LATIN_EXTENDED_A
) );
760 aAllSubsets
.push_back( Subset( 0x0180, 0x024F, RID_SUBSETSTR_LATIN_EXTENDED_B
) );
761 aAllSubsets
.push_back( Subset( 0x0250, 0x02AF, RID_SUBSETSTR_IPA_EXTENSIONS
) );
762 aAllSubsets
.push_back( Subset( 0x02B0, 0x02FF, RID_SUBSETSTR_SPACING_MODIFIERS
) );
763 aAllSubsets
.push_back( Subset( 0x0300, 0x036F, RID_SUBSETSTR_COMB_DIACRITICAL
) );
764 aAllSubsets
.push_back( Subset( 0x0370, 0x03FF, RID_SUBSETSTR_BASIC_GREEK
) );
765 // aAllSubsets.push_back( Subset( 0x03D0, 0x03F3, RID_SUBSETSTR_GREEK_SYMS_COPTIC ) );
766 aAllSubsets
.push_back( Subset( 0x0400, 0x04FF, RID_SUBSETSTR_CYRILLIC
) );
767 aAllSubsets
.push_back( Subset( 0x0530, 0x058F, RID_SUBSETSTR_ARMENIAN
) );
768 aAllSubsets
.push_back( Subset( 0x0590, 0x05FF, RID_SUBSETSTR_BASIC_HEBREW
) );
769 // aAllSubsets.push_back( Subset( 0x0591, 0x05C4, RID_SUBSETSTR_HEBREW_EXTENDED ) );
770 aAllSubsets
.push_back( Subset( 0x0600, 0x065F, RID_SUBSETSTR_BASIC_ARABIC
) );
771 aAllSubsets
.push_back( Subset( 0x0660, 0x06FF, RID_SUBSETSTR_ARABIC_EXTENDED
) );
772 aAllSubsets
.push_back( Subset( 0x0700, 0x074F, RID_SUBSETSTR_SYRIAC
) );
773 aAllSubsets
.push_back( Subset( 0x0780, 0x07BF, RID_SUBSETSTR_THAANA
) );
774 aAllSubsets
.push_back( Subset( 0x0900, 0x097F, RID_SUBSETSTR_DEVANAGARI
) );
775 aAllSubsets
.push_back( Subset( 0x0980, 0x09FF, RID_SUBSETSTR_BENGALI
) );
776 aAllSubsets
.push_back( Subset( 0x0A00, 0x0A7F, RID_SUBSETSTR_GURMUKHI
) );
777 aAllSubsets
.push_back( Subset( 0x0A80, 0x0AFF, RID_SUBSETSTR_GUJARATI
) );
778 aAllSubsets
.push_back( Subset( 0x0B00, 0x0B7F, RID_SUBSETSTR_ORIYA
) );
779 aAllSubsets
.push_back( Subset( 0x0B80, 0x0BFF, RID_SUBSETSTR_TAMIL
) );
780 aAllSubsets
.push_back( Subset( 0x0C00, 0x0C7F, RID_SUBSETSTR_TELUGU
) );
781 aAllSubsets
.push_back( Subset( 0x0C80, 0x0CFF, RID_SUBSETSTR_KANNADA
) );
782 aAllSubsets
.push_back( Subset( 0x0D00, 0x0D7F, RID_SUBSETSTR_MALAYALAM
) );
783 aAllSubsets
.push_back( Subset( 0x0D80, 0x0DFF, RID_SUBSETSTR_SINHALA
) );
784 aAllSubsets
.push_back( Subset( 0x0E00, 0x0E7F, RID_SUBSETSTR_THAI
) );
785 aAllSubsets
.push_back( Subset( 0x0E80, 0x0EFF, RID_SUBSETSTR_LAO
) );
786 aAllSubsets
.push_back( Subset( 0x0F00, 0x0FBF, RID_SUBSETSTR_TIBETAN
) );
787 aAllSubsets
.push_back( Subset( 0x1000, 0x109F, RID_SUBSETSTR_MYANMAR
) );
788 aAllSubsets
.push_back( Subset( 0x10A0, 0x10FF, RID_SUBSETSTR_BASIC_GEORGIAN
) );
789 // aAllSubsets.push_back( Subset( 0x10A0, 0x10C5, RID_SUBSETSTR_GEORGIAN_EXTENDED ) );
790 aAllSubsets
.push_back( Subset( 0x1100, 0x11FF, RID_SUBSETSTR_HANGUL_JAMO
) );
791 aAllSubsets
.push_back( Subset( 0x1200, 0x137F, RID_SUBSETSTR_ETHIOPIC
) );
792 aAllSubsets
.push_back( Subset( 0x13A0, 0x13FF, RID_SUBSETSTR_CHEROKEE
) );
793 aAllSubsets
.push_back( Subset( 0x1400, 0x167F, RID_SUBSETSTR_CANADIAN_ABORIGINAL
) );
794 aAllSubsets
.push_back( Subset( 0x1680, 0x169F, RID_SUBSETSTR_OGHAM
) );
795 aAllSubsets
.push_back( Subset( 0x16A0, 0x16F0, RID_SUBSETSTR_RUNIC
) );
796 aAllSubsets
.push_back( Subset( 0x1700, 0x171F, RID_SUBSETSTR_TAGALOG
) );
797 aAllSubsets
.push_back( Subset( 0x1720, 0x173F, RID_SUBSETSTR_HANUNOO
) );
798 aAllSubsets
.push_back( Subset( 0x1740, 0x175F, RID_SUBSETSTR_BUHID
) );
799 aAllSubsets
.push_back( Subset( 0x1760, 0x177F, RID_SUBSETSTR_TAGBANWA
) );
800 aAllSubsets
.push_back( Subset( 0x1780, 0x17FF, RID_SUBSETSTR_KHMER
) );
801 aAllSubsets
.push_back( Subset( 0x1800, 0x18AF, RID_SUBSETSTR_MONGOLIAN
) );
802 aAllSubsets
.push_back( Subset( 0x1E00, 0x1EFF, RID_SUBSETSTR_LATIN_EXTENDED_ADDS
) );
803 aAllSubsets
.push_back( Subset( 0x1F00, 0x1FFF, RID_SUBSETSTR_GREEK_EXTENDED
) );
805 aAllSubsets
.push_back( Subset( 0x2000, 0x206F, RID_SUBSETSTR_GENERAL_PUNCTUATION
) );
806 aAllSubsets
.push_back( Subset( 0x2070, 0x209F, RID_SUBSETSTR_SUB_SUPER_SCRIPTS
) );
807 aAllSubsets
.push_back( Subset( 0x20A0, 0x20CF, RID_SUBSETSTR_CURRENCY_SYMBOLS
) );
808 aAllSubsets
.push_back( Subset( 0x20D0, 0x20FF, RID_SUBSETSTR_COMB_DIACRITIC_SYMS
) );
809 aAllSubsets
.push_back( Subset( 0x2100, 0x214F, RID_SUBSETSTR_LETTERLIKE_SYMBOLS
) );
810 aAllSubsets
.push_back( Subset( 0x2150, 0x218F, RID_SUBSETSTR_NUMBER_FORMS
) );
811 aAllSubsets
.push_back( Subset( 0x2190, 0x21FF, RID_SUBSETSTR_ARROWS
) );
812 aAllSubsets
.push_back( Subset( 0x2200, 0x22FF, RID_SUBSETSTR_MATH_OPERATORS
) );
813 aAllSubsets
.push_back( Subset( 0x2300, 0x23FF, RID_SUBSETSTR_MISC_TECHNICAL
) );
814 aAllSubsets
.push_back( Subset( 0x2400, 0x243F, RID_SUBSETSTR_CONTROL_PICTURES
) );
815 aAllSubsets
.push_back( Subset( 0x2440, 0x245F, RID_SUBSETSTR_OPTICAL_CHAR_REC
) );
816 aAllSubsets
.push_back( Subset( 0x2460, 0x24FF, RID_SUBSETSTR_ENCLOSED_ALPHANUM
) );
817 aAllSubsets
.push_back( Subset( 0x2500, 0x257F, RID_SUBSETSTR_BOX_DRAWING
) );
818 aAllSubsets
.push_back( Subset( 0x2580, 0x259F, RID_SUBSETSTR_BLOCK_ELEMENTS
) );
819 aAllSubsets
.push_back( Subset( 0x25A0, 0x25FF, RID_SUBSETSTR_GEOMETRIC_SHAPES
) );
820 aAllSubsets
.push_back( Subset( 0x2600, 0x26FF, RID_SUBSETSTR_MISC_DINGBATS
) );
821 aAllSubsets
.push_back( Subset( 0x2700, 0x27BF, RID_SUBSETSTR_DINGBATS
) );
823 aAllSubsets
.push_back( Subset( 0x27C0, 0x27FF, RID_SUBSETSTR_MISC_MATH_SYMS_A
) );
824 aAllSubsets
.push_back( Subset( 0x27F0, 0x27FF, RID_SUBSETSTR_SUPPL_ARROWS_A
) );
825 aAllSubsets
.push_back( Subset( 0x2800, 0x28FF, RID_SUBSETSTR_BRAILLE_PATTERNS
) );
826 aAllSubsets
.push_back( Subset( 0x2900, 0x297F, RID_SUBSETSTR_SUPPL_ARROWS_B
) );
827 aAllSubsets
.push_back( Subset( 0x2980, 0x29FF, RID_SUBSETSTR_MISC_MATH_SYMS_B
) );
828 aAllSubsets
.push_back( Subset( 0x2E80, 0x2EFF, RID_SUBSETSTR_CJK_RADICAL_SUPPL
) );
829 aAllSubsets
.push_back( Subset( 0x2F00, 0x2FDF, RID_SUBSETSTR_KANXI_RADICALS
) );
830 aAllSubsets
.push_back( Subset( 0x2FF0, 0x2FFF, RID_SUBSETSTR_IDEO_DESC_CHARS
) );
832 aAllSubsets
.push_back( Subset( 0x3000, 0x303F, RID_SUBSETSTR_CJK_SYMS_PUNCTUATION
) );
833 aAllSubsets
.push_back( Subset( 0x3040, 0x309F, RID_SUBSETSTR_HIRAGANA
) );
834 aAllSubsets
.push_back( Subset( 0x30A0, 0x30FF, RID_SUBSETSTR_KATAKANA
) );
835 aAllSubsets
.push_back( Subset( 0x3100, 0x312F, RID_SUBSETSTR_BOPOMOFO
) );
836 aAllSubsets
.push_back( Subset( 0x3130, 0x318F, RID_SUBSETSTR_HANGUL_COMPAT_JAMO
) );
837 aAllSubsets
.push_back( Subset( 0x3190, 0x319F, RID_SUBSETSTR_KANBUN
) );
838 aAllSubsets
.push_back( Subset( 0x31A0, 0x31BF, RID_SUBSETSTR_BOPOMOFO_EXTENDED
) );
839 aAllSubsets
.push_back( Subset( 0x31C0, 0x31FF, RID_SUBSETSTR_KATAKANA_PHONETIC
) );
840 aAllSubsets
.push_back( Subset( 0x3200, 0x32FF, RID_SUBSETSTR_ENCLOSED_CJK_LETTERS
) );
841 aAllSubsets
.push_back( Subset( 0x3300, 0x33FF, RID_SUBSETSTR_CJK_COMPATIBILITY
) );
843 aAllSubsets
.push_back( Subset( 0x3400, 0x4DFF, RID_SUBSETSTR_CJK_EXT_A_UNIFIED_IDGRAPH
) );
844 aAllSubsets
.push_back( Subset( 0x4E00, 0x9FA5, RID_SUBSETSTR_CJK_UNIFIED_IDGRAPH
) );
845 aAllSubsets
.push_back( Subset( 0xA000, 0xA4CF, RID_SUBSETSTR_YI
) );
846 aAllSubsets
.push_back( Subset( 0xAC00, 0xB097, RID_SUBSETSTR_HANGUL_GA
) );
847 aAllSubsets
.push_back( Subset( 0xB098, 0xB2E3, RID_SUBSETSTR_HANGUL_NA
) );
848 aAllSubsets
.push_back( Subset( 0xB2E4, 0xB77B, RID_SUBSETSTR_HANGUL_DA
) );
849 aAllSubsets
.push_back( Subset( 0xB77C, 0xB9C7, RID_SUBSETSTR_HANGUL_RA
) );
850 aAllSubsets
.push_back( Subset( 0xB9C8, 0xBC13, RID_SUBSETSTR_HANGUL_MA
) );
851 aAllSubsets
.push_back( Subset( 0xBC14, 0xC0AB, RID_SUBSETSTR_HANGUL_BA
) );
852 aAllSubsets
.push_back( Subset( 0xC0AC, 0xC543, RID_SUBSETSTR_HANGUL_SA
) );
853 aAllSubsets
.push_back( Subset( 0xC544, 0xC78F, RID_SUBSETSTR_HANGUL_AH
) );
854 aAllSubsets
.push_back( Subset( 0xC790, 0xCC27, RID_SUBSETSTR_HANGUL_JA
) );
855 aAllSubsets
.push_back( Subset( 0xCC28, 0xCE73, RID_SUBSETSTR_HANGUL_CHA
) );
856 aAllSubsets
.push_back( Subset( 0xCE74, 0xD0BF, RID_SUBSETSTR_HANGUL_KA
) );
857 aAllSubsets
.push_back( Subset( 0xD0C0, 0xD30B, RID_SUBSETSTR_HANGUL_TA
) );
858 aAllSubsets
.push_back( Subset( 0xD30C, 0xD557, RID_SUBSETSTR_HANGUL_PA
) );
859 aAllSubsets
.push_back( Subset( 0xD558, 0xD7A3, RID_SUBSETSTR_HANGUL_HA
) );
860 // aAllSubsets.push_back( Subset( 0xAC00, 0xD7AF, RID_SUBSETSTR_HANGUL ) );
862 // aAllSubsets.push_back( Subset( 0xD800, 0xDFFF, RID_SUBSETSTR_SURROGATE ) );
863 aAllSubsets
.push_back( Subset( 0xE000, 0xF8FF, RID_SUBSETSTR_PRIVATE_USE_AREA
) );
864 aAllSubsets
.push_back( Subset( 0xF900, 0xFAFF, RID_SUBSETSTR_CJK_COMPAT_IDGRAPHS
) );
865 aAllSubsets
.push_back( Subset( 0xFB00, 0xFB4F, RID_SUBSETSTR_ALPHA_PRESENTATION
) );
866 aAllSubsets
.push_back( Subset( 0xFB50, 0xFDFF, RID_SUBSETSTR_ARABIC_PRESENT_A
) );
867 aAllSubsets
.push_back( Subset( 0xFE20, 0xFE2F, RID_SUBSETSTR_COMBINING_HALF_MARKS
) );
868 aAllSubsets
.push_back( Subset( 0xFE30, 0xFE4F, RID_SUBSETSTR_CJK_COMPAT_FORMS
) );
869 aAllSubsets
.push_back( Subset( 0xFE50, 0xFE6F, RID_SUBSETSTR_SMALL_FORM_VARIANTS
) );
870 aAllSubsets
.push_back( Subset( 0xFE70, 0xFEFF, RID_SUBSETSTR_ARABIC_PRESENT_B
) );
871 aAllSubsets
.push_back( Subset( 0xFF00, 0xFFEF, RID_SUBSETSTR_HALFW_FULLW_FORMS
) );
872 aAllSubsets
.push_back( Subset( 0xFFF0, 0xFFFF, RID_SUBSETSTR_SPECIALS
) );
875 maSubsets
= aAllSubsets
;
878 void SubsetMap::ApplyCharMap( const FontCharMap
* pFontCharMap
)
883 // remove subsets that are not matched in any range
884 SubsetList::iterator it_next
= maSubsets
.begin();
885 while( it_next
!= maSubsets
.end() )
887 SubsetList::iterator it
= it_next
++;
888 const Subset
& rSubset
= *it
;
889 sal_uInt32 cMin
= rSubset
.GetRangeMin();
890 sal_uInt32 cMax
= rSubset
.GetRangeMax();
892 int nCount
= pFontCharMap
->CountCharsInRange( cMin
, cMax
);
894 maSubsets
.erase( it
);