xref: /AOO41X/main/vcl/unx/gtk/a11y/atktextattributes.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "atktextattributes.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <com/sun/star/awt/FontSlant.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/awt/FontStrikeout.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/awt/FontUnderline.hpp>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <com/sun/star/style/CaseMap.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/style/LineSpacing.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/style/LineSpacingMode.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/style/ParagraphAdjust.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/style/TabAlign.hpp>
42*cdf0e10cSrcweir #include <com/sun/star/style/TabStop.hpp>
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include <com/sun/star/text/WritingMode2.hpp>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include "atkwrapper.hxx"
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #include <vcl/svapp.hxx>
51*cdf0e10cSrcweir #include <vcl/outdev.hxx>
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir #include <stdio.h>
54*cdf0e10cSrcweir #include <string.h>
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir using namespace ::com::sun::star;
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir typedef gchar* (* AtkTextAttrFunc)       ( const uno::Any& rAny );
59*cdf0e10cSrcweir typedef bool   (* TextPropertyValueFunc) ( uno::Any& rAny, const gchar * value );
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir #define STRNCMP_PARAM( s )  s,sizeof( s )-1
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir /*****************************************************************************/
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_paragraph_style = ATK_TEXT_ATTR_INVALID;
67*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_font_effect = ATK_TEXT_ATTR_INVALID;
68*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_decoration = ATK_TEXT_ATTR_INVALID;
69*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_line_height = ATK_TEXT_ATTR_INVALID;
70*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_rotation = ATK_TEXT_ATTR_INVALID;
71*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_shadow = ATK_TEXT_ATTR_INVALID;
72*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_tab_interval = ATK_TEXT_ATTR_INVALID;
73*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_tab_stops = ATK_TEXT_ATTR_INVALID;
74*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_writing_mode = ATK_TEXT_ATTR_INVALID;
75*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_vertical_align = ATK_TEXT_ATTR_INVALID;
76*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_misspelled = ATK_TEXT_ATTR_INVALID;
77*cdf0e10cSrcweir // --> OD 2010-03-01 #i92232#
78*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_tracked_change = ATK_TEXT_ATTR_INVALID;
79*cdf0e10cSrcweir // <--
80*cdf0e10cSrcweir // --> OD 2010-03-05 #i92233#
81*cdf0e10cSrcweir static AtkTextAttribute atk_text_attribute_mm_to_pixel_ratio = ATK_TEXT_ATTR_INVALID;
82*cdf0e10cSrcweir // <--
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir /*****************************************************************************/
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir /**
87*cdf0e10cSrcweir   * !! IMPORTANT NOTE !! : when adding items to this list, KEEP THE LIST SORTED
88*cdf0e10cSrcweir   *                        and re-arrange the enum values accordingly.
89*cdf0e10cSrcweir   */
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir enum ExportedAttribute
92*cdf0e10cSrcweir {
93*cdf0e10cSrcweir     TEXT_ATTRIBUTE_BACKGROUND_COLOR = 0,
94*cdf0e10cSrcweir     TEXT_ATTRIBUTE_CASEMAP,
95*cdf0e10cSrcweir     TEXT_ATTRIBUTE_FOREGROUND_COLOR,
96*cdf0e10cSrcweir     TEXT_ATTRIBUTE_CONTOURED,
97*cdf0e10cSrcweir     TEXT_ATTRIBUTE_CHAR_ESCAPEMENT,
98*cdf0e10cSrcweir     TEXT_ATTRIBUTE_BLINKING,
99*cdf0e10cSrcweir     TEXT_ATTRIBUTE_FONT_NAME,
100*cdf0e10cSrcweir     TEXT_ATTRIBUTE_HEIGHT,
101*cdf0e10cSrcweir     TEXT_ATTRIBUTE_HIDDEN,
102*cdf0e10cSrcweir     TEXT_ATTRIBUTE_KERNING,
103*cdf0e10cSrcweir     TEXT_ATTRIBUTE_LOCALE,
104*cdf0e10cSrcweir     TEXT_ATTRIBUTE_POSTURE,
105*cdf0e10cSrcweir     TEXT_ATTRIBUTE_RELIEF,
106*cdf0e10cSrcweir     TEXT_ATTRIBUTE_ROTATION,
107*cdf0e10cSrcweir     TEXT_ATTRIBUTE_SCALE,
108*cdf0e10cSrcweir     TEXT_ATTRIBUTE_SHADOWED,
109*cdf0e10cSrcweir     TEXT_ATTRIBUTE_STRIKETHROUGH,
110*cdf0e10cSrcweir     TEXT_ATTRIBUTE_UNDERLINE,
111*cdf0e10cSrcweir     TEXT_ATTRIBUTE_WEIGHT,
112*cdf0e10cSrcweir     // --> OD 2010-03-05 #i92233#
113*cdf0e10cSrcweir     TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO,
114*cdf0e10cSrcweir     // <--
115*cdf0e10cSrcweir     TEXT_ATTRIBUTE_JUSTIFICATION,
116*cdf0e10cSrcweir     TEXT_ATTRIBUTE_BOTTOM_MARGIN,
117*cdf0e10cSrcweir     TEXT_ATTRIBUTE_FIRST_LINE_INDENT,
118*cdf0e10cSrcweir     TEXT_ATTRIBUTE_LEFT_MARGIN,
119*cdf0e10cSrcweir     TEXT_ATTRIBUTE_LINE_SPACING,
120*cdf0e10cSrcweir     TEXT_ATTRIBUTE_RIGHT_MARGIN,
121*cdf0e10cSrcweir     TEXT_ATTRIBUTE_STYLE_NAME,
122*cdf0e10cSrcweir     TEXT_ATTRIBUTE_TAB_STOPS,
123*cdf0e10cSrcweir     TEXT_ATTRIBUTE_TOP_MARGIN,
124*cdf0e10cSrcweir     TEXT_ATTRIBUTE_WRITING_MODE,
125*cdf0e10cSrcweir     TEXT_ATTRIBUTE_LAST
126*cdf0e10cSrcweir };
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir static const char * ExportedTextAttributes[TEXT_ATTRIBUTE_LAST] =
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     "CharBackColor",        // TEXT_ATTRIBUTE_BACKGROUND_COLOR
131*cdf0e10cSrcweir     "CharCaseMap",          // TEXT_ATTRIBUTE_CASEMAP
132*cdf0e10cSrcweir     "CharColor",            // TEXT_ATTRIBUTE_FOREGROUND_COLOR
133*cdf0e10cSrcweir     "CharContoured",        // TEXT_ATTRIBUTE_CONTOURED
134*cdf0e10cSrcweir     "CharEscapement",       // TEXT_ATTRIBUTE_CHAR_ESCAPEMENT
135*cdf0e10cSrcweir     "CharFlash",            // TEXT_ATTRIBUTE_BLINKING
136*cdf0e10cSrcweir     "CharFontName",         // TEXT_ATTRIBUTE_FONT_NAME
137*cdf0e10cSrcweir     "CharHeight",           // TEXT_ATTRIBUTE_HEIGHT
138*cdf0e10cSrcweir     "CharHidden",           // TEXT_ATTRIBUTE_HIDDEN
139*cdf0e10cSrcweir     "CharKerning",          // TEXT_ATTRIBUTE_KERNING
140*cdf0e10cSrcweir     "CharLocale",           // TEXT_ATTRIBUTE_LOCALE
141*cdf0e10cSrcweir     "CharPosture",          // TEXT_ATTRIBUTE_POSTURE
142*cdf0e10cSrcweir     "CharRelief",           // TEXT_ATTRIBUTE_RELIEF
143*cdf0e10cSrcweir     "CharRotation",         // TEXT_ATTRIBUTE_ROTATION
144*cdf0e10cSrcweir     "CharScaleWidth",       // TEXT_ATTRIBUTE_SCALE
145*cdf0e10cSrcweir     "CharShadowed",         // TEXT_ATTRIBUTE_SHADOWED
146*cdf0e10cSrcweir     "CharStrikeout",        // TEXT_ATTRIBUTE_STRIKETHROUGH
147*cdf0e10cSrcweir     "CharUnderline",        // TEXT_ATTRIBUTE_UNDERLINE
148*cdf0e10cSrcweir     "CharWeight",           // TEXT_ATTRIBUTE_WEIGHT
149*cdf0e10cSrcweir     // --> OD 2010-03-05 #i92233#
150*cdf0e10cSrcweir     "MMToPixelRatio",       // TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO
151*cdf0e10cSrcweir     // <--
152*cdf0e10cSrcweir     "ParaAdjust",           // TEXT_ATTRIBUTE_JUSTIFICATION
153*cdf0e10cSrcweir     "ParaBottomMargin",     // TEXT_ATTRIBUTE_BOTTOM_MARGIN
154*cdf0e10cSrcweir     "ParaFirstLineIndent",  // TEXT_ATTRIBUTE_FIRST_LINE_INDENT
155*cdf0e10cSrcweir     "ParaLeftMargin",       // TEXT_ATTRIBUTE_LEFT_MARGIN
156*cdf0e10cSrcweir     "ParaLineSpacing",      // TEXT_ATTRIBUTE_LINE_SPACING
157*cdf0e10cSrcweir     "ParaRightMargin",      // TEXT_ATTRIBUTE_RIGHT_MARGIN
158*cdf0e10cSrcweir     "ParaStyleName",        // TEXT_ATTRIBUTE_STYLE_NAME
159*cdf0e10cSrcweir     "ParaTabStops",         // TEXT_ATTRIBUTE_TAB_STOPS
160*cdf0e10cSrcweir     "ParaTopMargin",        // TEXT_ATTRIBUTE_TOP_MARGIN
161*cdf0e10cSrcweir     "WritingMode"           // TEXT_ATTRIBUTE_WRITING_MODE
162*cdf0e10cSrcweir };
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir /*****************************************************************************/
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir static gchar*
168*cdf0e10cSrcweir get_value( const uno::Sequence< beans::PropertyValue >& rAttributeList,
169*cdf0e10cSrcweir            sal_Int32 nIndex, AtkTextAttrFunc func )
170*cdf0e10cSrcweir {
171*cdf0e10cSrcweir     if( nIndex != -1 )
172*cdf0e10cSrcweir         return func(rAttributeList[nIndex].Value);
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir     return NULL;
175*cdf0e10cSrcweir }
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir #define get_bool_value( list, index ) get_value( list, index, Bool2String )
178*cdf0e10cSrcweir #define get_short_value( list, index ) get_value( list, index, Short2String )
179*cdf0e10cSrcweir //#define get_long_value( list, index ) get_value( list, index, Long2String ) pb: not used (warning on linux)
180*cdf0e10cSrcweir #define get_height_value( list, index ) get_value( list, index, Float2String )
181*cdf0e10cSrcweir #define get_justification_value( list, index ) get_value( list, index, Adjust2Justification )
182*cdf0e10cSrcweir #define get_cmm_value( list, index ) get_value( list, index, CMM2UnitString )
183*cdf0e10cSrcweir #define get_scale_width( list, index ) get_value( list, index, Scale2String )
184*cdf0e10cSrcweir #define get_strikethrough_value( list, index ) get_value( list, index, Strikeout2String )
185*cdf0e10cSrcweir #define get_string_value( list, index ) get_value( list, index, GetString )
186*cdf0e10cSrcweir #define get_style_value( list, index ) get_value( list, index, FontSlant2Style )
187*cdf0e10cSrcweir #define get_underline_value( list, index ) get_value( list, index, Underline2String )
188*cdf0e10cSrcweir #define get_variant_value( list, index ) get_value( list, index, CaseMap2String )
189*cdf0e10cSrcweir #define get_weight_value( list, index ) get_value( list, index, Weight2String )
190*cdf0e10cSrcweir #define get_language_string( list, index ) get_value( list, index, Locale2String )
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir /*
193*cdf0e10cSrcweir static gchar*
194*cdf0e10cSrcweir dump_value( const uno::Sequence< beans::PropertyValue >& rAttributeList, sal_Int32 nIndex )
195*cdf0e10cSrcweir {
196*cdf0e10cSrcweir     if( nIndex != -1 )
197*cdf0e10cSrcweir     {
198*cdf0e10cSrcweir         rtl::OString aName = rtl::OUStringToOString(rAttributeList[nIndex].Name, RTL_TEXTENCODING_UTF8);
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir         if( rAttributeList[nIndex].Value.has<sal_Int16> () )
201*cdf0e10cSrcweir             OSL_TRACE( "%s = %d (short value)", aName.getStr(),
202*cdf0e10cSrcweir                 rAttributeList[nIndex].Value.get<sal_Int16> () );
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir         else if( rAttributeList[nIndex].Value.has<sal_Int8> () )
205*cdf0e10cSrcweir             OSL_TRACE( "%s = %d (byte value)", aName.getStr(),
206*cdf0e10cSrcweir                 rAttributeList[nIndex].Value.get<sal_Int8> () );
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir         else if( rAttributeList[nIndex].Value.has<sal_Bool> () )
209*cdf0e10cSrcweir             OSL_TRACE( "%s = %s (bool value)", aName.getStr(),
210*cdf0e10cSrcweir                 rAttributeList[nIndex].Value.get<sal_Bool> () ? "true" : "false" );
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir         else if( rAttributeList[nIndex].Value.has<rtl::OUString> () )
213*cdf0e10cSrcweir             OSL_TRACE( "%s = %s", aName.getStr(),
214*cdf0e10cSrcweir                 rtl::OUStringToOString(rAttributeList[nIndex].Value.get<rtl::OUString> (),
215*cdf0e10cSrcweir                     RTL_TEXTENCODING_UTF8).getStr() );
216*cdf0e10cSrcweir     }
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir     return NULL;
219*cdf0e10cSrcweir }
220*cdf0e10cSrcweir */
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir static inline
223*cdf0e10cSrcweir double toPoint(sal_Int16 n)
224*cdf0e10cSrcweir {
225*cdf0e10cSrcweir     // 100th mm -> pt
226*cdf0e10cSrcweir     return (double) (n * 72) / 2540;
227*cdf0e10cSrcweir }
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir /*****************************************************************************/
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir /*
233*cdf0e10cSrcweir static gchar*
234*cdf0e10cSrcweir NullString(const uno::Any&)
235*cdf0e10cSrcweir {
236*cdf0e10cSrcweir     return NULL;
237*cdf0e10cSrcweir }
238*cdf0e10cSrcweir */
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir static bool
241*cdf0e10cSrcweir InvalidValue( uno::Any&, const gchar * )
242*cdf0e10cSrcweir {
243*cdf0e10cSrcweir     return false;
244*cdf0e10cSrcweir }
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir /*****************************************************************************/
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir static gchar*
249*cdf0e10cSrcweir Float2String(const uno::Any& rAny)
250*cdf0e10cSrcweir {
251*cdf0e10cSrcweir     return g_strdup_printf( "%g", rAny.get<float>() );
252*cdf0e10cSrcweir }
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir static bool
255*cdf0e10cSrcweir String2Float( uno::Any& rAny, const gchar * value )
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir     float fval;
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir     if( 1 != sscanf( value, "%g", &fval ) )
260*cdf0e10cSrcweir         return false;
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir     rAny = uno::makeAny( fval );
263*cdf0e10cSrcweir     return true;
264*cdf0e10cSrcweir }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir /*****************************************************************************/
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir /*
269*cdf0e10cSrcweir static gchar*
270*cdf0e10cSrcweir Short2String(const uno::Any& rAny)
271*cdf0e10cSrcweir {
272*cdf0e10cSrcweir     return g_strdup_printf( "%d", rAny.get<sal_Int16>() );
273*cdf0e10cSrcweir }
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir static bool
276*cdf0e10cSrcweir String2Short( uno::Any& rAny, const gchar * value )
277*cdf0e10cSrcweir {
278*cdf0e10cSrcweir     sal_Int32 lval;
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir     if( 1 != sscanf( value, "%d", &lval ) )
281*cdf0e10cSrcweir         return false;
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir     rAny = uno::makeAny( (sal_Int16) lval );
284*cdf0e10cSrcweir     return true;
285*cdf0e10cSrcweir }
286*cdf0e10cSrcweir */
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir /*****************************************************************************/
289*cdf0e10cSrcweir /* pb: not used (warning on linux)
290*cdf0e10cSrcweir static gchar*
291*cdf0e10cSrcweir Long2String(const uno::Any& rAny)
292*cdf0e10cSrcweir {
293*cdf0e10cSrcweir     return g_strdup_printf( "%ld", rAny.get<sal_Int32>() );
294*cdf0e10cSrcweir }
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir static bool
297*cdf0e10cSrcweir String2Long( uno::Any& rAny, const gchar * value )
298*cdf0e10cSrcweir {
299*cdf0e10cSrcweir     sal_Int32 lval;
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir     if( 1 != sscanf( value, "%ld", &lval ) )
302*cdf0e10cSrcweir         return false;
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir     rAny = uno::makeAny( lval );
305*cdf0e10cSrcweir     return true;
306*cdf0e10cSrcweir }
307*cdf0e10cSrcweir */
308*cdf0e10cSrcweir /*****************************************************************************/
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir static accessibility::XAccessibleComponent*
311*cdf0e10cSrcweir     getComponent( AtkText *pText ) throw (uno::RuntimeException)
312*cdf0e10cSrcweir {
313*cdf0e10cSrcweir     AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pText );
314*cdf0e10cSrcweir     if( pWrap )
315*cdf0e10cSrcweir     {
316*cdf0e10cSrcweir         if( !pWrap->mpComponent && pWrap->mpContext )
317*cdf0e10cSrcweir         {
318*cdf0e10cSrcweir             uno::Any any = pWrap->mpContext->queryInterface( accessibility::XAccessibleComponent::static_type(NULL) );
319*cdf0e10cSrcweir             pWrap->mpComponent = reinterpret_cast< accessibility::XAccessibleComponent * > (any.pReserved);
320*cdf0e10cSrcweir             pWrap->mpComponent->acquire();
321*cdf0e10cSrcweir         }
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir         return pWrap->mpComponent;
324*cdf0e10cSrcweir     }
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir     return NULL;
327*cdf0e10cSrcweir }
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir static gchar*
330*cdf0e10cSrcweir get_color_value(const uno::Sequence< beans::PropertyValue >& rAttributeList,
331*cdf0e10cSrcweir                 const sal_Int32 * pIndexArray,
332*cdf0e10cSrcweir                 ExportedAttribute attr,
333*cdf0e10cSrcweir                 AtkText * text)
334*cdf0e10cSrcweir {
335*cdf0e10cSrcweir     sal_Int32 nColor = -1; // AUTOMATIC
336*cdf0e10cSrcweir     sal_Int32 nIndex = pIndexArray[attr];
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir     if( nIndex != -1 )
339*cdf0e10cSrcweir         nColor = rAttributeList[nIndex].Value.get<sal_Int32>();
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir     /*
342*cdf0e10cSrcweir      * Check for color value for 100% alpha white, which means
343*cdf0e10cSrcweir      * "automatic". Grab the RGB value from XAccessibleComponent
344*cdf0e10cSrcweir      * in this case.
345*cdf0e10cSrcweir      */
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir     if( (nColor == -1) && text )
348*cdf0e10cSrcweir     {
349*cdf0e10cSrcweir         try
350*cdf0e10cSrcweir         {
351*cdf0e10cSrcweir             accessibility::XAccessibleComponent *pComponent = getComponent( text );
352*cdf0e10cSrcweir             if( pComponent )
353*cdf0e10cSrcweir             {
354*cdf0e10cSrcweir                 switch( attr )
355*cdf0e10cSrcweir                 {
356*cdf0e10cSrcweir                     case TEXT_ATTRIBUTE_BACKGROUND_COLOR:
357*cdf0e10cSrcweir                         nColor = pComponent->getBackground();
358*cdf0e10cSrcweir                         break;
359*cdf0e10cSrcweir                     case TEXT_ATTRIBUTE_FOREGROUND_COLOR:
360*cdf0e10cSrcweir                         nColor = pComponent->getForeground();
361*cdf0e10cSrcweir                         break;
362*cdf0e10cSrcweir                     default:
363*cdf0e10cSrcweir                         break;
364*cdf0e10cSrcweir                 }
365*cdf0e10cSrcweir             }
366*cdf0e10cSrcweir         }
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir         catch(const uno::Exception& e) {
369*cdf0e10cSrcweir             g_warning( "Exception in get[Fore|Back]groundColor()" );
370*cdf0e10cSrcweir         }
371*cdf0e10cSrcweir     }
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir     if( nColor != -1 )
374*cdf0e10cSrcweir     {
375*cdf0e10cSrcweir         sal_uInt8 blue  = nColor & 0xFF;
376*cdf0e10cSrcweir         sal_uInt8 green = (nColor >> 8) & 0xFF;
377*cdf0e10cSrcweir         sal_uInt8 red   = (nColor >> 16) & 0xFF;
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir         return g_strdup_printf( "%u,%u,%u", red, green, blue );
380*cdf0e10cSrcweir     }
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir     return NULL;
383*cdf0e10cSrcweir }
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir static bool
386*cdf0e10cSrcweir String2Color( uno::Any& rAny, const gchar * value )
387*cdf0e10cSrcweir {
388*cdf0e10cSrcweir     int red, green, blue;
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir     if( 3 != sscanf( value, "%d,%d,%d", &red, &green, &blue ) )
391*cdf0e10cSrcweir         return false;
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir     sal_Int32 nColor = (sal_Int32) blue | ( (sal_Int32) green << 8 ) | ( ( sal_Int32 ) red << 16 );
394*cdf0e10cSrcweir     rAny = uno::makeAny( nColor );
395*cdf0e10cSrcweir     return true;
396*cdf0e10cSrcweir }
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir /*****************************************************************************/
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir static gchar*
401*cdf0e10cSrcweir FontSlant2Style(const uno::Any& rAny)
402*cdf0e10cSrcweir {
403*cdf0e10cSrcweir     const gchar * value = NULL;
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir     switch( rAny.get<awt::FontSlant>() )
406*cdf0e10cSrcweir     {
407*cdf0e10cSrcweir         case awt::FontSlant_NONE:
408*cdf0e10cSrcweir             value = "normal";
409*cdf0e10cSrcweir             break;
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir         case awt::FontSlant_OBLIQUE:
412*cdf0e10cSrcweir             value = "oblique";
413*cdf0e10cSrcweir             break;
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir         case awt::FontSlant_ITALIC:
416*cdf0e10cSrcweir             value = "italic";
417*cdf0e10cSrcweir             break;
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir         case awt::FontSlant_REVERSE_OBLIQUE:
420*cdf0e10cSrcweir             value = "reverse oblique";
421*cdf0e10cSrcweir             break;
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir         case awt::FontSlant_REVERSE_ITALIC:
424*cdf0e10cSrcweir             value = "reverse italic";
425*cdf0e10cSrcweir             break;
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir         default:
428*cdf0e10cSrcweir             break;
429*cdf0e10cSrcweir     }
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir     if( value )
432*cdf0e10cSrcweir          return g_strdup( value );
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir     return NULL;
435*cdf0e10cSrcweir }
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir static bool
438*cdf0e10cSrcweir Style2FontSlant( uno::Any& rAny, const gchar * value )
439*cdf0e10cSrcweir {
440*cdf0e10cSrcweir     awt::FontSlant aFontSlant;
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir     if( strncmp( value, STRNCMP_PARAM( "normal" ) ) )
443*cdf0e10cSrcweir         aFontSlant = awt::FontSlant_NONE;
444*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "oblique" ) ) )
445*cdf0e10cSrcweir         aFontSlant = awt::FontSlant_OBLIQUE;
446*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "italic" ) ) )
447*cdf0e10cSrcweir         aFontSlant = awt::FontSlant_ITALIC;
448*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "reverse oblique" ) ) )
449*cdf0e10cSrcweir         aFontSlant = awt::FontSlant_REVERSE_OBLIQUE;
450*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "reverse italic" ) ) )
451*cdf0e10cSrcweir         aFontSlant = awt::FontSlant_REVERSE_ITALIC;
452*cdf0e10cSrcweir     else
453*cdf0e10cSrcweir         return false;
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir     rAny = uno::makeAny( aFontSlant );
456*cdf0e10cSrcweir     return true;
457*cdf0e10cSrcweir }
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir /*****************************************************************************/
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir static gchar*
462*cdf0e10cSrcweir Weight2String(const uno::Any& rAny)
463*cdf0e10cSrcweir {
464*cdf0e10cSrcweir     return g_strdup_printf( "%g", rAny.get<float>() * 4 );
465*cdf0e10cSrcweir }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir static bool
468*cdf0e10cSrcweir String2Weight( uno::Any& rAny, const gchar * value )
469*cdf0e10cSrcweir {
470*cdf0e10cSrcweir     float weight;
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir     if( 1 != sscanf( value, "%g", &weight ) )
473*cdf0e10cSrcweir         return false;
474*cdf0e10cSrcweir 
475*cdf0e10cSrcweir     rAny = uno::makeAny( weight / 4 );
476*cdf0e10cSrcweir     return true;
477*cdf0e10cSrcweir }
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir /*****************************************************************************/
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir static gchar*
483*cdf0e10cSrcweir Adjust2Justification(const uno::Any& rAny)
484*cdf0e10cSrcweir {
485*cdf0e10cSrcweir     const gchar * value = NULL;
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir     switch( rAny.get<short>() )
488*cdf0e10cSrcweir     {
489*cdf0e10cSrcweir         case style::ParagraphAdjust_LEFT:
490*cdf0e10cSrcweir             value = "left";
491*cdf0e10cSrcweir             break;
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir         case style::ParagraphAdjust_RIGHT:
494*cdf0e10cSrcweir             value = "right";
495*cdf0e10cSrcweir             break;
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir         case style::ParagraphAdjust_BLOCK:
498*cdf0e10cSrcweir         case style::ParagraphAdjust_STRETCH:
499*cdf0e10cSrcweir             value = "fill";
500*cdf0e10cSrcweir             break;
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir         case style::ParagraphAdjust_CENTER:
503*cdf0e10cSrcweir             value = "center";
504*cdf0e10cSrcweir             break;
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir         default:
507*cdf0e10cSrcweir             break;
508*cdf0e10cSrcweir     }
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir     if( value )
511*cdf0e10cSrcweir         return g_strdup( value );
512*cdf0e10cSrcweir 
513*cdf0e10cSrcweir     return NULL;
514*cdf0e10cSrcweir }
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir static bool
517*cdf0e10cSrcweir Justification2Adjust( uno::Any& rAny, const gchar * value )
518*cdf0e10cSrcweir {
519*cdf0e10cSrcweir     short nParagraphAdjust;
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir     if( strncmp( value, STRNCMP_PARAM( "left" ) ) )
522*cdf0e10cSrcweir         nParagraphAdjust = style::ParagraphAdjust_LEFT;
523*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "right" ) ) )
524*cdf0e10cSrcweir         nParagraphAdjust = style::ParagraphAdjust_RIGHT;
525*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "fill" ) ) )
526*cdf0e10cSrcweir         nParagraphAdjust = style::ParagraphAdjust_BLOCK;
527*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "center" ) ) )
528*cdf0e10cSrcweir         nParagraphAdjust = style::ParagraphAdjust_CENTER;
529*cdf0e10cSrcweir     else
530*cdf0e10cSrcweir         return false;
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir     rAny = uno::makeAny( nParagraphAdjust );
533*cdf0e10cSrcweir     return true;
534*cdf0e10cSrcweir }
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir /*****************************************************************************/
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir const gchar * font_strikethrough[] = {
539*cdf0e10cSrcweir     "none",   // FontStrikeout::NONE
540*cdf0e10cSrcweir     "single", // FontStrikeout::SINGLE
541*cdf0e10cSrcweir     "double", // FontStrikeout::DOUBLE
542*cdf0e10cSrcweir     NULL,     // FontStrikeout::DONTKNOW
543*cdf0e10cSrcweir     "bold",   // FontStrikeout::BOLD
544*cdf0e10cSrcweir     "with /", // FontStrikeout::SLASH
545*cdf0e10cSrcweir     "with X"  // FontStrikeout::X
546*cdf0e10cSrcweir };
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir const sal_Int16 n_strikeout_constants = sizeof(font_strikethrough) / sizeof(gchar*);
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir static gchar*
551*cdf0e10cSrcweir Strikeout2String(const uno::Any& rAny)
552*cdf0e10cSrcweir {
553*cdf0e10cSrcweir     sal_Int16 n = rAny.get<sal_Int16>();
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir     if( n >= 0 && n < n_strikeout_constants )
556*cdf0e10cSrcweir         return g_strdup( font_strikethrough[n] );
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir     return NULL;
559*cdf0e10cSrcweir }
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir static bool
562*cdf0e10cSrcweir String2Strikeout( uno::Any& rAny, const gchar * value )
563*cdf0e10cSrcweir {
564*cdf0e10cSrcweir     for( sal_Int16 n=0; n < n_strikeout_constants; ++n )
565*cdf0e10cSrcweir     {
566*cdf0e10cSrcweir         if( ( NULL != font_strikethrough[n] ) &&
567*cdf0e10cSrcweir             0 == strncmp( value, font_strikethrough[n], strlen( font_strikethrough[n] ) ) )
568*cdf0e10cSrcweir         {
569*cdf0e10cSrcweir             rAny = uno::makeAny( n );
570*cdf0e10cSrcweir             return true;
571*cdf0e10cSrcweir         }
572*cdf0e10cSrcweir     }
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir     return false;
575*cdf0e10cSrcweir }
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir /*****************************************************************************/
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir static gchar*
580*cdf0e10cSrcweir Underline2String(const uno::Any& rAny)
581*cdf0e10cSrcweir {
582*cdf0e10cSrcweir     const gchar * value = NULL;
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir     switch( rAny.get<sal_Int16>() )
585*cdf0e10cSrcweir     {
586*cdf0e10cSrcweir         case awt::FontUnderline::NONE:
587*cdf0e10cSrcweir             value = "none";
588*cdf0e10cSrcweir             break;
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir         case awt::FontUnderline::SINGLE:
591*cdf0e10cSrcweir             value = "single";
592*cdf0e10cSrcweir             break;
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir         case awt::FontUnderline::DOUBLE:
595*cdf0e10cSrcweir             value = "double";
596*cdf0e10cSrcweir             break;
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir         default:
599*cdf0e10cSrcweir             break;
600*cdf0e10cSrcweir     }
601*cdf0e10cSrcweir 
602*cdf0e10cSrcweir     if( value )
603*cdf0e10cSrcweir         return g_strdup( value );
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir     return NULL;
606*cdf0e10cSrcweir }
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir static bool
609*cdf0e10cSrcweir String2Underline( uno::Any& rAny, const gchar * value )
610*cdf0e10cSrcweir {
611*cdf0e10cSrcweir     short nUnderline;
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir     if( strncmp( value, STRNCMP_PARAM( "none" ) ) )
614*cdf0e10cSrcweir         nUnderline = awt::FontUnderline::NONE;
615*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "single" ) ) )
616*cdf0e10cSrcweir         nUnderline = awt::FontUnderline::SINGLE;
617*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "double" ) ) )
618*cdf0e10cSrcweir         nUnderline = awt::FontUnderline::DOUBLE;
619*cdf0e10cSrcweir     else
620*cdf0e10cSrcweir         return false;
621*cdf0e10cSrcweir 
622*cdf0e10cSrcweir     rAny = uno::makeAny( nUnderline );
623*cdf0e10cSrcweir     return true;
624*cdf0e10cSrcweir }
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir /*****************************************************************************/
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir static gchar*
629*cdf0e10cSrcweir GetString(const uno::Any& rAny)
630*cdf0e10cSrcweir {
631*cdf0e10cSrcweir     rtl::OString aFontName = rtl::OUStringToOString( rAny.get< rtl::OUString > (), RTL_TEXTENCODING_UTF8 );
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir     if( aFontName.getLength() )
634*cdf0e10cSrcweir         return g_strdup( aFontName.getStr() );
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir     return NULL;
637*cdf0e10cSrcweir }
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir static bool
640*cdf0e10cSrcweir SetString( uno::Any& rAny, const gchar * value )
641*cdf0e10cSrcweir {
642*cdf0e10cSrcweir     rtl::OString aFontName( value );
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir     if( aFontName.getLength() )
645*cdf0e10cSrcweir     {
646*cdf0e10cSrcweir         rAny = uno::makeAny( rtl::OStringToOUString( aFontName, RTL_TEXTENCODING_UTF8 ) );
647*cdf0e10cSrcweir         return true;
648*cdf0e10cSrcweir     }
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir     return false;
651*cdf0e10cSrcweir }
652*cdf0e10cSrcweir 
653*cdf0e10cSrcweir /*****************************************************************************/
654*cdf0e10cSrcweir 
655*cdf0e10cSrcweir // @see http://developer.gnome.org/doc/API/2.0/atk/AtkText.html#AtkTextAttribute
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir // CMM = 100th of mm
658*cdf0e10cSrcweir static gchar*
659*cdf0e10cSrcweir CMM2UnitString(const uno::Any& rAny)
660*cdf0e10cSrcweir {
661*cdf0e10cSrcweir     double fValue = rAny.get<sal_Int32>();
662*cdf0e10cSrcweir     fValue = fValue * 0.01;
663*cdf0e10cSrcweir 
664*cdf0e10cSrcweir     return g_strdup_printf( "%gmm", fValue );
665*cdf0e10cSrcweir }
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir static bool
668*cdf0e10cSrcweir UnitString2CMM( uno::Any& rAny, const gchar * value )
669*cdf0e10cSrcweir {
670*cdf0e10cSrcweir     float fValue = 0.0; // pb: dont use double here because of warning on linux
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir     if( 1 != sscanf( value, "%gmm", &fValue ) )
673*cdf0e10cSrcweir         return false;
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir     fValue = fValue * 100;
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir     rAny = uno::makeAny( (sal_Int32) fValue);
678*cdf0e10cSrcweir     return true;
679*cdf0e10cSrcweir }
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir /*****************************************************************************/
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir static const gchar * bool_values[] = { "true", "false" };
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir static gchar *
686*cdf0e10cSrcweir Bool2String( const uno::Any& rAny )
687*cdf0e10cSrcweir {
688*cdf0e10cSrcweir     int n = 1;
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir     if( rAny.get<sal_Bool>() )
691*cdf0e10cSrcweir         n = 0;
692*cdf0e10cSrcweir 
693*cdf0e10cSrcweir     return g_strdup( bool_values[n] );
694*cdf0e10cSrcweir }
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir static bool
697*cdf0e10cSrcweir String2Bool( uno::Any& rAny, const gchar * value )
698*cdf0e10cSrcweir {
699*cdf0e10cSrcweir     sal_Bool bValue;
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir     if( strncmp( value, STRNCMP_PARAM( "true" ) ) )
702*cdf0e10cSrcweir         bValue = sal_True;
703*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "false" ) ) )
704*cdf0e10cSrcweir         bValue = sal_False;
705*cdf0e10cSrcweir     else
706*cdf0e10cSrcweir         return false;
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir     rAny = uno::makeAny(bValue);
709*cdf0e10cSrcweir     return true;
710*cdf0e10cSrcweir }
711*cdf0e10cSrcweir 
712*cdf0e10cSrcweir /*****************************************************************************/
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir static gchar*
715*cdf0e10cSrcweir Scale2String( const uno::Any& rAny )
716*cdf0e10cSrcweir {
717*cdf0e10cSrcweir     return g_strdup_printf( "%g", (double) (rAny.get< sal_Int16 > ()) / 100 );
718*cdf0e10cSrcweir }
719*cdf0e10cSrcweir 
720*cdf0e10cSrcweir static bool
721*cdf0e10cSrcweir String2Scale( uno::Any& rAny, const gchar * value )
722*cdf0e10cSrcweir {
723*cdf0e10cSrcweir     double dval;
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir     if( 1 != sscanf( value, "%lg", &dval ) )
726*cdf0e10cSrcweir         return false;
727*cdf0e10cSrcweir 
728*cdf0e10cSrcweir     rAny = uno::makeAny((sal_Int16) (dval * 100));
729*cdf0e10cSrcweir     return true;
730*cdf0e10cSrcweir }
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir /*****************************************************************************/
733*cdf0e10cSrcweir 
734*cdf0e10cSrcweir static gchar *
735*cdf0e10cSrcweir CaseMap2String( const uno::Any& rAny )
736*cdf0e10cSrcweir {
737*cdf0e10cSrcweir     const gchar * value = NULL;
738*cdf0e10cSrcweir 
739*cdf0e10cSrcweir     switch( rAny.get<short>() )
740*cdf0e10cSrcweir     {
741*cdf0e10cSrcweir         case style::CaseMap::SMALLCAPS:
742*cdf0e10cSrcweir             value = "small_caps";
743*cdf0e10cSrcweir             break;
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir         default:
746*cdf0e10cSrcweir             value = "normal";
747*cdf0e10cSrcweir             break;
748*cdf0e10cSrcweir     }
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir     if( value )
751*cdf0e10cSrcweir         return g_strdup( value );
752*cdf0e10cSrcweir 
753*cdf0e10cSrcweir     return NULL;
754*cdf0e10cSrcweir }
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir static bool
757*cdf0e10cSrcweir String2CaseMap( uno::Any& rAny, const gchar * value )
758*cdf0e10cSrcweir {
759*cdf0e10cSrcweir     short nCaseMap;
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir     if( strncmp( value, STRNCMP_PARAM( "normal" ) ) )
762*cdf0e10cSrcweir         nCaseMap = style::CaseMap::NONE;
763*cdf0e10cSrcweir     else if( strncmp( value, STRNCMP_PARAM( "small_caps" ) ) )
764*cdf0e10cSrcweir         nCaseMap = style::CaseMap::SMALLCAPS;
765*cdf0e10cSrcweir     else
766*cdf0e10cSrcweir         return false;
767*cdf0e10cSrcweir 
768*cdf0e10cSrcweir     rAny = uno::makeAny( nCaseMap );
769*cdf0e10cSrcweir     return true;
770*cdf0e10cSrcweir }
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir /*****************************************************************************/
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir const gchar * font_stretch[] = {
775*cdf0e10cSrcweir     "ultra_condensed",
776*cdf0e10cSrcweir     "extra_condensed",
777*cdf0e10cSrcweir     "condensed",
778*cdf0e10cSrcweir     "semi_condensed",
779*cdf0e10cSrcweir     "normal",
780*cdf0e10cSrcweir     "semi_expanded",
781*cdf0e10cSrcweir     "expanded",
782*cdf0e10cSrcweir     "extra_expanded",
783*cdf0e10cSrcweir     "ultra_expanded"
784*cdf0e10cSrcweir };
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir static gchar*
787*cdf0e10cSrcweir Kerning2Stretch(const uno::Any& rAny)
788*cdf0e10cSrcweir {
789*cdf0e10cSrcweir     sal_Int16 n = rAny.get<sal_Int16>();
790*cdf0e10cSrcweir     int i = 4;
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir     // No good idea for a mapping - just return the basic info
793*cdf0e10cSrcweir     if( n < 0 )
794*cdf0e10cSrcweir         i=2;
795*cdf0e10cSrcweir     else if( n > 0 )
796*cdf0e10cSrcweir         i=6;
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir     return g_strdup(font_stretch[i]);
799*cdf0e10cSrcweir }
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir /*****************************************************************************/
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir static gchar*
804*cdf0e10cSrcweir Locale2String(const uno::Any& rAny)
805*cdf0e10cSrcweir {
806*cdf0e10cSrcweir     lang::Locale aLocale = rAny.get<lang::Locale> ();
807*cdf0e10cSrcweir     return g_strdup_printf( "%s-%s",
808*cdf0e10cSrcweir         rtl::OUStringToOString( aLocale.Language, RTL_TEXTENCODING_ASCII_US).getStr(),
809*cdf0e10cSrcweir         rtl::OUStringToOString( aLocale.Country, RTL_TEXTENCODING_ASCII_US).toAsciiLowerCase().getStr() );
810*cdf0e10cSrcweir }
811*cdf0e10cSrcweir 
812*cdf0e10cSrcweir static bool
813*cdf0e10cSrcweir String2Locale( uno::Any& rAny, const gchar * value )
814*cdf0e10cSrcweir {
815*cdf0e10cSrcweir     bool ret = false;
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir     gchar ** str_array = g_strsplit_set( value, "-.@", -1 );
818*cdf0e10cSrcweir     if( str_array[0] != NULL )
819*cdf0e10cSrcweir     {
820*cdf0e10cSrcweir         ret = true;
821*cdf0e10cSrcweir 
822*cdf0e10cSrcweir         lang::Locale aLocale;
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir         aLocale.Language = rtl::OUString::createFromAscii(str_array[0]);
825*cdf0e10cSrcweir         if( str_array[1] != NULL )
826*cdf0e10cSrcweir         {
827*cdf0e10cSrcweir             gchar * country = g_ascii_strup(str_array[1], -1);
828*cdf0e10cSrcweir             aLocale.Country = rtl::OUString::createFromAscii(country);
829*cdf0e10cSrcweir             g_free(country);
830*cdf0e10cSrcweir         }
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir         rAny = uno::makeAny(aLocale);
833*cdf0e10cSrcweir     }
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir     g_strfreev(str_array);
836*cdf0e10cSrcweir     return ret;
837*cdf0e10cSrcweir }
838*cdf0e10cSrcweir 
839*cdf0e10cSrcweir /*****************************************************************************/
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir // @see http://www.w3.org/TR/2002/WD-css3-fonts-20020802/#font-effect-prop
842*cdf0e10cSrcweir static const gchar * relief[] = { "none", "emboss", "engrave" };
843*cdf0e10cSrcweir static const gchar * outline  = "outline";
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir static gchar *
846*cdf0e10cSrcweir get_font_effect(const uno::Sequence< beans::PropertyValue >& rAttributeList,
847*cdf0e10cSrcweir                 sal_Int32 nContourIndex, sal_Int32 nReliefIndex)
848*cdf0e10cSrcweir {
849*cdf0e10cSrcweir     if( nContourIndex != -1 )
850*cdf0e10cSrcweir     {
851*cdf0e10cSrcweir         if( rAttributeList[nContourIndex].Value.get<sal_Bool>() )
852*cdf0e10cSrcweir             return g_strdup(outline);
853*cdf0e10cSrcweir     }
854*cdf0e10cSrcweir 
855*cdf0e10cSrcweir     if( nReliefIndex != -1 )
856*cdf0e10cSrcweir     {
857*cdf0e10cSrcweir         sal_Int16 n = rAttributeList[nReliefIndex].Value.get<sal_Int16>();
858*cdf0e10cSrcweir         if( n <  3)
859*cdf0e10cSrcweir             return g_strdup(relief[n]);
860*cdf0e10cSrcweir     }
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir     return NULL;
863*cdf0e10cSrcweir }
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir /*****************************************************************************/
866*cdf0e10cSrcweir 
867*cdf0e10cSrcweir // @see http://www.w3.org/TR/REC-CSS2/text.html#lining-striking-props
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir 
870*cdf0e10cSrcweir enum
871*cdf0e10cSrcweir {
872*cdf0e10cSrcweir     DECORATION_NONE = 0,
873*cdf0e10cSrcweir     DECORATION_BLINK,
874*cdf0e10cSrcweir     DECORATION_UNDERLINE,
875*cdf0e10cSrcweir     DECORATION_LINE_THROUGH
876*cdf0e10cSrcweir };
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir 
879*cdf0e10cSrcweir static const gchar * decorations[] = { "none", "blink", "underline", "line-through" };
880*cdf0e10cSrcweir 
881*cdf0e10cSrcweir static gchar *
882*cdf0e10cSrcweir get_text_decoration(const uno::Sequence< beans::PropertyValue >& rAttributeList,
883*cdf0e10cSrcweir                     sal_Int32 nBlinkIndex, sal_Int32 nUnderlineIndex,
884*cdf0e10cSrcweir                     sal_Int16 nStrikeoutIndex)
885*cdf0e10cSrcweir {
886*cdf0e10cSrcweir     gchar * value_list[4] = { NULL, NULL, NULL, NULL };
887*cdf0e10cSrcweir     gint count = 0;
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir     // no property value found
890*cdf0e10cSrcweir     if( ( nBlinkIndex == -1 ) && (nUnderlineIndex == -1 ) && (nStrikeoutIndex == -1))
891*cdf0e10cSrcweir         return NULL;
892*cdf0e10cSrcweir 
893*cdf0e10cSrcweir     if( nBlinkIndex != -1 )
894*cdf0e10cSrcweir     {
895*cdf0e10cSrcweir         if( rAttributeList[nBlinkIndex].Value.get<sal_Bool>() )
896*cdf0e10cSrcweir             value_list[count++] = const_cast <gchar *> (decorations[DECORATION_BLINK]);
897*cdf0e10cSrcweir     }
898*cdf0e10cSrcweir     if( nUnderlineIndex != -1 )
899*cdf0e10cSrcweir     {
900*cdf0e10cSrcweir         sal_Int16 n = rAttributeList[nUnderlineIndex].Value.get<sal_Int16> ();
901*cdf0e10cSrcweir         if( n != awt::FontUnderline::NONE )
902*cdf0e10cSrcweir             value_list[count++] = const_cast <gchar *> (decorations[DECORATION_UNDERLINE]);
903*cdf0e10cSrcweir     }
904*cdf0e10cSrcweir     if( nStrikeoutIndex != -1 )
905*cdf0e10cSrcweir     {
906*cdf0e10cSrcweir         sal_Int16 n = rAttributeList[nStrikeoutIndex].Value.get<sal_Int16> ();
907*cdf0e10cSrcweir         if( n != awt::FontStrikeout::NONE && n != awt::FontStrikeout::DONTKNOW )
908*cdf0e10cSrcweir             value_list[count++] = const_cast <gchar *> (decorations[DECORATION_LINE_THROUGH]);
909*cdf0e10cSrcweir     }
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir     if( count == 0 )
912*cdf0e10cSrcweir         value_list[count++] = const_cast <gchar *> (decorations[DECORATION_NONE]);
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir     return g_strjoinv(" ", value_list);
915*cdf0e10cSrcweir }
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir /*****************************************************************************/
919*cdf0e10cSrcweir 
920*cdf0e10cSrcweir // @see http://www.w3.org/TR/REC-CSS2/text.html#propdef-text-shadow
921*cdf0e10cSrcweir 
922*cdf0e10cSrcweir static const gchar * shadow_values[] = { "none", "black" };
923*cdf0e10cSrcweir 
924*cdf0e10cSrcweir static gchar *
925*cdf0e10cSrcweir Bool2Shadow( const uno::Any& rAny )
926*cdf0e10cSrcweir {
927*cdf0e10cSrcweir     int n = 0;
928*cdf0e10cSrcweir 
929*cdf0e10cSrcweir     if( rAny.get<sal_Bool>() )
930*cdf0e10cSrcweir         n = 1;
931*cdf0e10cSrcweir 
932*cdf0e10cSrcweir     return g_strdup( shadow_values[n] );
933*cdf0e10cSrcweir }
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir /*****************************************************************************/
936*cdf0e10cSrcweir 
937*cdf0e10cSrcweir static gchar *
938*cdf0e10cSrcweir Short2Degree( const uno::Any& rAny )
939*cdf0e10cSrcweir {
940*cdf0e10cSrcweir     float f = rAny.get<sal_Int16>() / 10;
941*cdf0e10cSrcweir     return g_strdup_printf( "%g", f );
942*cdf0e10cSrcweir }
943*cdf0e10cSrcweir 
944*cdf0e10cSrcweir /*****************************************************************************/
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir const gchar * directions[] = { "ltr", "rtl", "rtl", "ltr", "none" };
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir static gchar *
949*cdf0e10cSrcweir WritingMode2Direction( const uno::Any& rAny )
950*cdf0e10cSrcweir {
951*cdf0e10cSrcweir     sal_Int16 n = rAny.get<sal_Int16>();
952*cdf0e10cSrcweir 
953*cdf0e10cSrcweir     if( 0 <= n && n <= text::WritingMode2::PAGE )
954*cdf0e10cSrcweir         return g_strdup(directions[n]);
955*cdf0e10cSrcweir 
956*cdf0e10cSrcweir     return NULL;
957*cdf0e10cSrcweir }
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir // @see http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection
960*cdf0e10cSrcweir 
961*cdf0e10cSrcweir const gchar * writing_modes[] = { "lr-tb", "rl-tb", "tb-rl", "tb-lr", "none" };
962*cdf0e10cSrcweir static gchar *
963*cdf0e10cSrcweir WritingMode2String( const uno::Any& rAny )
964*cdf0e10cSrcweir {
965*cdf0e10cSrcweir     sal_Int16 n = rAny.get<sal_Int16>();
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir     if( 0 <= n && n <= text::WritingMode2::PAGE )
968*cdf0e10cSrcweir         return g_strdup(writing_modes[n]);
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir     return NULL;
971*cdf0e10cSrcweir }
972*cdf0e10cSrcweir 
973*cdf0e10cSrcweir /*****************************************************************************/
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir const char * baseline_values[] = { "baseline", "sub", "super" };
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir // @see http://www.w3.org/TR/REC-CSS2/visudet.html#propdef-vertical-align
978*cdf0e10cSrcweir static gchar *
979*cdf0e10cSrcweir Escapement2VerticalAlign( const uno::Any& rAny )
980*cdf0e10cSrcweir {
981*cdf0e10cSrcweir     sal_Int16 n = rAny.get<sal_Int16>();
982*cdf0e10cSrcweir     gchar * ret = NULL;
983*cdf0e10cSrcweir 
984*cdf0e10cSrcweir     // Values are in %, 101% means "automatic"
985*cdf0e10cSrcweir     if( n == 0 )
986*cdf0e10cSrcweir         ret = g_strdup(baseline_values[0]);
987*cdf0e10cSrcweir     else if( n == 101 )
988*cdf0e10cSrcweir         ret = g_strdup(baseline_values[2]);
989*cdf0e10cSrcweir     else if( n == -101 )
990*cdf0e10cSrcweir         ret = g_strdup(baseline_values[1]);
991*cdf0e10cSrcweir     else
992*cdf0e10cSrcweir         ret = g_strdup_printf( "%d%%", n );
993*cdf0e10cSrcweir 
994*cdf0e10cSrcweir     return ret;
995*cdf0e10cSrcweir }
996*cdf0e10cSrcweir 
997*cdf0e10cSrcweir /*****************************************************************************/
998*cdf0e10cSrcweir 
999*cdf0e10cSrcweir // @see http://www.w3.org/TR/REC-CSS2/visudet.html#propdef-line-height
1000*cdf0e10cSrcweir static gchar *
1001*cdf0e10cSrcweir LineSpacing2LineHeight( const uno::Any& rAny )
1002*cdf0e10cSrcweir {
1003*cdf0e10cSrcweir     style::LineSpacing ls;
1004*cdf0e10cSrcweir     gchar * ret = NULL;
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir     if( rAny >>= ls )
1007*cdf0e10cSrcweir     {
1008*cdf0e10cSrcweir         if( ls.Mode == style::LineSpacingMode::PROP )
1009*cdf0e10cSrcweir             ret = g_strdup_printf( "%d%%", ls.Height );
1010*cdf0e10cSrcweir         else if( ls.Mode == style::LineSpacingMode::FIX )
1011*cdf0e10cSrcweir             ret = g_strdup_printf( "%.3gpt", toPoint(ls.Height) );
1012*cdf0e10cSrcweir     }
1013*cdf0e10cSrcweir 
1014*cdf0e10cSrcweir     return ret;
1015*cdf0e10cSrcweir }
1016*cdf0e10cSrcweir 
1017*cdf0e10cSrcweir /*****************************************************************************/
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir // @see http://www.w3.org/People/howcome/t/970224HTMLERB-CSS/WD-tabs-970117.html
1020*cdf0e10cSrcweir static gchar *
1021*cdf0e10cSrcweir TabStopList2String( const uno::Any& rAny, bool default_tabs )
1022*cdf0e10cSrcweir {
1023*cdf0e10cSrcweir     uno::Sequence< style::TabStop > theTabStops;
1024*cdf0e10cSrcweir     gchar * ret = NULL;
1025*cdf0e10cSrcweir 
1026*cdf0e10cSrcweir     if( rAny >>= theTabStops)
1027*cdf0e10cSrcweir     {
1028*cdf0e10cSrcweir         sal_Int32 indexOfTab = 0;
1029*cdf0e10cSrcweir         sal_Int32 numberOfTabs = theTabStops.getLength();
1030*cdf0e10cSrcweir         sal_Unicode lastFillChar = (sal_Unicode) ' ';
1031*cdf0e10cSrcweir 
1032*cdf0e10cSrcweir         for( ; indexOfTab < numberOfTabs; ++indexOfTab )
1033*cdf0e10cSrcweir         {
1034*cdf0e10cSrcweir             bool is_default_tab = (style::TabAlign_DEFAULT == theTabStops[indexOfTab].Alignment);
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir             if( is_default_tab != default_tabs )
1037*cdf0e10cSrcweir                 continue;
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir             double fValue = theTabStops[indexOfTab].Position;
1040*cdf0e10cSrcweir             fValue = fValue * 0.01;
1041*cdf0e10cSrcweir 
1042*cdf0e10cSrcweir             const gchar * tab_align = "";
1043*cdf0e10cSrcweir             switch( theTabStops[indexOfTab].Alignment )
1044*cdf0e10cSrcweir             {
1045*cdf0e10cSrcweir                 case style::TabAlign_LEFT :
1046*cdf0e10cSrcweir                     tab_align = "left ";
1047*cdf0e10cSrcweir                     break;
1048*cdf0e10cSrcweir                 case style::TabAlign_CENTER :
1049*cdf0e10cSrcweir                     tab_align = "center ";
1050*cdf0e10cSrcweir                     break;
1051*cdf0e10cSrcweir                 case style::TabAlign_RIGHT :
1052*cdf0e10cSrcweir                     tab_align = "right ";
1053*cdf0e10cSrcweir                     break;
1054*cdf0e10cSrcweir                 case style::TabAlign_DECIMAL :
1055*cdf0e10cSrcweir                     tab_align = "decimal ";
1056*cdf0e10cSrcweir                     break;
1057*cdf0e10cSrcweir                 default:
1058*cdf0e10cSrcweir                     break;
1059*cdf0e10cSrcweir             }
1060*cdf0e10cSrcweir 
1061*cdf0e10cSrcweir             const gchar * lead_char = "";
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir             if( theTabStops[indexOfTab].FillChar != lastFillChar )
1064*cdf0e10cSrcweir             {
1065*cdf0e10cSrcweir                 lastFillChar = theTabStops[indexOfTab].FillChar;
1066*cdf0e10cSrcweir                 switch (lastFillChar)
1067*cdf0e10cSrcweir                 {
1068*cdf0e10cSrcweir                     case (sal_Unicode) ' ':
1069*cdf0e10cSrcweir                         lead_char = "blank ";
1070*cdf0e10cSrcweir                         break;
1071*cdf0e10cSrcweir 
1072*cdf0e10cSrcweir                     case (sal_Unicode) '.':
1073*cdf0e10cSrcweir                         lead_char = "dotted ";
1074*cdf0e10cSrcweir                         break;
1075*cdf0e10cSrcweir 
1076*cdf0e10cSrcweir                     case (sal_Unicode) '-':
1077*cdf0e10cSrcweir                         lead_char = "dashed ";
1078*cdf0e10cSrcweir                         break;
1079*cdf0e10cSrcweir 
1080*cdf0e10cSrcweir                     case (sal_Unicode) '_':
1081*cdf0e10cSrcweir                         lead_char = "lined ";
1082*cdf0e10cSrcweir                         break;
1083*cdf0e10cSrcweir 
1084*cdf0e10cSrcweir                     default:
1085*cdf0e10cSrcweir                         lead_char = "custom ";
1086*cdf0e10cSrcweir                         break;
1087*cdf0e10cSrcweir                 }
1088*cdf0e10cSrcweir             }
1089*cdf0e10cSrcweir 
1090*cdf0e10cSrcweir             gchar * tab_str = g_strdup_printf( "%s%s%gmm", lead_char, tab_align, fValue );
1091*cdf0e10cSrcweir 
1092*cdf0e10cSrcweir             if( ret )
1093*cdf0e10cSrcweir             {
1094*cdf0e10cSrcweir                 gchar * old_tab_str = ret;
1095*cdf0e10cSrcweir                 ret = g_strconcat(old_tab_str, " ", tab_str, NULL /* terminated */);
1096*cdf0e10cSrcweir                 g_free( old_tab_str );
1097*cdf0e10cSrcweir             }
1098*cdf0e10cSrcweir             else
1099*cdf0e10cSrcweir                 ret = tab_str;
1100*cdf0e10cSrcweir         }
1101*cdf0e10cSrcweir     }
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir     return ret;
1104*cdf0e10cSrcweir }
1105*cdf0e10cSrcweir 
1106*cdf0e10cSrcweir static gchar *
1107*cdf0e10cSrcweir TabStops2String( const uno::Any& rAny )
1108*cdf0e10cSrcweir {
1109*cdf0e10cSrcweir     return TabStopList2String(rAny, false);
1110*cdf0e10cSrcweir }
1111*cdf0e10cSrcweir 
1112*cdf0e10cSrcweir static gchar *
1113*cdf0e10cSrcweir DefaultTabStops2String( const uno::Any& rAny )
1114*cdf0e10cSrcweir {
1115*cdf0e10cSrcweir     return TabStopList2String(rAny, true);
1116*cdf0e10cSrcweir }
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir /*****************************************************************************/
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir extern "C" int
1121*cdf0e10cSrcweir attr_compare(const void *p1,const void *p2)
1122*cdf0e10cSrcweir {
1123*cdf0e10cSrcweir     const rtl_uString * pustr = (const rtl_uString *) p1;
1124*cdf0e10cSrcweir     const char * pc = *((const char **) p2);
1125*cdf0e10cSrcweir 
1126*cdf0e10cSrcweir     return rtl_ustr_ascii_compare_WithLength(pustr->buffer, pustr->length, pc);
1127*cdf0e10cSrcweir }
1128*cdf0e10cSrcweir 
1129*cdf0e10cSrcweir static void
1130*cdf0e10cSrcweir find_exported_attributes( sal_Int32 *pArray,
1131*cdf0e10cSrcweir     const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rAttributeList )
1132*cdf0e10cSrcweir {
1133*cdf0e10cSrcweir     for( sal_Int32 i = 0; i < rAttributeList.getLength(); i++ )
1134*cdf0e10cSrcweir     {
1135*cdf0e10cSrcweir         const char ** pAttr = (const char **) bsearch(rAttributeList[i].Name.pData,
1136*cdf0e10cSrcweir             ExportedTextAttributes, TEXT_ATTRIBUTE_LAST, sizeof(const char *),
1137*cdf0e10cSrcweir             attr_compare);
1138*cdf0e10cSrcweir 
1139*cdf0e10cSrcweir         if( pAttr )
1140*cdf0e10cSrcweir         {
1141*cdf0e10cSrcweir             sal_Int32 nIndex = pAttr - ExportedTextAttributes;
1142*cdf0e10cSrcweir             pArray[nIndex] = i;
1143*cdf0e10cSrcweir         }
1144*cdf0e10cSrcweir     }
1145*cdf0e10cSrcweir }
1146*cdf0e10cSrcweir 
1147*cdf0e10cSrcweir /*****************************************************************************/
1148*cdf0e10cSrcweir 
1149*cdf0e10cSrcweir static AtkAttributeSet*
1150*cdf0e10cSrcweir attribute_set_prepend( AtkAttributeSet* attribute_set,
1151*cdf0e10cSrcweir                        AtkTextAttribute attribute,
1152*cdf0e10cSrcweir                        gchar * value )
1153*cdf0e10cSrcweir {
1154*cdf0e10cSrcweir     if( value )
1155*cdf0e10cSrcweir     {
1156*cdf0e10cSrcweir         AtkAttribute *at = (AtkAttribute *) g_malloc( sizeof (AtkAttribute) );
1157*cdf0e10cSrcweir         at->name  = g_strdup( atk_text_attribute_get_name( attribute ) );
1158*cdf0e10cSrcweir         at->value = value;
1159*cdf0e10cSrcweir 
1160*cdf0e10cSrcweir         return g_slist_prepend(attribute_set, at);
1161*cdf0e10cSrcweir     }
1162*cdf0e10cSrcweir 
1163*cdf0e10cSrcweir     return attribute_set;
1164*cdf0e10cSrcweir }
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir /*****************************************************************************/
1167*cdf0e10cSrcweir 
1168*cdf0e10cSrcweir AtkAttributeSet*
1169*cdf0e10cSrcweir attribute_set_new_from_property_values(
1170*cdf0e10cSrcweir     const uno::Sequence< beans::PropertyValue >& rAttributeList,
1171*cdf0e10cSrcweir     bool run_attributes_only,
1172*cdf0e10cSrcweir     AtkText *text)
1173*cdf0e10cSrcweir {
1174*cdf0e10cSrcweir     AtkAttributeSet* attribute_set = NULL;
1175*cdf0e10cSrcweir 
1176*cdf0e10cSrcweir     sal_Int32 aIndexList[TEXT_ATTRIBUTE_LAST] = { -1 };
1177*cdf0e10cSrcweir 
1178*cdf0e10cSrcweir     // Initialize index array with -1
1179*cdf0e10cSrcweir     for( sal_Int32 attr = 0; attr < TEXT_ATTRIBUTE_LAST; ++attr )
1180*cdf0e10cSrcweir         aIndexList[attr] = -1;
1181*cdf0e10cSrcweir 
1182*cdf0e10cSrcweir     find_exported_attributes(aIndexList, rAttributeList);
1183*cdf0e10cSrcweir 
1184*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_BG_COLOR,
1185*cdf0e10cSrcweir         get_color_value(rAttributeList, aIndexList, TEXT_ATTRIBUTE_BACKGROUND_COLOR, run_attributes_only ? NULL : text ) );
1186*cdf0e10cSrcweir 
1187*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_FG_COLOR,
1188*cdf0e10cSrcweir         get_color_value(rAttributeList, aIndexList, TEXT_ATTRIBUTE_FOREGROUND_COLOR, run_attributes_only ? NULL : text) );
1189*cdf0e10cSrcweir 
1190*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_INVISIBLE,
1191*cdf0e10cSrcweir         get_bool_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_HIDDEN]));
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_UNDERLINE,
1194*cdf0e10cSrcweir         get_underline_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_UNDERLINE]));
1195*cdf0e10cSrcweir 
1196*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STRIKETHROUGH,
1197*cdf0e10cSrcweir         get_strikethrough_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_STRIKETHROUGH]));
1198*cdf0e10cSrcweir 
1199*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_SIZE,
1200*cdf0e10cSrcweir         get_height_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_HEIGHT]));
1201*cdf0e10cSrcweir 
1202*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_WEIGHT,
1203*cdf0e10cSrcweir         get_weight_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WEIGHT]));
1204*cdf0e10cSrcweir 
1205*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_FAMILY_NAME,
1206*cdf0e10cSrcweir         get_string_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_FONT_NAME]));
1207*cdf0e10cSrcweir 
1208*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_VARIANT,
1209*cdf0e10cSrcweir         get_variant_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CASEMAP]));
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STYLE,
1212*cdf0e10cSrcweir         get_style_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_POSTURE]));
1213*cdf0e10cSrcweir 
1214*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_SCALE,
1215*cdf0e10cSrcweir         get_scale_width(rAttributeList, aIndexList[TEXT_ATTRIBUTE_SCALE]));
1216*cdf0e10cSrcweir 
1217*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_LANGUAGE,
1218*cdf0e10cSrcweir         get_language_string(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LOCALE]));
1219*cdf0e10cSrcweir 
1220*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_DIRECTION,
1221*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WRITING_MODE], WritingMode2Direction));
1222*cdf0e10cSrcweir 
1223*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_STRETCH,
1224*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_KERNING], Kerning2Stretch));
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_font_effect )
1227*cdf0e10cSrcweir         atk_text_attribute_font_effect = atk_text_attribute_register("font-effect");
1228*cdf0e10cSrcweir 
1229*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_font_effect,
1230*cdf0e10cSrcweir         get_font_effect(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CONTOURED], aIndexList[TEXT_ATTRIBUTE_RELIEF]));
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_decoration )
1233*cdf0e10cSrcweir         atk_text_attribute_decoration = atk_text_attribute_register("text-decoration");
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_decoration,
1236*cdf0e10cSrcweir         get_text_decoration(rAttributeList, aIndexList[TEXT_ATTRIBUTE_BLINKING],
1237*cdf0e10cSrcweir             aIndexList[TEXT_ATTRIBUTE_UNDERLINE], aIndexList[TEXT_ATTRIBUTE_STRIKETHROUGH]));
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_rotation )
1240*cdf0e10cSrcweir         atk_text_attribute_rotation = atk_text_attribute_register("text-rotation");
1241*cdf0e10cSrcweir 
1242*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_rotation,
1243*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_ROTATION], Short2Degree));
1244*cdf0e10cSrcweir 
1245*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_shadow )
1246*cdf0e10cSrcweir         atk_text_attribute_shadow = atk_text_attribute_register("text-shadow");
1247*cdf0e10cSrcweir 
1248*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_shadow,
1249*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_SHADOWED], Bool2Shadow));
1250*cdf0e10cSrcweir 
1251*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_writing_mode )
1252*cdf0e10cSrcweir         atk_text_attribute_writing_mode = atk_text_attribute_register("writing-mode");
1253*cdf0e10cSrcweir 
1254*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_writing_mode,
1255*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_WRITING_MODE], WritingMode2String));
1256*cdf0e10cSrcweir 
1257*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_vertical_align )
1258*cdf0e10cSrcweir         atk_text_attribute_vertical_align = atk_text_attribute_register("vertical-align");
1259*cdf0e10cSrcweir 
1260*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_vertical_align,
1261*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_CHAR_ESCAPEMENT], Escapement2VerticalAlign));
1262*cdf0e10cSrcweir 
1263*cdf0e10cSrcweir     if( run_attributes_only )
1264*cdf0e10cSrcweir         return attribute_set;
1265*cdf0e10cSrcweir 
1266*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_LEFT_MARGIN,
1267*cdf0e10cSrcweir         get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LEFT_MARGIN]));
1268*cdf0e10cSrcweir 
1269*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_RIGHT_MARGIN,
1270*cdf0e10cSrcweir         get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_RIGHT_MARGIN]));
1271*cdf0e10cSrcweir 
1272*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_INDENT,
1273*cdf0e10cSrcweir         get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_FIRST_LINE_INDENT]));
1274*cdf0e10cSrcweir 
1275*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES,
1276*cdf0e10cSrcweir         get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TOP_MARGIN]));
1277*cdf0e10cSrcweir 
1278*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES,
1279*cdf0e10cSrcweir         get_cmm_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_BOTTOM_MARGIN]));
1280*cdf0e10cSrcweir 
1281*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, ATK_TEXT_ATTR_JUSTIFICATION,
1282*cdf0e10cSrcweir         get_justification_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_JUSTIFICATION]));
1283*cdf0e10cSrcweir 
1284*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_paragraph_style )
1285*cdf0e10cSrcweir         atk_text_attribute_paragraph_style = atk_text_attribute_register("paragraph-style");
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_paragraph_style,
1288*cdf0e10cSrcweir         get_string_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_STYLE_NAME]));
1289*cdf0e10cSrcweir 
1290*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_line_height )
1291*cdf0e10cSrcweir         atk_text_attribute_line_height = atk_text_attribute_register("line-height");
1292*cdf0e10cSrcweir 
1293*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_line_height,
1294*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_LINE_SPACING], LineSpacing2LineHeight));
1295*cdf0e10cSrcweir 
1296*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tab_interval )
1297*cdf0e10cSrcweir         atk_text_attribute_tab_interval = atk_text_attribute_register("tab-interval");
1298*cdf0e10cSrcweir 
1299*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_tab_interval,
1300*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TAB_STOPS], DefaultTabStops2String));
1301*cdf0e10cSrcweir 
1302*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tab_stops )
1303*cdf0e10cSrcweir         atk_text_attribute_tab_stops = atk_text_attribute_register("tab-stops");
1304*cdf0e10cSrcweir 
1305*cdf0e10cSrcweir     attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_tab_stops,
1306*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TAB_STOPS], TabStops2String));
1307*cdf0e10cSrcweir 
1308*cdf0e10cSrcweir     // --> OD 2010-03-05 #i92233#
1309*cdf0e10cSrcweir     if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_mm_to_pixel_ratio )
1310*cdf0e10cSrcweir         atk_text_attribute_mm_to_pixel_ratio = atk_text_attribute_register("mm-to-pixel-ratio");
1311*cdf0e10cSrcweir 
1312*cdf0e10cSrcweir     attribute_set = attribute_set_prepend( attribute_set, atk_text_attribute_mm_to_pixel_ratio,
1313*cdf0e10cSrcweir         get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO], Float2String));
1314*cdf0e10cSrcweir     // <--
1315*cdf0e10cSrcweir 
1316*cdf0e10cSrcweir     return attribute_set;
1317*cdf0e10cSrcweir }
1318*cdf0e10cSrcweir 
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir AtkAttributeSet* attribute_set_prepend_misspelled( AtkAttributeSet* attribute_set )
1321*cdf0e10cSrcweir {
1322*cdf0e10cSrcweir 	if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_misspelled )
1323*cdf0e10cSrcweir 		atk_text_attribute_misspelled = atk_text_attribute_register( "text-spelling" );
1324*cdf0e10cSrcweir 
1325*cdf0e10cSrcweir 	attribute_set = attribute_set_prepend( attribute_set, atk_text_attribute_misspelled,
1326*cdf0e10cSrcweir 		g_strdup_printf( "misspelled" ) );
1327*cdf0e10cSrcweir 
1328*cdf0e10cSrcweir 	return attribute_set;
1329*cdf0e10cSrcweir }
1330*cdf0e10cSrcweir 
1331*cdf0e10cSrcweir // --> OD 2010-03-01 #i92232#
1332*cdf0e10cSrcweir AtkAttributeSet* attribute_set_prepend_tracked_change_insertion( AtkAttributeSet* attribute_set )
1333*cdf0e10cSrcweir {
1334*cdf0e10cSrcweir     if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change )
1335*cdf0e10cSrcweir     {
1336*cdf0e10cSrcweir         atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" );
1337*cdf0e10cSrcweir     }
1338*cdf0e10cSrcweir 
1339*cdf0e10cSrcweir     attribute_set = attribute_set_prepend( attribute_set,
1340*cdf0e10cSrcweir                                            atk_text_attribute_tracked_change,
1341*cdf0e10cSrcweir                                            g_strdup_printf( "insertion" ) );
1342*cdf0e10cSrcweir 
1343*cdf0e10cSrcweir     return attribute_set;
1344*cdf0e10cSrcweir }
1345*cdf0e10cSrcweir 
1346*cdf0e10cSrcweir AtkAttributeSet* attribute_set_prepend_tracked_change_deletion( AtkAttributeSet* attribute_set )
1347*cdf0e10cSrcweir {
1348*cdf0e10cSrcweir     if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change )
1349*cdf0e10cSrcweir     {
1350*cdf0e10cSrcweir         atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" );
1351*cdf0e10cSrcweir     }
1352*cdf0e10cSrcweir 
1353*cdf0e10cSrcweir     attribute_set = attribute_set_prepend( attribute_set,
1354*cdf0e10cSrcweir                                            atk_text_attribute_tracked_change,
1355*cdf0e10cSrcweir                                            g_strdup_printf( "deletion" ) );
1356*cdf0e10cSrcweir 
1357*cdf0e10cSrcweir     return attribute_set;
1358*cdf0e10cSrcweir }
1359*cdf0e10cSrcweir 
1360*cdf0e10cSrcweir AtkAttributeSet* attribute_set_prepend_tracked_change_formatchange( AtkAttributeSet* attribute_set )
1361*cdf0e10cSrcweir {
1362*cdf0e10cSrcweir     if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change )
1363*cdf0e10cSrcweir     {
1364*cdf0e10cSrcweir         atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" );
1365*cdf0e10cSrcweir     }
1366*cdf0e10cSrcweir 
1367*cdf0e10cSrcweir     attribute_set = attribute_set_prepend( attribute_set,
1368*cdf0e10cSrcweir                                            atk_text_attribute_tracked_change,
1369*cdf0e10cSrcweir                                            g_strdup_printf( "attribute-change" ) );
1370*cdf0e10cSrcweir 
1371*cdf0e10cSrcweir     return attribute_set;
1372*cdf0e10cSrcweir }
1373*cdf0e10cSrcweir // <--
1374*cdf0e10cSrcweir 
1375*cdf0e10cSrcweir /*****************************************************************************/
1376*cdf0e10cSrcweir 
1377*cdf0e10cSrcweir struct AtkTextAttrMapping
1378*cdf0e10cSrcweir {
1379*cdf0e10cSrcweir     const char *          name;
1380*cdf0e10cSrcweir     TextPropertyValueFunc toPropertyValue;
1381*cdf0e10cSrcweir };
1382*cdf0e10cSrcweir 
1383*cdf0e10cSrcweir const AtkTextAttrMapping g_TextAttrMap[] =
1384*cdf0e10cSrcweir {
1385*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_INVALID = 0
1386*cdf0e10cSrcweir     { "ParaLeftMargin", UnitString2CMM },       // ATK_TEXT_ATTR_LEFT_MARGIN
1387*cdf0e10cSrcweir     { "ParaRightMargin", UnitString2CMM },      // ATK_TEXT_ATTR_RIGHT_MARGIN
1388*cdf0e10cSrcweir     { "ParaFirstLineIndent", UnitString2CMM },  // ATK_TEXT_ATTR_INDENT
1389*cdf0e10cSrcweir     { "CharHidden", String2Bool },              // ATK_TEXT_ATTR_INVISIBLE
1390*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_EDITABLE
1391*cdf0e10cSrcweir     { "ParaTopMargin", UnitString2CMM },        // ATK_TEXT_ATTR_PIXELS_ABOVE_LINES
1392*cdf0e10cSrcweir     { "ParaBottomMargin", UnitString2CMM },     // ATK_TEXT_ATTR_PIXELS_BELOW_LINES
1393*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP
1394*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_BG_FULL_HEIGHT
1395*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_RISE
1396*cdf0e10cSrcweir     { "CharUnderline", String2Underline },      // ATK_TEXT_ATTR_UNDERLINE
1397*cdf0e10cSrcweir     { "CharStrikeout", String2Strikeout },      // ATK_TEXT_ATTR_STRIKETHROUGH
1398*cdf0e10cSrcweir     { "CharHeight", String2Float },             // ATK_TEXT_ATTR_SIZE
1399*cdf0e10cSrcweir     { "CharScaleWidth", String2Scale },         // ATK_TEXT_ATTR_SCALE
1400*cdf0e10cSrcweir     { "CharWeight", String2Weight },            // ATK_TEXT_ATTR_WEIGHT
1401*cdf0e10cSrcweir     { "CharLocale", String2Locale },            // ATK_TEXT_ATTR_LANGUAGE
1402*cdf0e10cSrcweir     { "CharFontName",  SetString },             // ATK_TEXT_ATTR_FAMILY_NAME
1403*cdf0e10cSrcweir     { "CharBackColor", String2Color },          // ATK_TEXT_ATTR_BG_COLOR
1404*cdf0e10cSrcweir     { "CharColor", String2Color },              // ATK_TEXT_ATTR_FG_COLOR
1405*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_BG_STIPPLE
1406*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_FG_STIPPLE
1407*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_WRAP_MODE
1408*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_DIRECTION
1409*cdf0e10cSrcweir     { "ParaAdjust", Justification2Adjust },     // ATK_TEXT_ATTR_JUSTIFICATION
1410*cdf0e10cSrcweir     { "", InvalidValue },                       // ATK_TEXT_ATTR_STRETCH
1411*cdf0e10cSrcweir     { "CharCaseMap", String2CaseMap },          // ATK_TEXT_ATTR_VARIANT
1412*cdf0e10cSrcweir     { "CharPosture", Style2FontSlant }          // ATK_TEXT_ATTR_STYLE
1413*cdf0e10cSrcweir };
1414*cdf0e10cSrcweir 
1415*cdf0e10cSrcweir static const sal_Int32 g_TextAttrMapSize = sizeof( g_TextAttrMap ) / sizeof( AtkTextAttrMapping );
1416*cdf0e10cSrcweir 
1417*cdf0e10cSrcweir /*****************************************************************************/
1418*cdf0e10cSrcweir 
1419*cdf0e10cSrcweir bool
1420*cdf0e10cSrcweir attribute_set_map_to_property_values(
1421*cdf0e10cSrcweir     AtkAttributeSet* attribute_set,
1422*cdf0e10cSrcweir     uno::Sequence< beans::PropertyValue >& rValueList )
1423*cdf0e10cSrcweir {
1424*cdf0e10cSrcweir     // Ensure enough space ..
1425*cdf0e10cSrcweir     uno::Sequence< beans::PropertyValue > aAttributeList (g_TextAttrMapSize);
1426*cdf0e10cSrcweir 
1427*cdf0e10cSrcweir     sal_Int32 nIndex = 0;
1428*cdf0e10cSrcweir     for( GSList * item = attribute_set; item != NULL; item = g_slist_next( item ) )
1429*cdf0e10cSrcweir     {
1430*cdf0e10cSrcweir         AtkAttribute* attribute = (AtkAttribute *) item;
1431*cdf0e10cSrcweir 
1432*cdf0e10cSrcweir         AtkTextAttribute text_attr = atk_text_attribute_for_name( attribute->name );
1433*cdf0e10cSrcweir         if( text_attr < g_TextAttrMapSize )
1434*cdf0e10cSrcweir         {
1435*cdf0e10cSrcweir             if( g_TextAttrMap[text_attr].name[0] != '\0' )
1436*cdf0e10cSrcweir             {
1437*cdf0e10cSrcweir                 if( ! g_TextAttrMap[text_attr].toPropertyValue( aAttributeList[nIndex].Value, attribute->value) )
1438*cdf0e10cSrcweir                     return false;
1439*cdf0e10cSrcweir 
1440*cdf0e10cSrcweir                 aAttributeList[nIndex].Name = rtl::OUString::createFromAscii( g_TextAttrMap[text_attr].name );
1441*cdf0e10cSrcweir                 aAttributeList[nIndex].State = beans::PropertyState_DIRECT_VALUE;
1442*cdf0e10cSrcweir                 ++nIndex;
1443*cdf0e10cSrcweir             }
1444*cdf0e10cSrcweir         }
1445*cdf0e10cSrcweir         else
1446*cdf0e10cSrcweir         {
1447*cdf0e10cSrcweir             // Unsupported text attribute
1448*cdf0e10cSrcweir             return false;
1449*cdf0e10cSrcweir         }
1450*cdf0e10cSrcweir     }
1451*cdf0e10cSrcweir 
1452*cdf0e10cSrcweir     aAttributeList.realloc( nIndex );
1453*cdf0e10cSrcweir     rValueList = aAttributeList;
1454*cdf0e10cSrcweir     return true;
1455*cdf0e10cSrcweir }
1456*cdf0e10cSrcweir 
1457