LCOV - code coverage report
Current view: top level - libreoffice/vcl/unx/gtk/a11y - atktextattributes.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 470 0.0 %
Date: 2012-12-27 Functions: 0 51 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10