LCOV - code coverage report
Current view: top level - sc/source/filter/oox - stylesbuffer.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1030 1611 63.9 %
Date: 2014-11-03 Functions: 142 202 70.3 %
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             : #include "stylesbuffer.hxx"
      21             : 
      22             : #include <com/sun/star/awt/FontDescriptor.hpp>
      23             : #include <com/sun/star/awt/FontFamily.hpp>
      24             : #include <com/sun/star/awt/FontPitch.hpp>
      25             : #include <com/sun/star/awt/FontSlant.hpp>
      26             : #include <com/sun/star/awt/FontStrikeout.hpp>
      27             : #include <com/sun/star/awt/FontType.hpp>
      28             : #include <com/sun/star/awt/FontWeight.hpp>
      29             : #include <com/sun/star/awt/FontUnderline.hpp>
      30             : #include <com/sun/star/awt/XDevice.hpp>
      31             : #include <com/sun/star/awt/XFont2.hpp>
      32             : #include <com/sun/star/container/XIndexAccess.hpp>
      33             : #include <com/sun/star/container/XNameAccess.hpp>
      34             : #include <com/sun/star/style/XStyle.hpp>
      35             : #include <com/sun/star/text/WritingMode2.hpp>
      36             : #include <com/sun/star/text/XText.hpp>
      37             : #include <com/sun/star/table/BorderLineStyle.hpp>
      38             : #include <com/sun/star/table/CellVertJustify2.hpp>
      39             : #include <com/sun/star/table/CellJustifyMethod.hpp>
      40             : #include <com/sun/star/table/TableBorder.hpp>
      41             : #include <editeng/justifyitem.hxx>
      42             : #include <editeng/frmdiritem.hxx>
      43             : #include <editeng/fontitem.hxx>
      44             : #include <editeng/postitem.hxx>
      45             : #include <editeng/fhgtitem.hxx>
      46             : #include <editeng/wghtitem.hxx>
      47             : #include <editeng/udlnitem.hxx>
      48             : #include <editeng/colritem.hxx>
      49             : #include <editeng/crossedoutitem.hxx>
      50             : #include <editeng/contouritem.hxx>
      51             : #include <editeng/escapementitem.hxx>
      52             : #include <editeng/shdditem.hxx>
      53             : #include <editeng/eeitem.hxx>
      54             : #include <editeng/boxitem.hxx>
      55             : #include <editeng/lineitem.hxx>
      56             : #include <editeng/brushitem.hxx>
      57             : #include <svx/rotmodit.hxx>
      58             : #include <tools/fontenum.hxx>
      59             : #include <toolkit/helper/vclunohelper.hxx>
      60             : #include <rtl/tencinfo.h>
      61             : #include <rtl/ustrbuf.hxx>
      62             : #include <oox/core/filterbase.hxx>
      63             : #include <oox/helper/attributelist.hxx>
      64             : #include <oox/helper/containerhelper.hxx>
      65             : #include <oox/helper/propertymap.hxx>
      66             : #include <oox/helper/propertyset.hxx>
      67             : #include "biffinputstream.hxx"
      68             : #include "condformatbuffer.hxx"
      69             : #include "excelhandlers.hxx"
      70             : #include "themebuffer.hxx"
      71             : #include "unitconverter.hxx"
      72             : #include "document.hxx"
      73             : #include "stlpool.hxx"
      74             : #include "docpool.hxx"
      75             : #include "ftools.hxx"
      76             : #include "scitems.hxx"
      77             : #include "attrib.hxx"
      78             : #include "globstr.hrc"
      79             : #include "xlconst.hxx"
      80             : #include <documentimport.hxx>
      81             : #include <numformat.hxx>
      82             : 
      83             : using ::com::sun::star::table::BorderLine2;
      84             : namespace oox {
      85             : namespace xls {
      86             : 
      87             : using namespace com::sun::star;
      88             : using namespace ::com::sun::star::awt;
      89             : using namespace ::com::sun::star::container;
      90             : using namespace ::com::sun::star::style;
      91             : using namespace ::com::sun::star::table;
      92             : using namespace ::com::sun::star::text;
      93             : using namespace ::com::sun::star::uno;
      94             : 
      95             : using ::oox::core::FilterBase;
      96             : 
      97             : namespace {
      98             : 
      99             : // OOXML constants ------------------------------------------------------------
     100             : 
     101             : // OOXML predefined color indexes (also used in BIFF3-BIFF8)
     102             : const sal_Int32 OOX_COLOR_USEROFFSET        = 0;        /// First user defined color in palette (OOXML/BIFF12).
     103             : const sal_Int32 BIFF_COLOR_USEROFFSET       = 8;        /// First user defined color in palette (BIFF3-BIFF8).
     104             : 
     105             : // OOXML font family (also used in BIFF)
     106             : const sal_Int32 OOX_FONTFAMILY_NONE         = 0;
     107             : const sal_Int32 OOX_FONTFAMILY_ROMAN        = 1;
     108             : const sal_Int32 OOX_FONTFAMILY_SWISS        = 2;
     109             : const sal_Int32 OOX_FONTFAMILY_MODERN       = 3;
     110             : const sal_Int32 OOX_FONTFAMILY_SCRIPT       = 4;
     111             : const sal_Int32 OOX_FONTFAMILY_DECORATIVE   = 5;
     112             : 
     113             : // OOXML cell text direction (also used in BIFF)
     114             : const sal_Int32 OOX_XF_TEXTDIR_CONTEXT      = 0;
     115             : const sal_Int32 OOX_XF_TEXTDIR_LTR          = 1;
     116             : const sal_Int32 OOX_XF_TEXTDIR_RTL          = 2;
     117             : 
     118             : // OOXML cell rotation (also used in BIFF)
     119             : const sal_Int32 OOX_XF_ROTATION_NONE        = 0;
     120             : const sal_Int32 OOX_XF_ROTATION_STACKED     = 255;
     121             : 
     122             : // OOXML cell indentation
     123             : const sal_Int32 OOX_XF_INDENT_NONE          = 0;
     124             : 
     125             : // OOXML built-in cell styles (also used in BIFF)
     126             : const sal_Int32 OOX_STYLE_NORMAL            = 0;        /// Default cell style.
     127             : const sal_Int32 OOX_STYLE_ROWLEVEL          = 1;        /// RowLevel_x cell style.
     128             : const sal_Int32 OOX_STYLE_COLLEVEL          = 2;        /// ColLevel_x cell style.
     129             : 
     130             : // BIFF12 constants -----------------------------------------------------------
     131             : 
     132             : // BIFF12 color types
     133             : const sal_uInt8 BIFF12_COLOR_AUTO           = 0;
     134             : const sal_uInt8 BIFF12_COLOR_INDEXED        = 1;
     135             : const sal_uInt8 BIFF12_COLOR_RGB            = 2;
     136             : const sal_uInt8 BIFF12_COLOR_THEME          = 3;
     137             : 
     138             : // BIFF12 diagonal borders
     139             : const sal_uInt8 BIFF12_BORDER_DIAG_TLBR     = 0x01;     /// Top-left to bottom-right.
     140             : const sal_uInt8 BIFF12_BORDER_DIAG_BLTR     = 0x02;     /// Bottom-left to top-right.
     141             : 
     142             : // BIFF12 gradient fill
     143             : const sal_Int32 BIFF12_FILL_GRADIENT        = 40;
     144             : 
     145             : // BIFF12 XF flags
     146             : const sal_uInt32 BIFF12_XF_WRAPTEXT         = 0x00400000;
     147             : const sal_uInt32 BIFF12_XF_JUSTLASTLINE     = 0x00800000;
     148             : const sal_uInt32 BIFF12_XF_SHRINK           = 0x01000000;
     149             : const sal_uInt32 BIFF12_XF_LOCKED           = 0x10000000;
     150             : const sal_uInt32 BIFF12_XF_HIDDEN           = 0x20000000;
     151             : 
     152             : // BIFF12 XF attribute used flags
     153             : const sal_uInt16 BIFF12_XF_NUMFMT_USED      = 0x0001;
     154             : const sal_uInt16 BIFF12_XF_FONT_USED        = 0x0002;
     155             : const sal_uInt16 BIFF12_XF_ALIGN_USED       = 0x0004;
     156             : const sal_uInt16 BIFF12_XF_BORDER_USED      = 0x0008;
     157             : const sal_uInt16 BIFF12_XF_AREA_USED        = 0x0010;
     158             : const sal_uInt16 BIFF12_XF_PROT_USED        = 0x0020;
     159             : 
     160             : // BIFF12 DXF constants
     161             : const sal_uInt16 BIFF12_DXF_FILL_PATTERN    = 0;
     162             : const sal_uInt16 BIFF12_DXF_FILL_FGCOLOR    = 1;
     163             : const sal_uInt16 BIFF12_DXF_FILL_BGCOLOR    = 2;
     164             : const sal_uInt16 BIFF12_DXF_FILL_GRADIENT   = 3;
     165             : const sal_uInt16 BIFF12_DXF_FILL_STOP       = 4;
     166             : const sal_uInt16 BIFF12_DXF_FONT_COLOR      = 5;
     167             : const sal_uInt16 BIFF12_DXF_BORDER_TOP      = 6;
     168             : const sal_uInt16 BIFF12_DXF_BORDER_BOTTOM   = 7;
     169             : const sal_uInt16 BIFF12_DXF_BORDER_LEFT     = 8;
     170             : const sal_uInt16 BIFF12_DXF_BORDER_RIGHT    = 9;
     171             : const sal_uInt16 BIFF12_DXF_FONT_NAME       = 24;
     172             : const sal_uInt16 BIFF12_DXF_FONT_WEIGHT     = 25;
     173             : const sal_uInt16 BIFF12_DXF_FONT_UNDERLINE  = 26;
     174             : const sal_uInt16 BIFF12_DXF_FONT_ESCAPEMENT = 27;
     175             : const sal_uInt16 BIFF12_DXF_FONT_ITALIC     = 28;
     176             : const sal_uInt16 BIFF12_DXF_FONT_STRIKE     = 29;
     177             : const sal_uInt16 BIFF12_DXF_FONT_OUTLINE    = 30;
     178             : const sal_uInt16 BIFF12_DXF_FONT_SHADOW     = 31;
     179             : const sal_uInt16 BIFF12_DXF_FONT_HEIGHT     = 36;
     180             : const sal_uInt16 BIFF12_DXF_FONT_SCHEME     = 37;
     181             : const sal_uInt16 BIFF12_DXF_NUMFMT_CODE     = 38;
     182             : const sal_uInt16 BIFF12_DXF_NUMFMT_ID       = 41;
     183             : 
     184             : // BIFF12 CELLSTYLE flags
     185             : const sal_uInt16 BIFF12_CELLSTYLE_BUILTIN   = 0x0001;
     186             : const sal_uInt16 BIFF12_CELLSTYLE_HIDDEN    = 0x0002;
     187             : const sal_uInt16 BIFF12_CELLSTYLE_CUSTOM    = 0x0004;
     188             : 
     189             : // BIFF constants -------------------------------------------------------------
     190             : 
     191             : // BIFF font flags, also used in BIFF12
     192             : const sal_uInt16 BIFF_FONTFLAG_ITALIC       = 0x0002;
     193             : const sal_uInt16 BIFF_FONTFLAG_STRIKEOUT    = 0x0008;
     194             : const sal_uInt16 BIFF_FONTFLAG_OUTLINE      = 0x0010;
     195             : const sal_uInt16 BIFF_FONTFLAG_SHADOW       = 0x0020;
     196             : 
     197             : // BIFF font weight
     198             : const sal_uInt16 BIFF_FONTWEIGHT_BOLD       = 450;
     199             : 
     200             : // BIFF font underline, also used in BIFF12
     201             : const sal_uInt8 BIFF_FONTUNDERL_NONE        = 0;
     202             : const sal_uInt8 BIFF_FONTUNDERL_SINGLE      = 1;
     203             : const sal_uInt8 BIFF_FONTUNDERL_DOUBLE      = 2;
     204             : const sal_uInt8 BIFF_FONTUNDERL_SINGLE_ACC  = 33;
     205             : const sal_uInt8 BIFF_FONTUNDERL_DOUBLE_ACC  = 34;
     206             : 
     207           0 : sal_Int32 lclReadRgbColor( BinaryInputStream& rStrm )
     208             : {
     209             :     sal_uInt8 nR, nG, nB, nA;
     210           0 :     rStrm >> nR >> nG >> nB >> nA;
     211           0 :     sal_Int32 nValue = nA;
     212           0 :     nValue <<= 8;
     213           0 :     nValue |= nR;
     214           0 :     nValue <<= 8;
     215           0 :     nValue |= nG;
     216           0 :     nValue <<= 8;
     217           0 :     nValue |= nB;
     218           0 :     return nValue;
     219             : }
     220             : 
     221             : } // namespace
     222             : 
     223         128 : ExcelGraphicHelper::ExcelGraphicHelper( const WorkbookHelper& rHelper ) :
     224         256 :     GraphicHelper( rHelper.getBaseFilter().getComponentContext(), rHelper.getBaseFilter().getTargetFrame(), rHelper.getBaseFilter().getStorage() ),
     225         256 :     WorkbookHelper( rHelper )
     226             : {
     227         128 : }
     228             : 
     229        1638 : sal_Int32 ExcelGraphicHelper::getSchemeColor( sal_Int32 nToken ) const
     230             : {
     231        1638 :     if( getFilterType() == FILTER_OOXML )
     232        1638 :         return getTheme().getColorByToken( nToken );
     233           0 :     return GraphicHelper::getSchemeColor( nToken );
     234             : }
     235             : 
     236        1262 : sal_Int32 ExcelGraphicHelper::getPaletteColor( sal_Int32 nPaletteIdx ) const
     237             : {
     238        1262 :     return getStyles().getPaletteColor( nPaletteIdx );
     239             : }
     240             : 
     241           0 : void Color::setAuto()
     242             : {
     243           0 :     clearTransformations();
     244           0 :     setSchemeClr( XML_phClr );
     245           0 : }
     246             : 
     247         134 : void Color::setRgb( sal_Int32 nRgbValue, double fTint )
     248             : {
     249         134 :     clearTransformations();
     250         134 :     setSrgbClr( nRgbValue & 0xFFFFFF );
     251         134 :     if( fTint != 0.0 ) addExcelTintTransformation( fTint );
     252         134 : }
     253             : 
     254          60 : void Color::setTheme( sal_Int32 nThemeIdx, double fTint )
     255             : {
     256          60 :     clearTransformations();
     257             :     static const sal_Int32 spnColorTokens[] = {
     258             :         XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2,
     259             :         XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink };
     260          60 :     setSchemeClr( STATIC_ARRAY_SELECT( spnColorTokens, nThemeIdx, XML_TOKEN_INVALID ) );
     261          60 :     if( fTint != 0.0 ) addExcelTintTransformation( fTint );
     262          60 : }
     263             : 
     264        2330 : void Color::setIndexed( sal_Int32 nPaletteIdx, double fTint )
     265             : {
     266        2330 :     clearTransformations();
     267        2330 :     setPaletteClr( nPaletteIdx );
     268        2330 :     if( fTint != 0.0 ) addExcelTintTransformation( fTint );
     269        2330 : }
     270             : 
     271         234 : void Color::importColor( const AttributeList& rAttribs )
     272             : {
     273         234 :     if( rAttribs.getBool( XML_auto, false ) )
     274           0 :         setAuto();
     275         234 :     else if( rAttribs.hasAttribute( XML_rgb ) )
     276         134 :         setRgb( rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT ), rAttribs.getDouble( XML_tint, 0.0 ) );
     277         100 :     else if( rAttribs.hasAttribute( XML_theme ) )
     278          60 :         setTheme( rAttribs.getInteger( XML_theme, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) );
     279          40 :     else if( rAttribs.hasAttribute( XML_indexed ) )
     280          40 :         setIndexed( rAttribs.getInteger( XML_indexed, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) );
     281             :     else
     282             :     {
     283             :         OSL_FAIL( "Color::importColor - unknown color type" );
     284           0 :         setAuto();
     285             :     }
     286         234 : }
     287             : 
     288           0 : void Color::importColor( SequenceInputStream& rStrm )
     289             : {
     290             :     sal_uInt8 nFlags, nIndex;
     291             :     sal_Int16 nTint;
     292           0 :     rStrm >> nFlags >> nIndex >> nTint;
     293             : 
     294             :     // scale tint from signed 16-bit to double range -1.0 ... 1.0
     295           0 :     double fTint = nTint;
     296           0 :     if( nTint < 0 )
     297           0 :         fTint /= -SAL_MIN_INT16;
     298           0 :     else if( nTint > 0 )
     299           0 :         fTint /= SAL_MAX_INT16;
     300             : 
     301           0 :     switch( extractValue< sal_uInt8 >( nFlags, 1, 7 ) )
     302             :     {
     303             :         case BIFF12_COLOR_AUTO:
     304           0 :             setAuto();
     305           0 :             rStrm.skip( 4 );
     306           0 :         break;
     307             :         case BIFF12_COLOR_INDEXED:
     308           0 :             setIndexed( nIndex, fTint );
     309           0 :             rStrm.skip( 4 );
     310           0 :         break;
     311             :         case BIFF12_COLOR_RGB:
     312           0 :             setRgb( lclReadRgbColor( rStrm ), fTint );
     313           0 :         break;
     314             :         case BIFF12_COLOR_THEME:
     315           0 :             setTheme( nIndex, fTint );
     316           0 :             rStrm.skip( 4 );
     317           0 :         break;
     318             :         default:
     319             :             OSL_FAIL( "Color::importColor - unknown color type" );
     320           0 :             setAuto();
     321           0 :             rStrm.skip( 4 );
     322             :     }
     323           0 : }
     324             : 
     325           0 : void Color::importColorId( SequenceInputStream& rStrm )
     326             : {
     327           0 :     setIndexed( rStrm.readInt32() );
     328           0 : }
     329             : 
     330           0 : SequenceInputStream& operator>>( SequenceInputStream& rStrm, Color& orColor )
     331             : {
     332           0 :     orColor.importColor( rStrm );
     333           0 :     return rStrm;
     334             : }
     335             : 
     336             : namespace {
     337             : 
     338             : /** Standard EGA colors, bright. */
     339             : #define PALETTE_EGA_COLORS_LIGHT \
     340             :             0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF
     341             : /** Standard EGA colors, dark. */
     342             : #define PALETTE_EGA_COLORS_DARK \
     343             :             0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080
     344             : 
     345             : /** Default color table for BIFF2. */
     346             : static const sal_Int32 spnDefColors2[] =
     347             : {
     348             : /*  0 */    PALETTE_EGA_COLORS_LIGHT
     349             : };
     350             : 
     351             : /** Default color table for BIFF3/BIFF4. */
     352             : static const sal_Int32 spnDefColors3[] =
     353             : {
     354             : /*  0 */    PALETTE_EGA_COLORS_LIGHT,
     355             : /*  8 */    PALETTE_EGA_COLORS_LIGHT,
     356             : /* 16 */    PALETTE_EGA_COLORS_DARK
     357             : };
     358             : 
     359             : /** Default color table for BIFF5. */
     360             : static const sal_Int32 spnDefColors5[] =
     361             : {
     362             : /*  0 */    PALETTE_EGA_COLORS_LIGHT,
     363             : /*  8 */    PALETTE_EGA_COLORS_LIGHT,
     364             : /* 16 */    PALETTE_EGA_COLORS_DARK,
     365             : /* 24 */    0x8080FF, 0x802060, 0xFFFFC0, 0xA0E0E0, 0x600080, 0xFF8080, 0x0080C0, 0xC0C0FF,
     366             : /* 32 */    0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
     367             : /* 40 */    0x00CFFF, 0x69FFFF, 0xE0FFE0, 0xFFFF80, 0xA6CAF0, 0xDD9CB3, 0xB38FEE, 0xE3E3E3,
     368             : /* 48 */    0x2A6FF9, 0x3FB8CD, 0x488436, 0x958C41, 0x8E5E42, 0xA0627A, 0x624FAC, 0x969696,
     369             : /* 56 */    0x1D2FBE, 0x286676, 0x004500, 0x453E01, 0x6A2813, 0x85396A, 0x4A3285, 0x424242
     370             : };
     371             : 
     372             : /** Default color table for BIFF8/BIFF12/OOXML. */
     373             : static const sal_Int32 spnDefColors8[] =
     374             : {
     375             : /*  0 */    PALETTE_EGA_COLORS_LIGHT,
     376             : /*  8 */    PALETTE_EGA_COLORS_LIGHT,
     377             : /* 16 */    PALETTE_EGA_COLORS_DARK,
     378             : /* 24 */    0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF,
     379             : /* 32 */    0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
     380             : /* 40 */    0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99,
     381             : /* 48 */    0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696,
     382             : /* 56 */    0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333
     383             : };
     384             : 
     385             : #undef PALETTE_EGA_COLORS_LIGHT
     386             : #undef PALETTE_EGA_COLORS_DARK
     387             : 
     388             : } // namespace
     389             : 
     390         128 : ColorPalette::ColorPalette( const WorkbookHelper& rHelper )
     391             :     : WorkbookHelper(rHelper)
     392         128 :     , mnAppendIndex(0)
     393             : {
     394             :     // default colors
     395         128 :     switch( getFilterType() )
     396             :     {
     397             :         case FILTER_OOXML:
     398         128 :             maColors.insert( maColors.begin(), spnDefColors8, STATIC_ARRAY_END( spnDefColors8 ) );
     399         128 :             mnAppendIndex = OOX_COLOR_USEROFFSET;
     400         128 :         break;
     401             :         case FILTER_BIFF:
     402           0 :             switch( getBiff() )
     403             :             {
     404           0 :                 case BIFF2: maColors.insert( maColors.begin(), spnDefColors2, STATIC_ARRAY_END( spnDefColors2 ) );  break;
     405             :                 case BIFF3:
     406           0 :                 case BIFF4: maColors.insert( maColors.begin(), spnDefColors3, STATIC_ARRAY_END( spnDefColors3 ) );  break;
     407           0 :                 case BIFF5: maColors.insert( maColors.begin(), spnDefColors5, STATIC_ARRAY_END( spnDefColors5 ) );  break;
     408           0 :                 case BIFF8: maColors.insert( maColors.begin(), spnDefColors8, STATIC_ARRAY_END( spnDefColors8 ) );  break;
     409           0 :                 case BIFF_UNKNOWN: break;
     410             :             }
     411           0 :             mnAppendIndex = BIFF_COLOR_USEROFFSET;
     412           0 :         break;
     413           0 :         case FILTER_UNKNOWN: break;
     414             :     }
     415         128 : }
     416             : 
     417        1024 : void ColorPalette::importPaletteColor( const AttributeList& rAttribs )
     418             : {
     419        1024 :     appendColor( rAttribs.getIntegerHex( XML_rgb, API_RGB_WHITE ) );
     420        1024 : }
     421             : 
     422           0 : void ColorPalette::importPaletteColor( SequenceInputStream& rStrm )
     423             : {
     424           0 :     sal_Int32 nRgb = lclReadRgbColor( rStrm );
     425           0 :     appendColor( nRgb & 0xFFFFFF );
     426           0 : }
     427             : 
     428        1262 : sal_Int32 ColorPalette::getColor( sal_Int32 nPaletteIdx ) const
     429             : {
     430        1262 :     sal_Int32 nColor = API_RGB_TRANSPARENT;
     431        1262 :     if( const sal_Int32* pnPaletteColor = ContainerHelper::getVectorElement( maColors, nPaletteIdx ) )
     432             :     {
     433           2 :         nColor = *pnPaletteColor;
     434             :     }
     435        1260 :     else switch( nPaletteIdx )
     436             :     {
     437             :         case OOX_COLOR_WINDOWTEXT3:
     438             :         case OOX_COLOR_WINDOWTEXT:
     439        1132 :         case OOX_COLOR_CHWINDOWTEXT:    nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_windowText );   break;
     440             :         case OOX_COLOR_WINDOWBACK3:
     441             :         case OOX_COLOR_WINDOWBACK:
     442         128 :         case OOX_COLOR_CHWINDOWBACK:    nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_window );       break;
     443           0 :         case OOX_COLOR_BUTTONBACK:      nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_btnFace );      break;
     444           0 :         case OOX_COLOR_CHBORDERAUTO:    nColor = API_RGB_BLACK; /* really always black? */                              break;
     445           0 :         case OOX_COLOR_NOTEBACK:        nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoBk );       break;
     446           0 :         case OOX_COLOR_NOTETEXT:        nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoText );     break;
     447           0 :         case OOX_COLOR_FONTAUTO:        nColor = API_RGB_TRANSPARENT;                                                   break;
     448             :         default:                        OSL_FAIL( "ColorPalette::getColor - unknown color index" );
     449             :     }
     450        1262 :     return nColor;
     451             : }
     452             : 
     453        1024 : void ColorPalette::appendColor( sal_Int32 nRGBValue )
     454             : {
     455        1024 :     if( mnAppendIndex < maColors.size() )
     456        1024 :         maColors[ mnAppendIndex ] = nRGBValue;
     457             :     else
     458           0 :         maColors.push_back( nRGBValue );
     459        1024 :     ++mnAppendIndex;
     460        1024 : }
     461             : 
     462             : namespace {
     463             : 
     464        1614 : void lclSetFontName( ApiScriptFontName& rFontName, const FontDescriptor& rFontDesc, bool bHasGlyphs )
     465             : {
     466        1614 :     if( bHasGlyphs )
     467             :     {
     468         952 :         rFontName.maName = rFontDesc.Name;
     469         952 :         rFontName.mnFamily = rFontDesc.Family;
     470             :         // API font descriptor contains rtl_TextEncoding constants
     471         952 :         rFontName.mnTextEnc = rFontDesc.CharSet;
     472             :     }
     473             :     else
     474             :     {
     475         662 :         rFontName = ApiScriptFontName();
     476             :     }
     477        1614 : }
     478             : 
     479             : } // namespace
     480             : 
     481         256 : FontModel::FontModel() :
     482             :     mnScheme( XML_none ),
     483             :     mnFamily( OOX_FONTFAMILY_NONE ),
     484             :     mnCharSet( WINDOWS_CHARSET_DEFAULT ),
     485             :     mfHeight( 0.0 ),
     486             :     mnUnderline( XML_none ),
     487             :     mnEscapement( XML_baseline ),
     488             :     mbBold( false ),
     489             :     mbItalic( false ),
     490             :     mbStrikeout( false ),
     491             :     mbOutline( false ),
     492         256 :     mbShadow( false )
     493             : {
     494         256 : }
     495             : 
     496           0 : void FontModel::setBiff12Scheme( sal_uInt8 nScheme )
     497             : {
     498             :     static const sal_Int32 spnSchemes[] = { XML_none, XML_major, XML_minor };
     499           0 :     mnScheme = STATIC_ARRAY_SELECT( spnSchemes, nScheme, XML_none );
     500           0 : }
     501             : 
     502           0 : void FontModel::setBiffHeight( sal_uInt16 nHeight )
     503             : {
     504           0 :     mfHeight = nHeight / 20.0;  // convert twips to points
     505           0 : }
     506             : 
     507           0 : void FontModel::setBiffWeight( sal_uInt16 nWeight )
     508             : {
     509           0 :     mbBold = nWeight >= BIFF_FONTWEIGHT_BOLD;
     510           0 : }
     511             : 
     512           0 : void FontModel::setBiffUnderline( sal_uInt16 nUnderline )
     513             : {
     514           0 :     switch( nUnderline )
     515             :     {
     516           0 :         case BIFF_FONTUNDERL_NONE:          mnUnderline = XML_none;             break;
     517           0 :         case BIFF_FONTUNDERL_SINGLE:        mnUnderline = XML_single;           break;
     518           0 :         case BIFF_FONTUNDERL_DOUBLE:        mnUnderline = XML_double;           break;
     519           0 :         case BIFF_FONTUNDERL_SINGLE_ACC:    mnUnderline = XML_singleAccounting; break;
     520           0 :         case BIFF_FONTUNDERL_DOUBLE_ACC:    mnUnderline = XML_doubleAccounting; break;
     521           0 :         default:                            mnUnderline = XML_none;
     522             :     }
     523           0 : }
     524             : 
     525           0 : void FontModel::setBiffEscapement( sal_uInt16 nEscapement )
     526             : {
     527             :     static const sal_Int32 spnEscapes[] = { XML_baseline, XML_superscript, XML_subscript };
     528           0 :     mnEscapement = STATIC_ARRAY_SELECT( spnEscapes, nEscapement, XML_baseline );
     529           0 : }
     530             : 
     531         540 : ApiFontUsedFlags::ApiFontUsedFlags( bool bAllUsed ) :
     532             :     mbNameUsed( bAllUsed ),
     533             :     mbColorUsed( bAllUsed ),
     534             :     mbSchemeUsed( bAllUsed ),
     535             :     mbHeightUsed( bAllUsed ),
     536             :     mbUnderlineUsed( bAllUsed ),
     537             :     mbEscapementUsed( bAllUsed ),
     538             :     mbWeightUsed( bAllUsed ),
     539             :     mbPostureUsed( bAllUsed ),
     540             :     mbStrikeoutUsed( bAllUsed ),
     541             :     mbOutlineUsed( bAllUsed ),
     542         540 :     mbShadowUsed( bAllUsed )
     543             : {
     544         540 : }
     545             : 
     546        2282 : ApiScriptFontName::ApiScriptFontName() :
     547             :     mnFamily( ::com::sun::star::awt::FontFamily::DONTKNOW ),
     548        2282 :     mnTextEnc( RTL_TEXTENCODING_DONTKNOW )
     549             : {
     550        2282 : }
     551             : 
     552         540 : ApiFontData::ApiFontData() :
     553             :     maDesc(
     554             :         "Calibri",
     555             :         220,                                            // height 11 points
     556             :         0,
     557             :         OUString(),
     558             :         ::com::sun::star::awt::FontFamily::DONTKNOW,
     559             :         RTL_TEXTENCODING_DONTKNOW,
     560             :         ::com::sun::star::awt::FontPitch::DONTKNOW,
     561             :         100.0,
     562             :         ::com::sun::star::awt::FontWeight::NORMAL,
     563             :         ::com::sun::star::awt::FontSlant_NONE,
     564             :         ::com::sun::star::awt::FontUnderline::NONE,
     565             :         ::com::sun::star::awt::FontStrikeout::NONE,
     566             :         0.0,
     567             :         sal_False,
     568             :         sal_False,
     569             :         ::com::sun::star::awt::FontType::DONTKNOW ),
     570             :     mnColor( API_RGB_TRANSPARENT ),
     571             :     mnEscapement( API_ESCAPE_NONE ),
     572             :     mnEscapeHeight( API_ESCAPEHEIGHT_NONE ),
     573             :     mbOutline( false ),
     574         540 :     mbShadow( false )
     575             : {
     576         540 :     maLatinFont.maName = maDesc.Name;
     577         540 : }
     578             : 
     579         408 : Font::Font( const WorkbookHelper& rHelper, bool bDxf ) :
     580             :     WorkbookHelper( rHelper ),
     581         408 :     maModel( rHelper.getTheme().getDefaultFontModel() ),
     582         408 :     maUsedFlags( !bDxf ),
     583        1224 :     mbDxf( bDxf )
     584             : {
     585         408 : }
     586             : 
     587         132 : Font::Font( const WorkbookHelper& rHelper, const FontModel& rModel ) :
     588             :     WorkbookHelper( rHelper ),
     589             :     maModel( rModel ),
     590             :     maUsedFlags( true ),
     591         132 :     mbDxf( false )
     592             : {
     593         132 : }
     594             : 
     595        1586 : void Font::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
     596             : {
     597        1586 :     const FontModel& rDefModel = getTheme().getDefaultFontModel();
     598        1586 :     switch( nElement )
     599             :     {
     600             :         case XLS_TOKEN( name ):     // when in <font> element
     601             :         case XLS_TOKEN( rFont ):    // when in <rPr> element
     602         408 :             if( rAttribs.hasAttribute( XML_val ) )
     603             :             {
     604         408 :                 maModel.maName = rAttribs.getXString( XML_val, OUString() );
     605         408 :                 maUsedFlags.mbNameUsed = true;
     606             :             }
     607         408 :         break;
     608             :         case XLS_TOKEN( scheme ):
     609          58 :             maModel.mnScheme = rAttribs.getToken( XML_val, rDefModel.mnScheme );
     610          58 :         break;
     611             :         case XLS_TOKEN( family ):
     612         396 :             maModel.mnFamily = rAttribs.getInteger( XML_val, rDefModel.mnFamily );
     613         396 :         break;
     614             :         case XLS_TOKEN( charset ):
     615         116 :             maModel.mnCharSet = rAttribs.getInteger( XML_val, rDefModel.mnCharSet );
     616         116 :         break;
     617             :         case XLS_TOKEN( sz ):
     618         408 :             maModel.mfHeight = rAttribs.getDouble( XML_val, rDefModel.mfHeight );
     619         408 :             maUsedFlags.mbHeightUsed = true;
     620         408 :         break;
     621             :         case XLS_TOKEN( color ):
     622         158 :             maModel.maColor.importColor( rAttribs );
     623         158 :             maUsedFlags.mbColorUsed = true;
     624         158 :         break;
     625             :         case XLS_TOKEN( u ):
     626           2 :             maModel.mnUnderline = rAttribs.getToken( XML_val, XML_single );
     627           2 :             maUsedFlags.mbUnderlineUsed = true;
     628           2 :         break;
     629             :         case XLS_TOKEN( vertAlign ):
     630           0 :             maModel.mnEscapement = rAttribs.getToken( XML_val, XML_baseline );
     631           0 :             maUsedFlags.mbEscapementUsed = true;
     632           0 :         break;
     633             :         case XLS_TOKEN( b ):
     634          36 :             maModel.mbBold = rAttribs.getBool( XML_val, true );
     635          36 :             maUsedFlags.mbWeightUsed = true;
     636          36 :         break;
     637             :         case XLS_TOKEN( i ):
     638           4 :             maModel.mbItalic = rAttribs.getBool( XML_val, true );
     639           4 :             maUsedFlags.mbPostureUsed = true;
     640           4 :         break;
     641             :         case XLS_TOKEN( strike ):
     642           0 :             maModel.mbStrikeout = rAttribs.getBool( XML_val, true );
     643           0 :             maUsedFlags.mbStrikeoutUsed = true;
     644           0 :         break;
     645             :         case XLS_TOKEN( outline ):
     646           0 :             maModel.mbOutline = rAttribs.getBool( XML_val, true );
     647           0 :             maUsedFlags.mbOutlineUsed = true;
     648           0 :         break;
     649             :         case XLS_TOKEN( shadow ):
     650           0 :             maModel.mbShadow = rAttribs.getBool( XML_val, true );
     651           0 :             maUsedFlags.mbShadowUsed = true;
     652           0 :         break;
     653             :     }
     654        1586 : }
     655             : 
     656           0 : void Font::importFont( SequenceInputStream& rStrm )
     657             : {
     658             :     SAL_WARN_IF( mbDxf, "sc", "Font::importFont - unexpected conditional formatting flag" );
     659             : 
     660             :     sal_uInt16 nHeight, nFlags, nWeight, nEscapement;
     661             :     sal_uInt8 nUnderline, nFamily, nCharSet, nScheme;
     662           0 :     rStrm >> nHeight >> nFlags >> nWeight >> nEscapement >> nUnderline >> nFamily >> nCharSet;
     663           0 :     rStrm.skip( 1 );
     664           0 :     rStrm >> maModel.maColor >> nScheme >> maModel.maName;
     665             : 
     666             :     // equal constants in all BIFFs for weight, underline, and escapement
     667           0 :     maModel.setBiff12Scheme( nScheme );
     668           0 :     maModel.setBiffHeight( nHeight );
     669           0 :     maModel.setBiffWeight( nWeight );
     670           0 :     maModel.setBiffUnderline( nUnderline );
     671           0 :     maModel.setBiffEscapement( nEscapement );
     672           0 :     maModel.mnFamily    = nFamily;
     673           0 :     maModel.mnCharSet   = nCharSet;
     674             :     // equal flags in all BIFFs
     675           0 :     maModel.mbItalic    = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
     676           0 :     maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT );
     677           0 :     maModel.mbOutline   = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE );
     678           0 :     maModel.mbShadow    = getFlag( nFlags, BIFF_FONTFLAG_SHADOW );
     679           0 : }
     680             : 
     681           0 : void Font::importDxfName( SequenceInputStream& rStrm )
     682             : {
     683             :     SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfName - missing conditional formatting flag" );
     684           0 :     maModel.maName = BiffHelper::readString( rStrm, false );
     685           0 :     maUsedFlags.mbColorUsed = true;
     686           0 : }
     687             : 
     688           0 : void Font::importDxfColor( SequenceInputStream& rStrm )
     689             : {
     690             :     SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfColor - missing conditional formatting flag" );
     691           0 :     rStrm >> maModel.maColor;
     692           0 :     maUsedFlags.mbColorUsed = true;
     693           0 : }
     694             : 
     695           0 : void Font::importDxfScheme( SequenceInputStream& rStrm )
     696             : {
     697             :     SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfScheme - missing conditional formatting flag" );
     698           0 :     maModel.setBiff12Scheme( rStrm.readuInt8() );
     699           0 :     maUsedFlags.mbSchemeUsed = true;
     700           0 : }
     701             : 
     702           0 : void Font::importDxfHeight( SequenceInputStream& rStrm )
     703             : {
     704             :     SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfHeight - missing conditional formatting flag" );
     705           0 :     maModel.setBiffHeight( rStrm.readuInt16() );
     706           0 :     maUsedFlags.mbHeightUsed = true;
     707           0 : }
     708             : 
     709           0 : void Font::importDxfWeight( SequenceInputStream& rStrm )
     710             : {
     711             :     SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfWeight - missing conditional formatting flag" );
     712           0 :     maModel.setBiffWeight( rStrm.readuInt16() );
     713           0 :     maUsedFlags.mbWeightUsed = true;
     714           0 : }
     715             : 
     716           0 : void Font::importDxfUnderline( SequenceInputStream& rStrm )
     717             : {
     718             :     SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfUnderline - missing conditional formatting flag" );
     719           0 :     maModel.setBiffUnderline( rStrm.readuInt16() );
     720           0 :     maUsedFlags.mbUnderlineUsed = true;
     721           0 : }
     722             : 
     723           0 : void Font::importDxfEscapement( SequenceInputStream& rStrm )
     724             : {
     725             :     SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfEscapement - missing conditional formatting flag" );
     726           0 :     maModel.setBiffEscapement( rStrm.readuInt16() );
     727           0 :     maUsedFlags.mbEscapementUsed = true;
     728           0 : }
     729             : 
     730           0 : void Font::importDxfFlag( sal_Int32 nElement, SequenceInputStream& rStrm )
     731             : {
     732             :     SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfFlag - missing conditional formatting flag" );
     733           0 :     bool bFlag = rStrm.readuInt8() != 0;
     734           0 :     switch( nElement )
     735             :     {
     736             :         case XML_i:
     737           0 :             maModel.mbItalic = bFlag;
     738           0 :             maUsedFlags.mbPostureUsed = true;
     739           0 :         break;
     740             :         case XML_strike:
     741           0 :             maModel.mbStrikeout = bFlag;
     742           0 :             maUsedFlags.mbStrikeoutUsed = true;
     743           0 :         break;
     744             :         case XML_outline:
     745           0 :             maModel.mbOutline = bFlag;
     746           0 :             maUsedFlags.mbOutlineUsed = true;
     747           0 :         break;
     748             :         case XML_shadow:
     749           0 :             maModel.mbShadow = bFlag;
     750           0 :             maUsedFlags.mbShadowUsed = true;
     751           0 :         break;
     752             :         default:
     753             :             OSL_FAIL( "Font::importDxfFlag - unexpected element identifier" );
     754             :     }
     755           0 : }
     756             : 
     757         538 : void Font::finalizeImport()
     758             : {
     759             :     namespace cssawt = ::com::sun::star::awt;
     760             : 
     761             :     // font name
     762         538 :     maApiData.maDesc.Name = maModel.maName;
     763             : 
     764             :     // font family
     765         538 :     switch( maModel.mnFamily )
     766             :     {
     767         196 :         case OOX_FONTFAMILY_NONE:           maApiData.maDesc.Family = cssawt::FontFamily::DONTKNOW;     break;
     768           0 :         case OOX_FONTFAMILY_ROMAN:          maApiData.maDesc.Family = cssawt::FontFamily::ROMAN;        break;
     769         342 :         case OOX_FONTFAMILY_SWISS:          maApiData.maDesc.Family = cssawt::FontFamily::SWISS;        break;
     770           0 :         case OOX_FONTFAMILY_MODERN:         maApiData.maDesc.Family = cssawt::FontFamily::MODERN;       break;
     771           0 :         case OOX_FONTFAMILY_SCRIPT:         maApiData.maDesc.Family = cssawt::FontFamily::SCRIPT;       break;
     772           0 :         case OOX_FONTFAMILY_DECORATIVE:     maApiData.maDesc.Family = cssawt::FontFamily::DECORATIVE;   break;
     773             :     }
     774             : 
     775             :     // character set (API font descriptor uses rtl_TextEncoding in member CharSet!)
     776         538 :     if( (0 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) )
     777             :         maApiData.maDesc.CharSet = static_cast< sal_Int16 >(
     778         538 :             rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ) );
     779             : 
     780             :     // color, height, weight, slant, strikeout, outline, shadow
     781         538 :     maApiData.mnColor          = maModel.maColor.getColor( getBaseFilter().getGraphicHelper() );
     782         538 :     maApiData.maDesc.Height    = static_cast< sal_Int16 >( maModel.mfHeight * 20.0 );
     783         538 :     maApiData.maDesc.Weight    = maModel.mbBold ? cssawt::FontWeight::BOLD : cssawt::FontWeight::NORMAL;
     784         538 :     maApiData.maDesc.Slant     = maModel.mbItalic ? cssawt::FontSlant_ITALIC : cssawt::FontSlant_NONE;
     785         538 :     maApiData.maDesc.Strikeout = maModel.mbStrikeout ? cssawt::FontStrikeout::SINGLE : cssawt::FontStrikeout::NONE;
     786         538 :     maApiData.mbOutline        = maModel.mbOutline;
     787         538 :     maApiData.mbShadow         = maModel.mbShadow;
     788             : 
     789             :     // underline
     790         538 :     switch( maModel.mnUnderline )
     791             :     {
     792           0 :         case XML_double:            maApiData.maDesc.Underline = cssawt::FontUnderline::DOUBLE; break;
     793           0 :         case XML_doubleAccounting:  maApiData.maDesc.Underline = cssawt::FontUnderline::DOUBLE; break;
     794         536 :         case XML_none:              maApiData.maDesc.Underline = cssawt::FontUnderline::NONE;   break;
     795           2 :         case XML_single:            maApiData.maDesc.Underline = cssawt::FontUnderline::SINGLE; break;
     796           0 :         case XML_singleAccounting:  maApiData.maDesc.Underline = cssawt::FontUnderline::SINGLE; break;
     797             :     }
     798             : 
     799             :     // escapement
     800         538 :     switch( maModel.mnEscapement )
     801             :     {
     802             :         case XML_baseline:
     803         538 :             maApiData.mnEscapement = API_ESCAPE_NONE;
     804         538 :             maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_NONE;
     805         538 :         break;
     806             :         case XML_superscript:
     807           0 :             maApiData.mnEscapement = API_ESCAPE_SUPERSCRIPT;
     808           0 :             maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT;
     809           0 :         break;
     810             :         case XML_subscript:
     811           0 :             maApiData.mnEscapement = API_ESCAPE_SUBSCRIPT;
     812           0 :             maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT;
     813           0 :         break;
     814             :     }
     815             : 
     816             :     // supported script types
     817         538 :     if( maUsedFlags.mbNameUsed )
     818             :     {
     819         538 :         PropertySet aDocProps( getDocument() );
     820        1076 :         Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY );
     821         538 :         if( xDevice.is() )
     822             :         {
     823         538 :             Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY );
     824         538 :             if( xFont.is() )
     825             :             {
     826             :                 // #91658# CJK fonts
     827             :                 bool bHasAsian =
     828        3228 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x3041 ) ) ) ||    // 3040-309F: Hiragana
     829        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x30A1 ) ) ) ||    // 30A0-30FF: Katakana
     830        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x3111 ) ) ) ||    // 3100-312F: Bopomofo
     831        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x3131 ) ) ) ||    // 3130-318F: Hangul Compatibility Jamo
     832        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x3301 ) ) ) ||    // 3300-33FF: CJK Compatibility
     833        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x3401 ) ) ) ||    // 3400-4DBF: CJK Unified Ideographs Extension A
     834        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x4E01 ) ) ) ||    // 4E00-9FAF: CJK Unified Ideographs
     835        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x7E01 ) ) ) ||    // 4E00-9FAF: CJK unified ideographs
     836        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0xA001 ) ) ) ||    // A001-A48F: Yi Syllables
     837        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0xAC01 ) ) ) ||    // AC00-D7AF: Hangul Syllables
     838        2690 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0xCC01 ) ) ) ||    // AC00-D7AF: Hangul Syllables
     839        4304 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0xF901 ) ) ) ||    // F900-FAFF: CJK Compatibility Ideographs
     840        1614 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0xFF71 ) ) );      // FF00-FFEF: Halfwidth/Fullwidth Forms
     841             :                 // #113783# CTL fonts
     842             :                 bool bHasCmplx =
     843        2400 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x05D1 ) ) ) ||    // 0590-05FF: Hebrew
     844        1034 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x0631 ) ) ) ||    // 0600-06FF: Arabic
     845        1034 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x0721 ) ) ) ||    // 0700-074F: Syriac
     846        1034 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x0911 ) ) ) ||    // 0900-0DFF: Indic scripts
     847        1034 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0x0E01 ) ) ) ||    // 0E00-0E7F: Thai
     848        1034 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0xFB21 ) ) ) ||    // FB1D-FB4F: Hebrew Presentation Forms
     849        2648 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0xFB51 ) ) ) ||    // FB50-FDFF: Arabic Presentation Forms-A
     850         786 :                     xFont->hasGlyphs( OUString( sal_Unicode( 0xFE71 ) ) );      // FE70-FEFF: Arabic Presentation Forms-B
     851             :                 // Western fonts
     852             :                 bool bHasLatin =
     853        1366 :                     (!bHasAsian && !bHasCmplx) ||
     854        1366 :                     xFont->hasGlyphs( OUString( 'A' ) );
     855             : 
     856         538 :                 lclSetFontName( maApiData.maLatinFont, maApiData.maDesc, bHasLatin );
     857         538 :                 lclSetFontName( maApiData.maAsianFont, maApiData.maDesc, bHasAsian );
     858         538 :                 lclSetFontName( maApiData.maCmplxFont, maApiData.maDesc, bHasCmplx );
     859         538 :             }
     860         538 :         }
     861             :     }
     862         538 : }
     863             : 
     864        1126 : bool Font::needsRichTextFormat() const
     865             : {
     866        1126 :     return maApiData.mnEscapement != API_ESCAPE_NONE;
     867             : }
     868         428 : ::FontFamily lcl_getFontFamily( sal_Int32 nFamily )
     869             : {
     870             :     namespace cssawt = ::com::sun::star::awt;
     871             : 
     872         428 :     ::FontFamily eScFamily = FAMILY_DONTKNOW;
     873         428 :     switch( nFamily )
     874             :     {
     875             :         case cssawt::FontFamily::DONTKNOW:
     876          26 :             eScFamily = FAMILY_DONTKNOW;
     877          26 :             break;
     878             :         case cssawt::FontFamily::ROMAN:
     879           0 :             eScFamily = FAMILY_ROMAN;
     880           0 :             break;
     881             :         case cssawt::FontFamily::SWISS:
     882         402 :             eScFamily = FAMILY_SWISS;
     883         402 :             break;
     884             :         case cssawt::FontFamily::MODERN:
     885           0 :             eScFamily = FAMILY_MODERN;
     886           0 :             break;
     887             :         case cssawt::FontFamily::SCRIPT:
     888           0 :             eScFamily = FAMILY_SCRIPT;
     889           0 :             break;
     890             :         case cssawt::FontFamily::DECORATIVE:
     891           0 :             eScFamily = FAMILY_DECORATIVE;
     892           0 :             break;
     893             :     }
     894         428 :     return eScFamily;
     895             : }
     896             : 
     897         304 : void Font::fillToItemSet( SfxItemSet& rItemSet, FontPropertyType ePropType, bool bSkipPoolDefs ) const
     898             : {
     899         304 :     bool bEdit = ( ePropType == FONT_PROPTYPE_TEXT );
     900             :     namespace cssawt = ::com::sun::star::awt;
     901         304 :     if ( maUsedFlags.mbNameUsed )
     902             :     {
     903         304 :         if( !maApiData.maLatinFont.maName.isEmpty() )
     904             :         {
     905         304 :             rtl_TextEncoding eFontEnc = maApiData.maLatinFont.mnTextEnc;
     906             :             // taken from binary importer
     907           2 :             rtl_TextEncoding eTempTextEnc = (bEdit && (eFontEnc == getTextEncoding())) ?
     908         304 :                 ScfTools::GetSystemTextEncoding() : eFontEnc;
     909             : 
     910             :             SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maLatinFont.mnFamily ), maApiData.maLatinFont.maName, OUString(),
     911         304 :                 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
     912         304 :             ScfTools::PutItem( rItemSet, aFontItem, bEdit ? EE_CHAR_FONTINFO : ATTR_FONT, bSkipPoolDefs );
     913             :         }
     914         304 :         if( !maApiData.maAsianFont.maName.isEmpty() )
     915             :         {
     916           0 :             rtl_TextEncoding eFontEnc = maApiData.maAsianFont.mnTextEnc;
     917             :             // taken from binary importer
     918           0 :             rtl_TextEncoding eTempTextEnc = (bEdit && (eFontEnc == getTextEncoding())) ?
     919           0 :                 ScfTools::GetSystemTextEncoding() : eFontEnc;
     920             :             SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maAsianFont.mnFamily ), maApiData.maAsianFont.maName, OUString(),
     921           0 :                 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
     922           0 :             ScfTools::PutItem( rItemSet, aFontItem, bEdit ? EE_CHAR_FONTINFO_CJK : ATTR_CJK_FONT, bSkipPoolDefs );
     923             :         }
     924         304 :         if( !maApiData.maCmplxFont.maName.isEmpty() )
     925             :         {
     926         124 :             rtl_TextEncoding eFontEnc = maApiData.maCmplxFont.mnTextEnc;
     927             :             // taken from binary importer
     928           0 :             rtl_TextEncoding eTempTextEnc = (bEdit && (eFontEnc == getTextEncoding())) ?
     929         124 :                 ScfTools::GetSystemTextEncoding() : eFontEnc;
     930             :             SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maCmplxFont.mnFamily ), maApiData.maCmplxFont.maName, OUString(),
     931         124 :                 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
     932         124 :             ScfTools::PutItem( rItemSet, aFontItem, bEdit ? EE_CHAR_FONTINFO_CTL : ATTR_CTL_FONT, bSkipPoolDefs );
     933             :         }
     934             :     }
     935             :     // font height
     936         304 :     if( maUsedFlags.mbHeightUsed )
     937             :     {
     938         304 :         sal_Int32 nHeight = maApiData.maDesc.Height;
     939             :         // do we use EXC_FONTITEM_HF ( or is it just relevant for the binary filter )
     940         304 :         if( bEdit/* && (eType != EXC_FONTITEM_HF) */)     // do not convert header/footer height
     941           2 :             nHeight = (nHeight * 127 + 36) / EXC_POINTS_PER_INCH;   // 1 in == 72 pt
     942         304 :         SvxFontHeightItem aHeightItem( nHeight, 100, ATTR_FONT_HEIGHT );
     943         304 :         ScfTools::PutItem( rItemSet, aHeightItem, bEdit ? EE_CHAR_FONTHEIGHT :  ATTR_FONT_HEIGHT, bSkipPoolDefs );
     944         304 :         ScfTools::PutItem( rItemSet, aHeightItem, bEdit ? EE_CHAR_FONTHEIGHT_CJK : ATTR_CJK_FONT_HEIGHT, bSkipPoolDefs );
     945         304 :         ScfTools::PutItem( rItemSet, aHeightItem, bEdit ? EE_CHAR_FONTHEIGHT_CTL : ATTR_CTL_FONT_HEIGHT, bSkipPoolDefs );
     946             :     }
     947             :     // font weight
     948         304 :     if( maUsedFlags.mbWeightUsed )
     949             :     {
     950         288 :         ::FontWeight fWeight = VCLUnoHelper::ConvertFontWeight( maApiData.maDesc.Weight );
     951         288 :         SvxWeightItem aWeightItem( fWeight, ATTR_FONT_WEIGHT );
     952         288 :         ScfTools::PutItem( rItemSet, aWeightItem, bEdit ? EE_CHAR_WEIGHT : ATTR_FONT_WEIGHT, bSkipPoolDefs );
     953         288 :         ScfTools::PutItem( rItemSet, aWeightItem, bEdit ? EE_CHAR_WEIGHT_CTL : ATTR_CTL_FONT_WEIGHT, bSkipPoolDefs );
     954         288 :         ScfTools::PutItem( rItemSet, aWeightItem, bEdit ? EE_CHAR_WEIGHT_CJK : ATTR_CJK_FONT_WEIGHT, bSkipPoolDefs );
     955             :     }
     956             :     // font posture
     957         304 :     if( maUsedFlags.mbPostureUsed )
     958             :     {
     959         288 :         SvxPostureItem aPostItem( ( maApiData.maDesc.Slant == cssawt::FontSlant_ITALIC ) ? ITALIC_NORMAL :  ITALIC_NONE,  ATTR_FONT_POSTURE);
     960         288 :         ScfTools::PutItem( rItemSet, aPostItem, bEdit ? EE_CHAR_ITALIC : ATTR_FONT_POSTURE, bSkipPoolDefs );
     961         288 :         ScfTools::PutItem( rItemSet, aPostItem, bEdit ? EE_CHAR_ITALIC_CJK : ATTR_CJK_FONT_POSTURE, bSkipPoolDefs );
     962         288 :         ScfTools::PutItem( rItemSet, aPostItem, bEdit ? EE_CHAR_ITALIC_CTL : ATTR_CTL_FONT_POSTURE, bSkipPoolDefs );
     963             :     }
     964             :     // character color
     965         304 :     if( maUsedFlags.mbColorUsed )
     966             :     {
     967         304 :         ScfTools::PutItem( rItemSet,SvxColorItem( maApiData.mnColor, bEdit ? EE_CHAR_COLOR : ATTR_FONT_COLOR  ) , bSkipPoolDefs );
     968             :     }
     969             :     // underline style
     970         304 :     if( maUsedFlags.mbUnderlineUsed )
     971             :     {
     972             :         ::FontUnderline eScUnderl;
     973         288 :         if ( maApiData.maDesc.Underline == cssawt::FontUnderline::DOUBLE )
     974           0 :             eScUnderl = UNDERLINE_DOUBLE;
     975         288 :         else if ( maApiData.maDesc.Underline == cssawt::FontUnderline::SINGLE )
     976           4 :             eScUnderl = UNDERLINE_SINGLE;
     977             :         else
     978         284 :             eScUnderl = UNDERLINE_NONE;
     979         288 :         SvxUnderlineItem aUnderlItem( eScUnderl, ATTR_FONT_UNDERLINE );
     980         288 :         ScfTools::PutItem( rItemSet, aUnderlItem, bEdit ? EE_CHAR_UNDERLINE : ATTR_FONT_UNDERLINE, bSkipPoolDefs );
     981             :     }
     982             :     // strike out style
     983         304 :     if( maUsedFlags.mbStrikeoutUsed )
     984             :     {
     985         288 :         ScfTools::PutItem( rItemSet, SvxCrossedOutItem( maModel.mbStrikeout ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, bEdit ? EE_CHAR_STRIKEOUT : ATTR_FONT_CROSSEDOUT ), ATTR_FONT_CROSSEDOUT, bSkipPoolDefs );
     986             :     }
     987             : 
     988             :     // outline style
     989         304 :     if( maUsedFlags.mbOutlineUsed )
     990             :     {
     991         288 :         ScfTools::PutItem( rItemSet, SvxContourItem( maApiData.mbOutline, ATTR_FONT_CONTOUR ), bEdit ? EE_CHAR_OUTLINE : ATTR_FONT_CONTOUR, bSkipPoolDefs );
     992             :     }
     993             : 
     994             :     // shadow style
     995         304 :     if( maUsedFlags.mbShadowUsed )
     996             :     {
     997         288 :         ScfTools::PutItem( rItemSet, SvxShadowedItem( maApiData.mbShadow, ATTR_FONT_SHADOWED ), bEdit ? EE_CHAR_SHADOW : ATTR_FONT_SHADOWED, bSkipPoolDefs );
     998             :     }
     999         304 :     if( maUsedFlags.mbEscapementUsed )
    1000             :     {
    1001         288 :         SvxEscapement eScEscapem = SVX_ESCAPEMENT_OFF;
    1002         288 :         if ( maApiData.mnEscapement == API_ESCAPE_SUPERSCRIPT )
    1003           0 :             eScEscapem = SVX_ESCAPEMENT_SUPERSCRIPT;
    1004         288 :         else if ( maApiData.mnEscapement == API_ESCAPE_SUBSCRIPT )
    1005           0 :             eScEscapem = SVX_ESCAPEMENT_SUBSCRIPT;
    1006         288 :         if( ePropType == FONT_PROPTYPE_TEXT && bEdit )
    1007             :         {
    1008             :            // #TODO handle EscapementHeight
    1009           2 :             rItemSet.Put( SvxEscapementItem( eScEscapem, EE_CHAR_ESCAPEMENT ) );
    1010             :         }
    1011             :     }
    1012         304 : }
    1013             : 
    1014         136 : void Font::writeToPropertyMap( PropertyMap& rPropMap, FontPropertyType ePropType ) const
    1015             : {
    1016             :     // font name properties
    1017         136 :     if( maUsedFlags.mbNameUsed )
    1018             :     {
    1019         136 :         if( !maApiData.maLatinFont.maName.isEmpty() )
    1020             :         {
    1021         136 :             rPropMap.setProperty( PROP_CharFontName, maApiData.maLatinFont.maName);
    1022         136 :             rPropMap.setProperty( PROP_CharFontFamily, maApiData.maLatinFont.mnFamily);
    1023         136 :             rPropMap.setProperty( PROP_CharFontCharSet, maApiData.maLatinFont.mnTextEnc);
    1024             :         }
    1025         136 :         if( !maApiData.maAsianFont.maName.isEmpty() )
    1026             :         {
    1027           0 :             rPropMap.setProperty( PROP_CharFontNameAsian, maApiData.maAsianFont.maName);
    1028           0 :             rPropMap.setProperty( PROP_CharFontFamilyAsian, maApiData.maAsianFont.mnFamily);
    1029           0 :             rPropMap.setProperty( PROP_CharFontCharSetAsian, maApiData.maAsianFont.mnTextEnc);
    1030             :         }
    1031         136 :         if( !maApiData.maCmplxFont.maName.isEmpty() )
    1032             :         {
    1033         136 :             rPropMap.setProperty( PROP_CharFontNameComplex, maApiData.maCmplxFont.maName);
    1034         136 :             rPropMap.setProperty( PROP_CharFontFamilyComplex, maApiData.maCmplxFont.mnFamily);
    1035         136 :             rPropMap.setProperty( PROP_CharFontCharSetComplex, maApiData.maCmplxFont.mnTextEnc);
    1036             :         }
    1037             :     }
    1038             :     // font height
    1039         136 :     if( maUsedFlags.mbHeightUsed )
    1040             :     {
    1041         136 :         float fHeight = static_cast< float >( maApiData.maDesc.Height / 20.0 ); // twips to points
    1042         136 :         rPropMap.setProperty( PROP_CharHeight, fHeight);
    1043         136 :         rPropMap.setProperty( PROP_CharHeightAsian, fHeight);
    1044         136 :         rPropMap.setProperty( PROP_CharHeightComplex, fHeight);
    1045             :     }
    1046             :     // font weight
    1047         136 :     if( maUsedFlags.mbWeightUsed )
    1048             :     {
    1049         136 :         float fWeight = maApiData.maDesc.Weight;
    1050         136 :         rPropMap.setProperty( PROP_CharWeight, fWeight);
    1051         136 :         rPropMap.setProperty( PROP_CharWeightAsian, fWeight);
    1052         136 :         rPropMap.setProperty( PROP_CharWeightComplex, fWeight);
    1053             :     }
    1054             :     // font posture
    1055         136 :     if( maUsedFlags.mbPostureUsed )
    1056             :     {
    1057         136 :         rPropMap.setProperty( PROP_CharPosture, maApiData.maDesc.Slant);
    1058         136 :         rPropMap.setProperty( PROP_CharPostureAsian, maApiData.maDesc.Slant);
    1059         136 :         rPropMap.setProperty( PROP_CharPostureComplex, maApiData.maDesc.Slant);
    1060             :     }
    1061             :     // character color
    1062         136 :     if( maUsedFlags.mbColorUsed )
    1063         136 :         rPropMap.setProperty( PROP_CharColor, maApiData.mnColor);
    1064             :     // underline style
    1065         136 :     if( maUsedFlags.mbUnderlineUsed )
    1066         136 :         rPropMap.setProperty( PROP_CharUnderline, maApiData.maDesc.Underline);
    1067             :     // strike out style
    1068         136 :     if( maUsedFlags.mbStrikeoutUsed )
    1069         136 :         rPropMap.setProperty( PROP_CharStrikeout, maApiData.maDesc.Strikeout);
    1070             :     // outline style
    1071         136 :     if( maUsedFlags.mbOutlineUsed )
    1072         136 :         rPropMap.setProperty( PROP_CharContoured, maApiData.mbOutline);
    1073             :     // shadow style
    1074         136 :     if( maUsedFlags.mbShadowUsed )
    1075         136 :         rPropMap.setProperty( PROP_CharShadowed, maApiData.mbShadow);
    1076             :     // escapement
    1077         136 :     if( maUsedFlags.mbEscapementUsed )
    1078             :     {
    1079         136 :         rPropMap.setProperty( PROP_CharEscapement, maApiData.mnEscapement);
    1080         136 :         if( ePropType == FONT_PROPTYPE_TEXT )
    1081         136 :             rPropMap.setProperty( PROP_CharEscapementHeight, maApiData.mnEscapeHeight);
    1082             :     }
    1083         136 : }
    1084             : 
    1085         136 : void Font::writeToPropertySet( PropertySet& rPropSet, FontPropertyType ePropType ) const
    1086             : {
    1087         136 :     PropertyMap aPropMap;
    1088         136 :     writeToPropertyMap( aPropMap, ePropType );
    1089         136 :     rPropSet.setProperties( aPropMap );
    1090         136 : }
    1091             : 
    1092        1758 : AlignmentModel::AlignmentModel() :
    1093             :     mnHorAlign( XML_general ),
    1094             :     mnVerAlign( XML_bottom ),
    1095             :     mnTextDir( OOX_XF_TEXTDIR_CONTEXT ),
    1096             :     mnRotation( OOX_XF_ROTATION_NONE ),
    1097             :     mnIndent( OOX_XF_INDENT_NONE ),
    1098             :     mbWrapText( false ),
    1099             :     mbShrink( false ),
    1100        1758 :     mbJustLastLine( false )
    1101             : {
    1102        1758 : }
    1103             : 
    1104           0 : void AlignmentModel::setBiffHorAlign( sal_uInt8 nHorAlign )
    1105             : {
    1106             :     static const sal_Int32 spnHorAligns[] = {
    1107             :         XML_general, XML_left, XML_center, XML_right,
    1108             :         XML_fill, XML_justify, XML_centerContinuous, XML_distributed };
    1109           0 :     mnHorAlign = STATIC_ARRAY_SELECT( spnHorAligns, nHorAlign, XML_general );
    1110           0 : }
    1111             : 
    1112           0 : void AlignmentModel::setBiffVerAlign( sal_uInt8 nVerAlign )
    1113             : {
    1114             :     static const sal_Int32 spnVerAligns[] = {
    1115             :         XML_top, XML_center, XML_bottom, XML_justify, XML_distributed };
    1116           0 :     mnVerAlign = STATIC_ARRAY_SELECT( spnVerAligns, nVerAlign, XML_bottom );
    1117           0 : }
    1118             : 
    1119        1758 : ApiAlignmentData::ApiAlignmentData() :
    1120             :     meHorJustify( ::com::sun::star::table::CellHoriJustify_STANDARD ),
    1121             :     mnHorJustifyMethod( ::com::sun::star::table::CellJustifyMethod::AUTO ),
    1122             :     mnVerJustify( ::com::sun::star::table::CellVertJustify2::STANDARD ),
    1123             :     mnVerJustifyMethod( ::com::sun::star::table::CellJustifyMethod::AUTO ),
    1124             :     meOrientation( ::com::sun::star::table::CellOrientation_STANDARD ),
    1125             :     mnRotation( 0 ),
    1126             :     mnWritingMode( ::com::sun::star::text::WritingMode2::PAGE ),
    1127             :     mnIndent( 0 ),
    1128             :     mbWrapText( false ),
    1129        1758 :     mbShrink( false )
    1130             : {
    1131        1758 : }
    1132             : 
    1133         318 : bool operator==( const ApiAlignmentData& rLeft, const ApiAlignmentData& rRight )
    1134             : {
    1135             :     return
    1136         636 :         (rLeft.meHorJustify  == rRight.meHorJustify) &&
    1137         636 :         (rLeft.mnHorJustifyMethod == rRight.mnHorJustifyMethod) &&
    1138         636 :         (rLeft.mnVerJustify  == rRight.mnVerJustify) &&
    1139         636 :         (rLeft.mnVerJustifyMethod == rRight.mnVerJustifyMethod) &&
    1140         636 :         (rLeft.meOrientation == rRight.meOrientation) &&
    1141         636 :         (rLeft.mnRotation    == rRight.mnRotation) &&
    1142         636 :         (rLeft.mnWritingMode == rRight.mnWritingMode) &&
    1143         636 :         (rLeft.mnIndent      == rRight.mnIndent) &&
    1144         954 :         (rLeft.mbWrapText    == rRight.mbWrapText) &&
    1145         636 :         (rLeft.mbShrink      == rRight.mbShrink);
    1146             : }
    1147             : 
    1148        1758 : Alignment::Alignment( const WorkbookHelper& rHelper ) :
    1149        1758 :     WorkbookHelper( rHelper )
    1150             : {
    1151        1758 : }
    1152             : 
    1153         298 : void Alignment::importAlignment( const AttributeList& rAttribs )
    1154             : {
    1155         298 :     maModel.mnHorAlign     = rAttribs.getToken( XML_horizontal, XML_general );
    1156         298 :     maModel.mnVerAlign     = rAttribs.getToken( XML_vertical, XML_bottom );
    1157         298 :     maModel.mnTextDir      = rAttribs.getInteger( XML_readingOrder, OOX_XF_TEXTDIR_CONTEXT );
    1158         298 :     maModel.mnRotation     = rAttribs.getInteger( XML_textRotation, OOX_XF_ROTATION_NONE );
    1159         298 :     maModel.mnIndent       = rAttribs.getInteger( XML_indent, OOX_XF_INDENT_NONE );
    1160         298 :     maModel.mbWrapText     = rAttribs.getBool( XML_wrapText, false );
    1161         298 :     maModel.mbShrink       = rAttribs.getBool( XML_shrinkToFit, false );
    1162         298 :     maModel.mbJustLastLine = rAttribs.getBool( XML_justifyLastLine, false );
    1163         298 : }
    1164             : 
    1165           0 : void Alignment::setBiff12Data( sal_uInt32 nFlags )
    1166             : {
    1167           0 :     maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 16, 3 ) );
    1168           0 :     maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nFlags, 19, 3 ) );
    1169           0 :     maModel.mnTextDir      = extractValue< sal_Int32 >( nFlags, 26, 2 );
    1170           0 :     maModel.mnRotation     = extractValue< sal_Int32 >( nFlags, 0, 8 );
    1171           0 :     maModel.mnIndent       = extractValue< sal_uInt8 >( nFlags, 8, 8 );
    1172           0 :     maModel.mbWrapText     = getFlag( nFlags, BIFF12_XF_WRAPTEXT );
    1173           0 :     maModel.mbShrink       = getFlag( nFlags, BIFF12_XF_SHRINK );
    1174           0 :     maModel.mbJustLastLine = getFlag( nFlags, BIFF12_XF_JUSTLASTLINE );
    1175           0 : }
    1176             : 
    1177        1758 : void Alignment::finalizeImport()
    1178             : {
    1179             :     namespace csstab = ::com::sun::star::table;
    1180             :     namespace csstxt = ::com::sun::star::text;
    1181             : 
    1182             :     // horizontal alignment
    1183        1758 :     switch( maModel.mnHorAlign )
    1184             :     {
    1185          20 :         case XML_center:            maApiData.meHorJustify = csstab::CellHoriJustify_CENTER;    break;
    1186           0 :         case XML_centerContinuous:  maApiData.meHorJustify = csstab::CellHoriJustify_CENTER;    break;
    1187           0 :         case XML_distributed:       maApiData.meHorJustify = csstab::CellHoriJustify_BLOCK;     break;
    1188           0 :         case XML_fill:              maApiData.meHorJustify = csstab::CellHoriJustify_REPEAT;    break;
    1189        1696 :         case XML_general:           maApiData.meHorJustify = csstab::CellHoriJustify_STANDARD;  break;
    1190           0 :         case XML_justify:           maApiData.meHorJustify = csstab::CellHoriJustify_BLOCK;     break;
    1191          34 :         case XML_left:              maApiData.meHorJustify = csstab::CellHoriJustify_LEFT;      break;
    1192           8 :         case XML_right:             maApiData.meHorJustify = csstab::CellHoriJustify_RIGHT;     break;
    1193             :     }
    1194             : 
    1195        1758 :     if (maModel.mnHorAlign == XML_distributed)
    1196           0 :         maApiData.mnHorJustifyMethod = csstab::CellJustifyMethod::DISTRIBUTE;
    1197             : 
    1198             :     // vertical alignment
    1199        1758 :     switch( maModel.mnVerAlign )
    1200             :     {
    1201        1730 :         case XML_bottom:        maApiData.mnVerJustify = csstab::CellVertJustify2::BOTTOM;    break;
    1202          24 :         case XML_center:        maApiData.mnVerJustify = csstab::CellVertJustify2::CENTER;    break;
    1203           0 :         case XML_distributed:   maApiData.mnVerJustify = csstab::CellVertJustify2::BLOCK;     break;
    1204           0 :         case XML_justify:       maApiData.mnVerJustify = csstab::CellVertJustify2::BLOCK;     break;
    1205           4 :         case XML_top:           maApiData.mnVerJustify = csstab::CellVertJustify2::TOP;       break;
    1206             :     }
    1207             : 
    1208        1758 :     if (maModel.mnVerAlign == XML_distributed)
    1209           0 :         maApiData.mnVerJustifyMethod = csstab::CellJustifyMethod::DISTRIBUTE;
    1210             : 
    1211             :     /*  indentation: expressed as number of blocks of 3 space characters in
    1212             :         OOXML/BIFF12, and as multiple of 10 points in BIFF8. */
    1213        1758 :     sal_Int32 nIndent = 0;
    1214        1758 :     switch( getFilterType() )
    1215             :     {
    1216        1758 :         case FILTER_OOXML:  nIndent = getUnitConverter().scaleToMm100( 3.0 * maModel.mnIndent, UNIT_SPACE );  break;
    1217           0 :         case FILTER_BIFF:   nIndent = getUnitConverter().scaleToMm100( 10.0 * maModel.mnIndent, UNIT_POINT ); break;
    1218           0 :         case FILTER_UNKNOWN: break;
    1219             :     }
    1220        1758 :     if( (0 <= nIndent) && (nIndent <= SAL_MAX_INT16) )
    1221        1758 :         maApiData.mnIndent = static_cast< sal_Int16 >( nIndent );
    1222             : 
    1223             :     // complex text direction
    1224        1758 :     switch( maModel.mnTextDir )
    1225             :     {
    1226        1758 :         case OOX_XF_TEXTDIR_CONTEXT:    maApiData.mnWritingMode = csstxt::WritingMode2::PAGE;   break;
    1227           0 :         case OOX_XF_TEXTDIR_LTR:        maApiData.mnWritingMode = csstxt::WritingMode2::LR_TB;  break;
    1228           0 :         case OOX_XF_TEXTDIR_RTL:        maApiData.mnWritingMode = csstxt::WritingMode2::RL_TB;  break;
    1229             :     }
    1230             : 
    1231             :     // rotation: 0-90 means 0 to 90 degrees ccw, 91-180 means 1 to 90 degrees cw, 255 means stacked
    1232        1758 :     sal_Int32 nOoxRot = maModel.mnRotation;
    1233        1758 :     maApiData.mnRotation = ((0 <= nOoxRot) && (nOoxRot <= 90)) ?
    1234             :         (100 * nOoxRot) :
    1235        3516 :         (((91 <= nOoxRot) && (nOoxRot <= 180)) ? (100 * (450 - nOoxRot)) : 0);
    1236             : 
    1237             :     // "Orientation" property used for character stacking
    1238             :     maApiData.meOrientation = (nOoxRot == OOX_XF_ROTATION_STACKED) ?
    1239        1758 :         csstab::CellOrientation_STACKED : csstab::CellOrientation_STANDARD;
    1240             : 
    1241             :     // alignment flags (#i84960 automatic line break, if vertically justified/distributed)
    1242        1758 :     maApiData.mbWrapText = maModel.mbWrapText || (maModel.mnVerAlign == XML_distributed) || (maModel.mnVerAlign == XML_justify);
    1243        1758 :     maApiData.mbShrink = maModel.mbShrink;
    1244             : 
    1245        1758 : }
    1246             : 
    1247         168 : ::SvxCellVerJustify Alignment::GetScVerAlign() const
    1248             : {
    1249             :     namespace csstab = ::com::sun::star::table;
    1250         168 :     ::SvxCellVerJustify nVert = ::SVX_VER_JUSTIFY_STANDARD;
    1251         168 :     switch ( maApiData.mnVerJustify )
    1252             :     {
    1253             :         case csstab::CellVertJustify2::BOTTOM:
    1254         140 :             nVert = ::SVX_VER_JUSTIFY_BOTTOM;
    1255         140 :             break;
    1256             :         case csstab::CellVertJustify2::CENTER:
    1257          24 :             nVert = ::SVX_VER_JUSTIFY_CENTER;
    1258          24 :             break;
    1259             :         case csstab::CellVertJustify2::TOP:
    1260           4 :             nVert = ::SVX_VER_JUSTIFY_TOP;
    1261           4 :             break;
    1262             :         case csstab::CellVertJustify2::BLOCK:
    1263           0 :             nVert = ::SVX_VER_JUSTIFY_BLOCK;
    1264           0 :             break;
    1265             :         case csstab::CellVertJustify2::STANDARD:
    1266             :         default:
    1267           0 :             nVert = ::SVX_VER_JUSTIFY_STANDARD;
    1268           0 :             break;
    1269             :     }
    1270         168 :     return nVert;
    1271             : }
    1272             : 
    1273         168 : ::SvxCellHorJustify Alignment::GetScHorAlign() const
    1274             : {
    1275             :     namespace csstab = ::com::sun::star::table;
    1276         168 :     ::SvxCellHorJustify nHori = ::SVX_HOR_JUSTIFY_STANDARD;
    1277         168 :     switch( maApiData.meHorJustify )
    1278             :     {
    1279             :         case csstab::CellHoriJustify_LEFT:
    1280           4 :             nHori = ::SVX_HOR_JUSTIFY_LEFT;
    1281           4 :             break;
    1282             :         case csstab::CellHoriJustify_CENTER:
    1283          20 :             nHori = ::SVX_HOR_JUSTIFY_CENTER;
    1284          20 :             break;
    1285             :         case csstab::CellHoriJustify_RIGHT:
    1286           8 :             nHori = ::SVX_HOR_JUSTIFY_RIGHT;
    1287           8 :             break;
    1288             :         case csstab::CellHoriJustify_BLOCK:
    1289           0 :             nHori = ::SVX_HOR_JUSTIFY_BLOCK;
    1290           0 :             break;
    1291             :         case csstab::CellHoriJustify_REPEAT:
    1292           0 :             nHori = ::SVX_HOR_JUSTIFY_REPEAT;
    1293           0 :             break;
    1294             :         case csstab::CellHoriJustify_STANDARD:
    1295             :         default:
    1296         136 :             nHori = ::SVX_HOR_JUSTIFY_STANDARD;
    1297         136 :             break;
    1298             :     }
    1299         168 :     return nHori;
    1300             : }
    1301             : 
    1302         168 : ::SvxFrameDirection Alignment::GetScFrameDir() const
    1303             : {
    1304             :     namespace csstxt = ::com::sun::star::text;
    1305         168 :     ::SvxFrameDirection eFrameDir = ::FRMDIR_ENVIRONMENT;
    1306         168 :     switch( maApiData.mnWritingMode )
    1307             :     {
    1308             :         case csstxt::WritingMode2::PAGE:
    1309         168 :             eFrameDir = ::FRMDIR_ENVIRONMENT;
    1310         168 :             break;
    1311             :         case csstxt::WritingMode2::LR_TB:
    1312           0 :             eFrameDir = ::FRMDIR_HORI_LEFT_TOP;
    1313           0 :             break;
    1314             :         case csstxt::WritingMode2::RL_TB:
    1315           0 :             eFrameDir = ::FRMDIR_HORI_RIGHT_TOP;
    1316           0 :             break;
    1317             :         default:
    1318             :             OSL_FAIL( "GetScFrameDir - unknown CTL text direction" );
    1319             :     }
    1320         168 :     return eFrameDir;
    1321             : }
    1322             : 
    1323         168 : void Alignment::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
    1324             : {
    1325             :     namespace csstab = ::com::sun::star::table;
    1326             :     // horizontal alignment
    1327         168 :     ScfTools::PutItem( rItemSet, SvxHorJustifyItem( GetScHorAlign(), ATTR_HOR_JUSTIFY ), bSkipPoolDefs );
    1328         168 :     ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( ( maApiData.mnHorJustifyMethod == csstab::CellJustifyMethod::DISTRIBUTE ) ? ::SVX_JUSTIFY_METHOD_DISTRIBUTE : ::SVX_JUSTIFY_METHOD_AUTO, ATTR_HOR_JUSTIFY_METHOD ), bSkipPoolDefs );
    1329         168 :     ScfTools::PutItem( rItemSet, SvxVerJustifyItem( GetScVerAlign(), ATTR_VER_JUSTIFY ), bSkipPoolDefs );
    1330             :     // vertical alignment
    1331         168 :     ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( ( maApiData.mnVerJustifyMethod == csstab::CellJustifyMethod::DISTRIBUTE ) ? ::SVX_JUSTIFY_METHOD_DISTRIBUTE : ::SVX_JUSTIFY_METHOD_AUTO, ATTR_VER_JUSTIFY_METHOD ), bSkipPoolDefs );
    1332             : 
    1333             :     // CTL text direction
    1334         168 :     ScfTools::PutItem( rItemSet, SvxFrameDirectionItem( GetScFrameDir(), ATTR_WRITINGDIR ), bSkipPoolDefs );
    1335             :     // set an angle in the range from -90 to 90 degrees
    1336         168 :     ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, maApiData.mnRotation ), bSkipPoolDefs );
    1337             :     // Orientation
    1338         168 :     ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, maApiData.meOrientation == csstab::CellOrientation_STACKED ), bSkipPoolDefs );
    1339             :     // indent
    1340         168 :     ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_INDENT, maApiData.mnIndent ), bSkipPoolDefs );
    1341             :     // line wrap
    1342         168 :     ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_LINEBREAK, maApiData.mbWrapText ), bSkipPoolDefs );
    1343         168 :     ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_SHRINKTOFIT, maApiData.mbShrink ), bSkipPoolDefs );
    1344         168 : }
    1345             : 
    1346           0 : void Alignment::writeToPropertyMap( PropertyMap& rPropMap ) const
    1347             : {
    1348           0 :     rPropMap.setProperty( PROP_HoriJustify, maApiData.meHorJustify);
    1349           0 :     rPropMap.setProperty( PROP_HoriJustifyMethod, maApiData.mnHorJustifyMethod);
    1350           0 :     rPropMap.setProperty( PROP_VertJustify, maApiData.mnVerJustify);
    1351           0 :     rPropMap.setProperty( PROP_VertJustifyMethod, maApiData.mnVerJustifyMethod);
    1352           0 :     rPropMap.setProperty( PROP_WritingMode, maApiData.mnWritingMode);
    1353           0 :     rPropMap.setProperty( PROP_RotateAngle, maApiData.mnRotation);
    1354           0 :     rPropMap.setProperty( PROP_Orientation, maApiData.meOrientation);
    1355           0 :     rPropMap.setProperty( PROP_ParaIndent, maApiData.mnIndent);
    1356           0 :     rPropMap.setProperty( PROP_IsTextWrapped, maApiData.mbWrapText);
    1357           0 :     rPropMap.setProperty( PROP_ShrinkToFit, maApiData.mbShrink);
    1358           0 : }
    1359             : 
    1360        1758 : ProtectionModel::ProtectionModel() :
    1361             :     mbLocked( true ),   // default in Excel and Calc
    1362        1758 :     mbHidden( false )
    1363             : {
    1364        1758 : }
    1365             : 
    1366        1758 : ApiProtectionData::ApiProtectionData() :
    1367        1758 :     maCellProt( sal_True, sal_False, sal_False, sal_False )
    1368             : {
    1369        1758 : }
    1370             : 
    1371         268 : bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight )
    1372             : {
    1373             :     return
    1374         536 :         (rLeft.maCellProt.IsLocked        == rRight.maCellProt.IsLocked) &&
    1375         536 :         (rLeft.maCellProt.IsFormulaHidden == rRight.maCellProt.IsFormulaHidden) &&
    1376         804 :         (rLeft.maCellProt.IsHidden        == rRight.maCellProt.IsHidden) &&
    1377         536 :         (rLeft.maCellProt.IsPrintHidden   == rRight.maCellProt.IsPrintHidden);
    1378             : }
    1379             : 
    1380        1758 : Protection::Protection( const WorkbookHelper& rHelper ) :
    1381        1758 :     WorkbookHelper( rHelper )
    1382             : {
    1383        1758 : }
    1384             : 
    1385         250 : void Protection::importProtection( const AttributeList& rAttribs )
    1386             : {
    1387         250 :     maModel.mbLocked = rAttribs.getBool( XML_locked, true );
    1388         250 :     maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
    1389         250 : }
    1390             : 
    1391           0 : void Protection::setBiff12Data( sal_uInt32 nFlags )
    1392             : {
    1393           0 :     maModel.mbLocked = getFlag( nFlags, BIFF12_XF_LOCKED );
    1394           0 :     maModel.mbHidden = getFlag( nFlags, BIFF12_XF_HIDDEN );
    1395           0 : }
    1396             : 
    1397        1758 : void Protection::finalizeImport()
    1398             : {
    1399        1758 :     maApiData.maCellProt.IsLocked = maModel.mbLocked;
    1400        1758 :     maApiData.maCellProt.IsFormulaHidden = maModel.mbHidden;
    1401        1758 : }
    1402             : 
    1403           2 : void Protection::writeToPropertyMap( PropertyMap& rPropMap ) const
    1404             : {
    1405           2 :     rPropMap.setProperty( PROP_CellProtection, maApiData.maCellProt);
    1406           2 : }
    1407             : 
    1408         214 : void Protection::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
    1409             : {
    1410         214 :     ScfTools::PutItem( rItemSet, ScProtectionAttr( maApiData.maCellProt.IsLocked, maApiData.maCellProt.IsFormulaHidden ), bSkipPoolDefs );
    1411         214 : }
    1412             : 
    1413             : namespace {
    1414             : 
    1415           8 : bool lcl_isBorder(const ::com::sun::star::table::BorderLine& rBorder)
    1416             : {
    1417           8 :     return (rBorder.InnerLineWidth > 0) || (rBorder.OuterLineWidth > 0);
    1418             : }
    1419             : 
    1420             : }
    1421             : 
    1422        1250 : BorderLineModel::BorderLineModel( bool bDxf ) :
    1423             :     mnStyle( XML_none ),
    1424        1250 :     mbUsed( !bDxf )
    1425             : {
    1426        1250 :     maColor.setIndexed( OOX_COLOR_WINDOWTEXT );
    1427        1250 : }
    1428             : 
    1429           0 : void BorderLineModel::setBiffStyle( sal_Int32 nLineStyle )
    1430             : {
    1431             :     static const sal_Int32 spnStyleIds[] = {
    1432             :         XML_none, XML_thin, XML_medium, XML_dashed,
    1433             :         XML_dotted, XML_thick, XML_double, XML_hair,
    1434             :         XML_mediumDashed, XML_dashDot, XML_mediumDashDot, XML_dashDotDot,
    1435             :         XML_mediumDashDotDot, XML_slantDashDot };
    1436           0 :     mnStyle = STATIC_ARRAY_SELECT( spnStyleIds, nLineStyle, XML_none );
    1437           0 : }
    1438             : 
    1439         250 : BorderModel::BorderModel( bool bDxf ) :
    1440             :     maLeft( bDxf ),
    1441             :     maRight( bDxf ),
    1442             :     maTop( bDxf ),
    1443             :     maBottom( bDxf ),
    1444             :     maDiagonal( bDxf ),
    1445             :     mbDiagTLtoBR( false ),
    1446         250 :     mbDiagBLtoTR( false )
    1447             : {
    1448         250 : }
    1449             : 
    1450         250 : ApiBorderData::ApiBorderData() :
    1451             :     mbBorderUsed( false ),
    1452         250 :     mbDiagUsed( false )
    1453             : {
    1454         250 : }
    1455             : 
    1456           2 : bool ApiBorderData::hasAnyOuterBorder() const
    1457             : {
    1458             :     return
    1459           4 :         ( ( lcl_isBorder( maTop ) &&  maTop.OuterLineWidth > 0 ) ) ||
    1460           4 :         ( ( lcl_isBorder( maBottom ) && maBottom.OuterLineWidth > 0 ) ) ||
    1461           6 :         ( ( lcl_isBorder( maLeft ) && maLeft.OuterLineWidth > 0 ) ) ||
    1462           4 :         ( ( lcl_isBorder( maRight ) && maRight.OuterLineWidth > 0 ) );
    1463             : }
    1464             : 
    1465             : namespace {
    1466             : 
    1467           0 : bool operator==( const BorderLine& rLeft, const BorderLine& rRight )
    1468             : {
    1469             :     return
    1470           0 :         (rLeft.Color          == rRight.Color) &&
    1471           0 :         (rLeft.InnerLineWidth == rRight.InnerLineWidth) &&
    1472           0 :         (rLeft.OuterLineWidth == rRight.OuterLineWidth) &&
    1473           0 :         (rLeft.LineDistance   == rRight.LineDistance);
    1474             : }
    1475             : 
    1476             : } // namespace
    1477             : 
    1478           0 : bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight )
    1479             : {
    1480             :     return
    1481           0 :         (rLeft.maLeft       == rRight.maLeft)   &&
    1482           0 :         (rLeft.maRight      == rRight.maRight)  &&
    1483           0 :         (rLeft.maTop        == rRight.maTop)    &&
    1484           0 :         (rLeft.maBottom     == rRight.maBottom) &&
    1485           0 :         (rLeft.maTLtoBR     == rRight.maTLtoBR) &&
    1486           0 :         (rLeft.maBLtoTR     == rRight.maBLtoTR) &&
    1487           0 :         (rLeft.mbBorderUsed == rRight.mbBorderUsed) &&
    1488           0 :         (rLeft.mbDiagUsed   == rRight.mbDiagUsed);
    1489             : }
    1490             : 
    1491             : namespace {
    1492             : 
    1493        1000 : inline void lclSetBorderLineWidth( BorderLine& rBorderLine,
    1494             :         sal_Int16 nOuter, sal_Int16 nDist = API_LINE_NONE, sal_Int16 nInner = API_LINE_NONE )
    1495             : {
    1496        1000 :     rBorderLine.OuterLineWidth = nOuter;
    1497        1000 :     rBorderLine.LineDistance = nDist;
    1498        1000 :     rBorderLine.InnerLineWidth = nInner;
    1499        1000 : }
    1500             : 
    1501             : } // namespace
    1502             : 
    1503         250 : Border::Border( const WorkbookHelper& rHelper, bool bDxf ) :
    1504             :     WorkbookHelper( rHelper ),
    1505             :     maModel( bDxf ),
    1506         250 :     mbDxf( bDxf )
    1507             : {
    1508         250 : }
    1509             : 
    1510         250 : void Border::importBorder( const AttributeList& rAttribs )
    1511             : {
    1512         250 :     maModel.mbDiagTLtoBR = rAttribs.getBool( XML_diagonalDown, false );
    1513         250 :     maModel.mbDiagBLtoTR = rAttribs.getBool( XML_diagonalUp, false );
    1514         250 : }
    1515             : 
    1516        1250 : void Border::importStyle( sal_Int32 nElement, const AttributeList& rAttribs )
    1517             : {
    1518        1250 :     if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
    1519             :     {
    1520        1250 :         pBorderLine->mnStyle = rAttribs.getToken( XML_style, XML_none );
    1521        1250 :         pBorderLine->mbUsed = true;
    1522             :     }
    1523        1250 : }
    1524             : 
    1525          34 : void Border::importColor( sal_Int32 nElement, const AttributeList& rAttribs )
    1526             : {
    1527          34 :     if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
    1528          34 :         pBorderLine->maColor.importColor( rAttribs );
    1529          34 : }
    1530             : 
    1531           0 : void Border::importBorder( SequenceInputStream& rStrm )
    1532             : {
    1533           0 :     sal_uInt8 nFlags = rStrm.readuInt8();
    1534           0 :     maModel.mbDiagTLtoBR = getFlag( nFlags, BIFF12_BORDER_DIAG_TLBR );
    1535           0 :     maModel.mbDiagBLtoTR = getFlag( nFlags, BIFF12_BORDER_DIAG_BLTR );
    1536           0 :     maModel.maTop.setBiffStyle( rStrm.readuInt16() );
    1537           0 :     rStrm >> maModel.maTop.maColor;
    1538           0 :     maModel.maBottom.setBiffStyle( rStrm.readuInt16() );
    1539           0 :     rStrm >> maModel.maBottom.maColor;
    1540           0 :     maModel.maLeft.setBiffStyle( rStrm.readuInt16() );
    1541           0 :     rStrm >> maModel.maLeft.maColor;
    1542           0 :     maModel.maRight.setBiffStyle( rStrm.readuInt16() );
    1543           0 :     rStrm >> maModel.maRight.maColor;
    1544           0 :     maModel.maDiagonal.setBiffStyle( rStrm.readuInt16() );
    1545           0 :     rStrm >> maModel.maDiagonal.maColor;
    1546           0 : }
    1547             : 
    1548           0 : void Border::importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm )
    1549             : {
    1550             :     SAL_WARN_IF( !mbDxf, "sc", "Border::importDxfBorder - missing conditional formatting flag" );
    1551           0 :     if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
    1552             :     {
    1553             :         sal_uInt16 nStyle;
    1554           0 :         rStrm >> pBorderLine->maColor >> nStyle;
    1555           0 :         pBorderLine->setBiffStyle( nStyle );
    1556           0 :         pBorderLine->mbUsed = true;
    1557             :     }
    1558           0 : }
    1559             : 
    1560         250 : void Border::finalizeImport( bool bRTL )
    1561             : {
    1562         250 :     if ( bRTL )
    1563             :     {
    1564           0 :         BorderLineModel aTmp = maModel.maLeft;
    1565           0 :         maModel.maLeft = maModel.maRight;
    1566           0 :         maModel.maRight = aTmp;
    1567             :     }
    1568         250 :     maApiData.mbBorderUsed = maModel.maLeft.mbUsed || maModel.maRight.mbUsed || maModel.maTop.mbUsed || maModel.maBottom.mbUsed;
    1569         250 :     maApiData.mbDiagUsed   = maModel.maDiagonal.mbUsed;
    1570             : 
    1571         250 :     convertBorderLine( maApiData.maLeft,   maModel.maLeft );
    1572         250 :     convertBorderLine( maApiData.maRight,  maModel.maRight );
    1573         250 :     convertBorderLine( maApiData.maTop,    maModel.maTop );
    1574         250 :     convertBorderLine( maApiData.maBottom, maModel.maBottom );
    1575             : 
    1576         250 :     if( maModel.mbDiagTLtoBR )
    1577           0 :         convertBorderLine( maApiData.maTLtoBR, maModel.maDiagonal );
    1578         250 :     if( maModel.mbDiagBLtoTR )
    1579           0 :         convertBorderLine( maApiData.maBLtoTR, maModel.maDiagonal );
    1580         250 : }
    1581             : 
    1582         314 : void Border::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
    1583             : {
    1584         314 :     if( maApiData.mbBorderUsed )
    1585             :     {
    1586         314 :          SvxBoxItem aBoxItem( ATTR_BORDER );
    1587         314 :          ::editeng::SvxBorderLine aLine;
    1588             : 
    1589         314 :          if (SvxBoxItem::LineToSvxLine(maApiData.maLeft, aLine, false))
    1590             :          {
    1591          58 :              aBoxItem.SetLine( &aLine, BOX_LINE_LEFT );
    1592             :          }
    1593         314 :          if (SvxBoxItem::LineToSvxLine(maApiData.maRight, aLine, false))
    1594             :          {
    1595          60 :              aBoxItem.SetLine( &aLine, BOX_LINE_RIGHT );
    1596             :          }
    1597         314 :          if (SvxBoxItem::LineToSvxLine(maApiData.maTop, aLine, false))
    1598             :          {
    1599         106 :              aBoxItem.SetLine( &aLine, BOX_LINE_TOP );
    1600             :          }
    1601         314 :          if (SvxBoxItem::LineToSvxLine(maApiData.maBottom, aLine, false))
    1602             :          {
    1603          56 :              aBoxItem.SetLine( &aLine, BOX_LINE_BOTTOM );
    1604             :          }
    1605         314 :          ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs );
    1606             :     }
    1607         314 :     if ( maApiData.mbDiagUsed )
    1608             :     {
    1609         314 :         SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
    1610         628 :         SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
    1611         314 :         ::editeng::SvxBorderLine aLine;
    1612         314 :         if (SvxBoxItem::LineToSvxLine(maApiData.maTLtoBR, aLine, false))
    1613             :         {
    1614           0 :             aTLBRItem.SetLine( &aLine );
    1615             :         }
    1616         314 :         if (SvxBoxItem::LineToSvxLine(maApiData.maBLtoTR, aLine, false))
    1617             :         {
    1618           0 :             aBLTRItem.SetLine( &aLine );
    1619             :         }
    1620         314 :         ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs );
    1621         628 :         ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs );
    1622             :     }
    1623         314 : }
    1624             : 
    1625           0 : void Border::writeToPropertyMap( PropertyMap& rPropMap ) const
    1626             : {
    1627           0 :     if( maApiData.mbBorderUsed )
    1628             :     {
    1629           0 :         rPropMap.setProperty( PROP_LeftBorder, maApiData.maLeft);
    1630           0 :         rPropMap.setProperty( PROP_RightBorder, maApiData.maRight);
    1631           0 :         rPropMap.setProperty( PROP_TopBorder, maApiData.maTop);
    1632           0 :         rPropMap.setProperty( PROP_BottomBorder, maApiData.maBottom);
    1633             :     }
    1634           0 :     if( maApiData.mbDiagUsed )
    1635             :     {
    1636           0 :         rPropMap.setProperty( PROP_DiagonalTLBR, maApiData.maTLtoBR);
    1637           0 :         rPropMap.setProperty( PROP_DiagonalBLTR, maApiData.maBLtoTR);
    1638             :     }
    1639           0 : }
    1640             : 
    1641           0 : bool Border::hasBorder() const
    1642             : {
    1643           0 :     if (lcl_isBorder(maApiData.maBottom))
    1644           0 :         return true;
    1645             : 
    1646           0 :     if (lcl_isBorder(maApiData.maTop))
    1647           0 :         return true;
    1648             : 
    1649           0 :     if (lcl_isBorder(maApiData.maLeft))
    1650           0 :         return true;
    1651             : 
    1652           0 :     if (lcl_isBorder(maApiData.maRight))
    1653           0 :         return true;
    1654             : 
    1655           0 :     return false;
    1656             : }
    1657             : 
    1658        1284 : BorderLineModel* Border::getBorderLine( sal_Int32 nElement )
    1659             : {
    1660        1284 :     switch( nElement )
    1661             :     {
    1662         250 :         case XLS_TOKEN( left ):     return &maModel.maLeft;
    1663           2 :         case XLS_TOKEN( start ):     return &maModel.maLeft;
    1664         250 :         case XLS_TOKEN( right ):    return &maModel.maRight;
    1665           2 :         case XLS_TOKEN( end ):    return &maModel.maRight;
    1666         278 :         case XLS_TOKEN( top ):      return &maModel.maTop;
    1667         252 :         case XLS_TOKEN( bottom ):   return &maModel.maBottom;
    1668         250 :         case XLS_TOKEN( diagonal ): return &maModel.maDiagonal;
    1669             :     }
    1670           0 :     return 0;
    1671             : }
    1672             : 
    1673        1000 : bool Border::convertBorderLine( BorderLine2& rBorderLine, const BorderLineModel& rModel )
    1674             : {
    1675        1000 :     rBorderLine.Color = rModel.maColor.getColor( getBaseFilter().getGraphicHelper(), API_RGB_BLACK );
    1676        1000 :     switch( rModel.mnStyle )
    1677             :     {
    1678             :         case XML_dashDot:
    1679           4 :             lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
    1680           4 :             rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT;
    1681           4 :         break;
    1682             :         case XML_dashDotDot:
    1683           4 :             lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
    1684           4 :             rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT_DOT;
    1685           4 :         break;
    1686             :         case XML_dashed:
    1687           4 :             lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
    1688           4 :             rBorderLine.LineStyle = table::BorderLineStyle::FINE_DASHED;
    1689           4 :         break;
    1690             :         case XML_dotted:
    1691           4 :             lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
    1692           4 :             rBorderLine.LineStyle = table::BorderLineStyle::DOTTED;
    1693           4 :         break;
    1694             :         case XML_double:
    1695           4 :             lclSetBorderLineWidth( rBorderLine, 10, 30, 10 );
    1696           4 :             rBorderLine.LineStyle = table::BorderLineStyle::DOUBLE_THIN;
    1697           4 :         break;
    1698           4 :         case XML_hair:              lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR );    break;
    1699          72 :         case XML_medium:            lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );  break;
    1700             :         case XML_mediumDashDot:
    1701           4 :             lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
    1702           4 :             rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT;
    1703           4 :             break;
    1704             :         case XML_mediumDashDotDot:
    1705           4 :             lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
    1706           4 :             rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT_DOT;
    1707           4 :             break;
    1708             :         case XML_mediumDashed:
    1709           4 :             lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
    1710           4 :             rBorderLine.LineStyle = table::BorderLineStyle::DASHED;
    1711           4 :         break;
    1712         748 :         case XML_none:              lclSetBorderLineWidth( rBorderLine, API_LINE_NONE );    break;
    1713             :         case XML_slantDashDot:
    1714           2 :             lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
    1715           2 :             rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT;
    1716           2 :             break;
    1717           4 :         case XML_thick:             lclSetBorderLineWidth( rBorderLine, API_LINE_THICK );   break;
    1718         138 :         case XML_thin:              lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );    break;
    1719           0 :         default:                    lclSetBorderLineWidth( rBorderLine, API_LINE_NONE );    break;
    1720             :     }
    1721        1000 :     return rModel.mbUsed;
    1722             : }
    1723             : 
    1724         260 : PatternFillModel::PatternFillModel( bool bDxf ) :
    1725             :     mnPattern( XML_none ),
    1726         260 :     mbPattColorUsed( !bDxf ),
    1727         260 :     mbFillColorUsed( !bDxf ),
    1728         780 :     mbPatternUsed( !bDxf )
    1729             : {
    1730         260 :     maPatternColor.setIndexed( OOX_COLOR_WINDOWTEXT );
    1731         260 :     maFillColor.setIndexed( OOX_COLOR_WINDOWBACK );
    1732         260 : }
    1733             : 
    1734           0 : void PatternFillModel::setBiffPattern( sal_Int32 nPattern )
    1735             : {
    1736             :     static const sal_Int32 spnPatternIds[] = {
    1737             :         XML_none, XML_solid, XML_mediumGray, XML_darkGray,
    1738             :         XML_lightGray, XML_darkHorizontal, XML_darkVertical, XML_darkDown,
    1739             :         XML_darkUp, XML_darkGrid, XML_darkTrellis, XML_lightHorizontal,
    1740             :         XML_lightVertical, XML_lightDown, XML_lightUp, XML_lightGrid,
    1741             :         XML_lightTrellis, XML_gray125, XML_gray0625 };
    1742           0 :     mnPattern = STATIC_ARRAY_SELECT( spnPatternIds, nPattern, XML_none );
    1743           0 : }
    1744             : 
    1745           0 : GradientFillModel::GradientFillModel() :
    1746             :     mnType( XML_linear ),
    1747             :     mfAngle( 0.0 ),
    1748             :     mfLeft( 0.0 ),
    1749             :     mfRight( 0.0 ),
    1750             :     mfTop( 0.0 ),
    1751           0 :     mfBottom( 0.0 )
    1752             : {
    1753           0 : }
    1754             : 
    1755           0 : void GradientFillModel::readGradient( SequenceInputStream& rStrm )
    1756             : {
    1757             :     sal_Int32 nType;
    1758           0 :     rStrm >> nType >> mfAngle >> mfLeft >> mfRight >> mfTop >> mfBottom;
    1759             :     static const sal_Int32 spnTypes[] = { XML_linear, XML_path };
    1760           0 :     mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
    1761           0 : }
    1762             : 
    1763           0 : void GradientFillModel::readGradientStop( SequenceInputStream& rStrm, bool bDxf )
    1764             : {
    1765           0 :     Color aColor;
    1766             :     double fPosition;
    1767           0 :     if( bDxf )
    1768             :     {
    1769           0 :         rStrm.skip( 2 );
    1770           0 :         rStrm >> fPosition >> aColor;
    1771             :     }
    1772             :     else
    1773             :     {
    1774           0 :         rStrm >> aColor >> fPosition;
    1775             :     }
    1776           0 :     if( !rStrm.isEof() && (fPosition >= 0.0) )
    1777           0 :         maColors[ fPosition ] = aColor;
    1778           0 : }
    1779             : 
    1780         260 : ApiSolidFillData::ApiSolidFillData() :
    1781             :     mnColor( API_RGB_TRANSPARENT ),
    1782             :     mbTransparent( true ),
    1783         260 :     mbUsed( false )
    1784             : {
    1785         260 : }
    1786             : 
    1787           0 : bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight )
    1788             : {
    1789             :     return
    1790           0 :         (rLeft.mnColor       == rRight.mnColor) &&
    1791           0 :         (rLeft.mbTransparent == rRight.mbTransparent) &&
    1792           0 :         (rLeft.mbUsed        == rRight.mbUsed);
    1793             : }
    1794             : 
    1795             : namespace {
    1796             : 
    1797         396 : inline sal_Int32 lclGetMixedColorComp( sal_Int32 nPatt, sal_Int32 nFill, sal_Int32 nAlpha )
    1798             : {
    1799         396 :     return ((nPatt - nFill) * nAlpha) / 0x80 + nFill;
    1800             : }
    1801             : 
    1802         132 : sal_Int32 lclGetMixedColor( sal_Int32 nPattColor, sal_Int32 nFillColor, sal_Int32 nAlpha )
    1803             : {
    1804             :     return
    1805         264 :         (lclGetMixedColorComp( nPattColor & 0xFF0000, nFillColor & 0xFF0000, nAlpha ) & 0xFF0000) |
    1806         132 :         (lclGetMixedColorComp( nPattColor & 0x00FF00, nFillColor & 0x00FF00, nAlpha ) & 0x00FF00) |
    1807         132 :         (lclGetMixedColorComp( nPattColor & 0x0000FF, nFillColor & 0x0000FF, nAlpha ) & 0x0000FF);
    1808             : }
    1809             : 
    1810             : } // namespace
    1811             : 
    1812         260 : Fill::Fill( const WorkbookHelper& rHelper, bool bDxf ) :
    1813             :     WorkbookHelper( rHelper ),
    1814         260 :     mbDxf( bDxf )
    1815             : {
    1816         260 : }
    1817             : 
    1818         260 : void Fill::importPatternFill( const AttributeList& rAttribs )
    1819             : {
    1820         260 :     mxPatternModel.reset( new PatternFillModel( mbDxf ) );
    1821         260 :     mxPatternModel->mnPattern = rAttribs.getToken( XML_patternType, XML_none );
    1822         260 :     if( mbDxf )
    1823           0 :         mxPatternModel->mbPatternUsed = rAttribs.hasAttribute( XML_patternType );
    1824         260 : }
    1825             : 
    1826           4 : void Fill::importFgColor( const AttributeList& rAttribs )
    1827             : {
    1828             :     OSL_ENSURE( mxPatternModel.get(), "Fill::importFgColor - missing pattern data" );
    1829           4 :     if( mxPatternModel.get() )
    1830             :     {
    1831           4 :         mxPatternModel->maPatternColor.importColor( rAttribs );
    1832           4 :         mxPatternModel->mbPattColorUsed = true;
    1833             :     }
    1834           4 : }
    1835             : 
    1836           4 : void Fill::importBgColor( const AttributeList& rAttribs )
    1837             : {
    1838             :     OSL_ENSURE( mxPatternModel.get(), "Fill::importBgColor - missing pattern data" );
    1839           4 :     if( mxPatternModel.get() )
    1840             :     {
    1841           4 :         mxPatternModel->maFillColor.importColor( rAttribs );
    1842           4 :         mxPatternModel->mbFillColorUsed = true;
    1843             :     }
    1844           4 : }
    1845             : 
    1846           0 : void Fill::importGradientFill( const AttributeList& rAttribs )
    1847             : {
    1848           0 :     mxGradientModel.reset( new GradientFillModel );
    1849           0 :     mxGradientModel->mnType = rAttribs.getToken( XML_type, XML_linear );
    1850           0 :     mxGradientModel->mfAngle = rAttribs.getDouble( XML_degree, 0.0 );
    1851           0 :     mxGradientModel->mfLeft = rAttribs.getDouble( XML_left, 0.0 );
    1852           0 :     mxGradientModel->mfRight = rAttribs.getDouble( XML_right, 0.0 );
    1853           0 :     mxGradientModel->mfTop = rAttribs.getDouble( XML_top, 0.0 );
    1854           0 :     mxGradientModel->mfBottom = rAttribs.getDouble( XML_bottom, 0.0 );
    1855           0 : }
    1856             : 
    1857           0 : void Fill::importColor( const AttributeList& rAttribs, double fPosition )
    1858             : {
    1859             :     OSL_ENSURE( mxGradientModel.get(), "Fill::importColor - missing gradient data" );
    1860           0 :     if( mxGradientModel.get() && (fPosition >= 0.0) )
    1861           0 :         mxGradientModel->maColors[ fPosition ].importColor( rAttribs );
    1862           0 : }
    1863             : 
    1864           0 : void Fill::importFill( SequenceInputStream& rStrm )
    1865             : {
    1866             :     SAL_WARN_IF( mbDxf, "sc", "Fill::importFill - unexpected conditional formatting flag" );
    1867           0 :     sal_Int32 nPattern = rStrm.readInt32();
    1868           0 :     if( nPattern == BIFF12_FILL_GRADIENT )
    1869             :     {
    1870           0 :         mxGradientModel.reset( new GradientFillModel );
    1871             :         sal_Int32 nStopCount;
    1872           0 :         rStrm.skip( 16 );
    1873           0 :         mxGradientModel->readGradient( rStrm );
    1874           0 :         rStrm >> nStopCount;
    1875           0 :         for( sal_Int32 nStop = 0; (nStop < nStopCount) && !rStrm.isEof(); ++nStop )
    1876           0 :             mxGradientModel->readGradientStop( rStrm, false );
    1877             :     }
    1878             :     else
    1879             :     {
    1880           0 :         mxPatternModel.reset( new PatternFillModel( mbDxf ) );
    1881           0 :         mxPatternModel->setBiffPattern( nPattern );
    1882           0 :         rStrm >> mxPatternModel->maPatternColor >> mxPatternModel->maFillColor;
    1883             :     }
    1884           0 : }
    1885             : 
    1886           0 : void Fill::importDxfPattern( SequenceInputStream& rStrm )
    1887             : {
    1888             :     SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfPattern - missing conditional formatting flag" );
    1889           0 :     if( !mxPatternModel )
    1890           0 :         mxPatternModel.reset( new PatternFillModel( mbDxf ) );
    1891           0 :     mxPatternModel->setBiffPattern( rStrm.readuInt8() );
    1892           0 :     mxPatternModel->mbPatternUsed = true;
    1893           0 : }
    1894             : 
    1895           0 : void Fill::importDxfFgColor( SequenceInputStream& rStrm )
    1896             : {
    1897             :     SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfFgColor - missing conditional formatting flag" );
    1898           0 :     if( !mxPatternModel )
    1899           0 :         mxPatternModel.reset( new PatternFillModel( mbDxf ) );
    1900           0 :     mxPatternModel->maPatternColor.importColor( rStrm );
    1901           0 :     mxPatternModel->mbPattColorUsed = true;
    1902           0 : }
    1903             : 
    1904           0 : void Fill::importDxfBgColor( SequenceInputStream& rStrm )
    1905             : {
    1906             :     SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfBgColor - missing conditional formatting flag" );
    1907           0 :     if( !mxPatternModel )
    1908           0 :         mxPatternModel.reset( new PatternFillModel( mbDxf ) );
    1909           0 :     mxPatternModel->maFillColor.importColor( rStrm );
    1910           0 :     mxPatternModel->mbFillColorUsed = true;
    1911           0 : }
    1912             : 
    1913           0 : void Fill::importDxfGradient( SequenceInputStream& rStrm )
    1914             : {
    1915             :     SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfGradient - missing conditional formatting flag" );
    1916           0 :     if( !mxGradientModel )
    1917           0 :         mxGradientModel.reset( new GradientFillModel );
    1918           0 :     mxGradientModel->readGradient( rStrm );
    1919           0 : }
    1920             : 
    1921           0 : void Fill::importDxfStop( SequenceInputStream& rStrm )
    1922             : {
    1923             :     SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfStop - missing conditional formatting flag" );
    1924           0 :     if( !mxGradientModel )
    1925           0 :         mxGradientModel.reset( new GradientFillModel );
    1926           0 :     mxGradientModel->readGradientStop( rStrm, true );
    1927           0 : }
    1928             : 
    1929         260 : void Fill::finalizeImport()
    1930             : {
    1931         260 :     const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
    1932             : 
    1933         260 :     if( mxPatternModel.get() )
    1934             :     {
    1935             :         // finalize the OOXML data struct
    1936         260 :         PatternFillModel& rModel = *mxPatternModel;
    1937         260 :         if( mbDxf )
    1938             :         {
    1939           0 :             if( rModel.mbFillColorUsed && (!rModel.mbPatternUsed || (rModel.mnPattern == XML_solid)) )
    1940             :             {
    1941           0 :                 rModel.maPatternColor = rModel.maFillColor;
    1942           0 :                 rModel.mnPattern = XML_solid;
    1943           0 :                 rModel.mbPattColorUsed = rModel.mbPatternUsed = true;
    1944             :             }
    1945           0 :             else if( !rModel.mbFillColorUsed && rModel.mbPatternUsed && (rModel.mnPattern == XML_solid) )
    1946             :             {
    1947           0 :                 rModel.mbPatternUsed = false;
    1948             :             }
    1949             :         }
    1950             : 
    1951             :         // convert to API fill settings
    1952         260 :         maApiData.mbUsed = rModel.mbPatternUsed;
    1953         260 :         if( rModel.mnPattern == XML_none )
    1954             :         {
    1955         128 :             maApiData.mnColor = API_RGB_TRANSPARENT;
    1956         128 :             maApiData.mbTransparent = true;
    1957             :         }
    1958             :         else
    1959             :         {
    1960         132 :             sal_Int32 nAlpha = 0x80;
    1961         132 :             switch( rModel.mnPattern )
    1962             :             {
    1963           0 :                 case XML_darkDown:          nAlpha = 0x40;  break;
    1964           0 :                 case XML_darkGray:          nAlpha = 0x60;  break;
    1965           0 :                 case XML_darkGrid:          nAlpha = 0x40;  break;
    1966           0 :                 case XML_darkHorizontal:    nAlpha = 0x40;  break;
    1967           0 :                 case XML_darkTrellis:       nAlpha = 0x60;  break;
    1968           0 :                 case XML_darkUp:            nAlpha = 0x40;  break;
    1969           0 :                 case XML_darkVertical:      nAlpha = 0x40;  break;
    1970           0 :                 case XML_gray0625:          nAlpha = 0x08;  break;
    1971         128 :                 case XML_gray125:           nAlpha = 0x10;  break;
    1972           0 :                 case XML_lightDown:         nAlpha = 0x20;  break;
    1973           0 :                 case XML_lightGray:         nAlpha = 0x20;  break;
    1974           0 :                 case XML_lightGrid:         nAlpha = 0x38;  break;
    1975           0 :                 case XML_lightHorizontal:   nAlpha = 0x20;  break;
    1976           0 :                 case XML_lightTrellis:      nAlpha = 0x30;  break;
    1977           0 :                 case XML_lightUp:           nAlpha = 0x20;  break;
    1978           0 :                 case XML_lightVertical:     nAlpha = 0x20;  break;
    1979           0 :                 case XML_mediumGray:        nAlpha = 0x40;  break;
    1980           4 :                 case XML_solid:             nAlpha = 0x80;  break;
    1981             :             }
    1982             : 
    1983         132 :             sal_Int32 nWinTextColor = rGraphicHelper.getSystemColor( XML_windowText );
    1984         132 :             sal_Int32 nWinColor = rGraphicHelper.getSystemColor( XML_window );
    1985             : 
    1986         132 :             if( !rModel.mbPattColorUsed )
    1987           0 :                 rModel.maPatternColor.setAuto();
    1988         132 :             sal_Int32 nPattColor = rModel.maPatternColor.getColor( rGraphicHelper, nWinTextColor );
    1989             : 
    1990         132 :             if( !rModel.mbFillColorUsed )
    1991           0 :                 rModel.maFillColor.setAuto();
    1992         132 :             sal_Int32 nFillColor = rModel.maFillColor.getColor( rGraphicHelper, nWinColor );
    1993             : 
    1994         132 :             maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha );
    1995         132 :             maApiData.mbTransparent = false;
    1996             :         }
    1997             :     }
    1998           0 :     else if( mxGradientModel.get() && !mxGradientModel->maColors.empty() )
    1999             :     {
    2000           0 :         GradientFillModel& rModel = *mxGradientModel;
    2001           0 :         maApiData.mbUsed = true;    // no support for differential attributes
    2002           0 :         GradientFillModel::ColorMap::const_iterator aIt = rModel.maColors.begin();
    2003             :         OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
    2004           0 :         maApiData.mnColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE );
    2005           0 :         if( ++aIt != rModel.maColors.end() )
    2006             :         {
    2007             :             OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
    2008           0 :             sal_Int32 nEndColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE );
    2009           0 :             maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 );
    2010           0 :             maApiData.mbTransparent = false;
    2011             :         }
    2012             :     }
    2013         260 : }
    2014             : 
    2015         144 : void Fill::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
    2016             : {
    2017         144 :     if( maApiData.mbUsed )
    2018             :     {
    2019         144 :         SvxBrushItem aBrushItem( ATTR_BACKGROUND );
    2020         144 :         if ( maApiData.mbTransparent )
    2021             :         {
    2022         140 :             aBrushItem.SetColor( ::Color( COL_TRANSPARENT ) );
    2023             :         }
    2024             :         else
    2025             :         {
    2026           4 :             aBrushItem.SetColor( maApiData.mnColor  );
    2027             :         }
    2028         144 :         ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
    2029             :     }
    2030         144 : }
    2031             : 
    2032           0 : void Fill::writeToPropertyMap( PropertyMap& rPropMap ) const
    2033             : {
    2034           0 :     if( maApiData.mbUsed )
    2035             :     {
    2036           0 :         rPropMap.setProperty( PROP_CellBackColor, maApiData.mnColor);
    2037           0 :         rPropMap.setProperty( PROP_IsCellBackgroundTransparent, maApiData.mbTransparent);
    2038             :     }
    2039           0 : }
    2040             : 
    2041        1758 : XfModel::XfModel() :
    2042             :     mnStyleXfId( -1 ),
    2043             :     mnFontId( -1 ),
    2044             :     mnNumFmtId( -1 ),
    2045             :     mnBorderId( -1 ),
    2046             :     mnFillId( -1 ),
    2047             :     mbCellXf( true ),
    2048             :     mbFontUsed( false ),
    2049             :     mbNumFmtUsed( false ),
    2050             :     mbAlignUsed( false ),
    2051             :     mbProtUsed( false ),
    2052             :     mbBorderUsed( false ),
    2053        1758 :     mbAreaUsed( false )
    2054             : {
    2055        1758 : }
    2056             : 
    2057         492 : Xf::AttrList::AttrList() : mbLatinNumFmtOnly(true) {}
    2058             : 
    2059        1758 : Xf::Xf( const WorkbookHelper& rHelper ) :
    2060             :     WorkbookHelper( rHelper ),
    2061             :     mnScNumFmt(0),
    2062             :     maAlignment( rHelper ),
    2063             :     maProtection( rHelper ),
    2064             :     meRotationRef( ::com::sun::star::table::CellVertJustify2::STANDARD ),
    2065        1758 :     mpStyleSheet( NULL )
    2066             : {
    2067        1758 : }
    2068             : 
    2069        1758 : void Xf::importXf( const AttributeList& rAttribs, bool bCellXf )
    2070             : {
    2071        1758 :     maModel.mbCellXf = bCellXf;
    2072        1758 :     maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 );
    2073        1758 :     maModel.mnFontId = rAttribs.getInteger( XML_fontId, -1 );
    2074        1758 :     maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 );
    2075        1758 :     maModel.mnBorderId = rAttribs.getInteger( XML_borderId, -1 );
    2076        1758 :     maModel.mnFillId = rAttribs.getInteger( XML_fillId, -1 );
    2077             : 
    2078             :     /*  Default value of the apply*** attributes is dependent on context:
    2079             :         true in cellStyleXfs element, false in cellXfs element... */
    2080        1758 :     maModel.mbAlignUsed  = rAttribs.getBool( XML_applyAlignment,    !maModel.mbCellXf );
    2081        1758 :     maModel.mbProtUsed   = rAttribs.getBool( XML_applyProtection,   !maModel.mbCellXf );
    2082        1758 :     maModel.mbFontUsed   = rAttribs.getBool( XML_applyFont,         !maModel.mbCellXf );
    2083        1758 :     maModel.mbNumFmtUsed = rAttribs.getBool( XML_applyNumberFormat, !maModel.mbCellXf );
    2084        1758 :     maModel.mbBorderUsed = rAttribs.getBool( XML_applyBorder,       !maModel.mbCellXf );
    2085        1758 :     maModel.mbAreaUsed   = rAttribs.getBool( XML_applyFill,         !maModel.mbCellXf );
    2086        1758 : }
    2087             : 
    2088         298 : void Xf::importAlignment( const AttributeList& rAttribs )
    2089             : {
    2090         298 :     maAlignment.importAlignment( rAttribs );
    2091         298 : }
    2092             : 
    2093         250 : void Xf::importProtection( const AttributeList& rAttribs )
    2094             : {
    2095         250 :     maProtection.importProtection( rAttribs );
    2096         250 : }
    2097             : 
    2098           0 : void Xf::importXf( SequenceInputStream& rStrm, bool bCellXf )
    2099             : {
    2100           0 :     maModel.mbCellXf = bCellXf;
    2101           0 :     maModel.mnStyleXfId = rStrm.readuInt16();
    2102           0 :     maModel.mnNumFmtId = rStrm.readuInt16();
    2103           0 :     maModel.mnFontId = rStrm.readuInt16();
    2104           0 :     maModel.mnFillId = rStrm.readuInt16();
    2105           0 :     maModel.mnBorderId = rStrm.readuInt16();
    2106           0 :     sal_uInt32 nFlags = rStrm.readuInt32();
    2107           0 :     maAlignment.setBiff12Data( nFlags );
    2108           0 :     maProtection.setBiff12Data( nFlags );
    2109             :     // used flags, see comments in Xf::setBiffUsedFlags()
    2110           0 :     sal_uInt16 nUsedFlags = rStrm.readuInt16();
    2111           0 :     maModel.mbFontUsed   = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_FONT_USED );
    2112           0 :     maModel.mbNumFmtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_NUMFMT_USED );
    2113           0 :     maModel.mbAlignUsed  = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_ALIGN_USED );
    2114           0 :     maModel.mbProtUsed   = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_PROT_USED );
    2115           0 :     maModel.mbBorderUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_BORDER_USED );
    2116           0 :     maModel.mbAreaUsed   = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_AREA_USED );
    2117           0 : }
    2118             : 
    2119        1758 : void Xf::finalizeImport()
    2120             : {
    2121             :     // alignment and protection
    2122        1758 :     maAlignment.finalizeImport();
    2123        1758 :     maProtection.finalizeImport();
    2124        1758 : }
    2125             : 
    2126        1382 : FontRef Xf::getFont() const
    2127             : {
    2128        1382 :     return getStyles().getFont( maModel.mnFontId );
    2129             : }
    2130             : 
    2131        1366 : void Xf::applyPatternToAttrList( AttrList& rAttrs, SCROW nRow1, SCROW nRow2, sal_Int32 nNumFmtId )
    2132             : {
    2133        1366 :     createPattern();
    2134        1366 :     ScPatternAttr& rPat = *mpPattern;
    2135        1366 :     ScDocument& rDoc = getScDocument();
    2136        1366 :     if ( isCellXf() )
    2137             :     {
    2138        1366 :         StylesBuffer& rStyles = getStyles();
    2139        1366 :         rStyles.createCellStyle( maModel.mnStyleXfId );
    2140             : 
    2141        1366 :         mpStyleSheet = rStyles.getCellStyleSheet( maModel.mnStyleXfId );
    2142        1366 :         if ( mpStyleSheet )
    2143             :         {
    2144             :             //rDoc.ApplySelectionStyle( static_cast<ScStyleSheet&>(*mpStyleSheet), rMarkData );
    2145        1304 :             rPat.SetStyleSheet(mpStyleSheet, false);
    2146             :         }
    2147             :         else
    2148             :         {
    2149          62 :             ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
    2150          62 :             if (pStylePool)
    2151             :             {
    2152             :                 ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>(
    2153             :                     pStylePool->Find(
    2154          62 :                         ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA));
    2155             : 
    2156          62 :                 if (pStyleSheet)
    2157          62 :                     rPat.SetStyleSheet( pStyleSheet, false );
    2158             :             }
    2159             :         }
    2160             :     }
    2161        1366 :     if ( nNumFmtId >= 0 )
    2162             :     {
    2163           0 :         ScPatternAttr aNumPat(rDoc.GetPool());
    2164           0 :         mnScNumFmt = getStyles().writeNumFmtToItemSet( aNumPat.GetItemSet(), nNumFmtId );
    2165           0 :         rPat.GetItemSet().Put(aNumPat.GetItemSet());
    2166             :     }
    2167             : 
    2168        1366 :     if (!sc::NumFmtUtil::isLatinScript(mnScNumFmt, rDoc))
    2169         154 :         rAttrs.mbLatinNumFmtOnly = false;
    2170             : 
    2171        1366 :     if (rPat.GetStyleName())
    2172             :     {
    2173             :         // Check for a gap between the last entry and this one.
    2174        1366 :         bool bHasGap = false;
    2175        1366 :         if (rAttrs.maAttrs.empty() && nRow1 > 0)
    2176             :             // First attribute range doesn't start at row 0.
    2177         254 :             bHasGap = true;
    2178             : 
    2179        1366 :         if (!rAttrs.maAttrs.empty() && rAttrs.maAttrs.back().nRow + 1 < nRow1)
    2180         248 :             bHasGap = true;
    2181             : 
    2182        1366 :         if (bHasGap)
    2183             :         {
    2184             :             // Fill this gap with the default pattern.
    2185             :             ScAttrEntry aEntry;
    2186         502 :             aEntry.nRow = nRow1 - 1;
    2187         502 :             aEntry.pPattern = rDoc.GetDefPattern();
    2188         502 :             rAttrs.maAttrs.push_back(aEntry);
    2189             : 
    2190             :             // Check if the default pattern is 'General'.
    2191         502 :             if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc))
    2192           0 :                 rAttrs.mbLatinNumFmtOnly = false;
    2193             :         }
    2194             : 
    2195             :         ScAttrEntry aEntry;
    2196        1366 :         aEntry.nRow = nRow2;
    2197        1366 :         aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(rPat));
    2198        1366 :         rAttrs.maAttrs.push_back(aEntry);
    2199             : 
    2200        1366 :         if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc))
    2201         154 :             rAttrs.mbLatinNumFmtOnly = false;
    2202             :     }
    2203        1366 : }
    2204             : 
    2205         190 : void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const
    2206             : {
    2207         190 :     StylesBuffer& rStyles = getStyles();
    2208             : 
    2209             :     // create and set cell style.
    2210             : 
    2211             :     // TODO : We should gradually move things to writeToDoc(), to set cell
    2212             :     // styles to the document directly.
    2213             : 
    2214         190 :     if( maModel.mbFontUsed )
    2215           0 :         rStyles.writeFontToPropertyMap( rPropMap, maModel.mnFontId );
    2216         190 :     if( maModel.mbNumFmtUsed )
    2217           0 :         rStyles.writeNumFmtToPropertyMap( rPropMap, maModel.mnNumFmtId );
    2218         190 :     if( maModel.mbAlignUsed )
    2219           0 :         maAlignment.writeToPropertyMap( rPropMap );
    2220         190 :     if( maModel.mbProtUsed )
    2221           2 :         maProtection.writeToPropertyMap( rPropMap );
    2222         190 :     if( maModel.mbBorderUsed )
    2223           0 :         rStyles.writeBorderToPropertyMap( rPropMap, maModel.mnBorderId );
    2224         190 :     if( maModel.mbAreaUsed )
    2225           0 :         rStyles.writeFillToPropertyMap( rPropMap, maModel.mnFillId );
    2226         190 : }
    2227             : 
    2228         190 : void Xf::writeToPropertySet( PropertySet& rPropSet ) const
    2229             : {
    2230         190 :     PropertyMap aPropMap;
    2231         190 :     writeToPropertyMap( aPropMap );
    2232         190 :     rPropSet.setProperties( aPropMap );
    2233         190 : }
    2234             : 
    2235         190 : void Xf::writeToDoc( ScDocumentImport& rDoc, const table::CellRangeAddress& rRange ) const
    2236             : {
    2237         190 :     const StylesBuffer& rStyles = getStyles();
    2238             : 
    2239         190 :     if (isCellXf())
    2240             :     {
    2241             :         // Cell style name.
    2242         190 :         OUString aStyleName = rStyles.createCellStyle(maModel.mnStyleXfId);
    2243             : 
    2244             :         ScStyleSheet* pStyleSheet =
    2245             :             static_cast<ScStyleSheet*>(
    2246         190 :                 rDoc.getDoc().GetStyleSheetPool()->Find(aStyleName, SFX_STYLE_FAMILY_PARA));
    2247             : 
    2248         190 :         if (pStyleSheet)
    2249             :         {
    2250         190 :             rDoc.getDoc().ApplyStyleAreaTab(
    2251             :                 rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow, rRange.Sheet,
    2252         380 :                 *pStyleSheet);
    2253         190 :         }
    2254             :     }
    2255             : 
    2256         190 :     boost::scoped_ptr<ScPatternAttr> pAttr(new ScPatternAttr(rDoc.getDoc().GetPool()));
    2257             : 
    2258             :     {
    2259         190 :         SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
    2260             : 
    2261         190 :         if (maModel.mbBorderUsed && rStyles.hasBorder(maModel.mnBorderId) && maAlignment.getApiData().mnRotation)
    2262           0 :             eRotateMode = SVX_ROTATE_MODE_BOTTOM;
    2263             : 
    2264         190 :         SvxRotateModeItem aItem(eRotateMode, ATTR_ROTATE_MODE);
    2265         190 :         ScfTools::PutItem(pAttr->GetItemSet(), aItem, false);
    2266             :     }
    2267             : 
    2268             :     // TODO : Move more properties from writeToPropertyMap().
    2269             : 
    2270         190 :     rDoc.getDoc().ApplyPatternAreaTab(
    2271         380 :         rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow, rRange.Sheet, *pAttr);
    2272         190 : }
    2273             : 
    2274             : const ::ScPatternAttr&
    2275        1516 : Xf::createPattern( bool bSkipPoolDefs )
    2276             : {
    2277        1516 :     if( mpPattern.get() )
    2278        1020 :         return *mpPattern;
    2279         496 :     mpPattern.reset( new ::ScPatternAttr( getScDocument().GetPool() ) );
    2280         496 :     SfxItemSet& rItemSet = mpPattern->GetItemSet();
    2281             :     /*  Enables the used flags, if the formatting attributes differ from the
    2282             :         style XF. In cell XFs Excel uses the cell attributes, if they differ
    2283             :         from the parent style XF (even if the used flag is switched off).
    2284             :         #109899# ...or if the respective flag is not set in parent style XF.
    2285             :      */
    2286         496 :     StylesBuffer& rStyles = getStyles();
    2287             : 
    2288         496 :     const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : 0;
    2289         496 :     if( pStyleXf && !mpStyleSheet )
    2290             :     {
    2291         346 :         rStyles.createCellStyle( maModel.mnStyleXfId );
    2292         346 :         mpStyleSheet = rStyles.getCellStyleSheet(  maModel.mnStyleXfId );
    2293             :         OSL_ENSURE( mpStyleSheet, "Xf::createPattern - no parentStyle created" );
    2294             : 
    2295         346 :         const XfModel& rStyleData = pStyleXf->maModel;
    2296         346 :         if( !maModel.mbFontUsed )
    2297         200 :             maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId);
    2298         346 :         if( !maModel.mbNumFmtUsed )
    2299         290 :             maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId);
    2300         346 :         if( !maModel.mbAlignUsed )
    2301         318 :             maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData());
    2302         346 :         if( !maModel.mbProtUsed )
    2303         344 :             maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData());
    2304         346 :         if( !maModel.mbBorderUsed )
    2305         170 :             maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId );
    2306         346 :         if( !maModel.mbAreaUsed )
    2307         342 :             maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId );
    2308             :     }
    2309             :     // cell protection
    2310         496 :     if( maModel.mbProtUsed )
    2311             :     {
    2312         214 :         maProtection.fillToItemSet( rItemSet, bSkipPoolDefs );
    2313             :     }
    2314             : 
    2315             :     // font
    2316         496 :     if( maModel.mbFontUsed )
    2317             :     {
    2318         286 :         rStyles.writeFontToItemSet( rItemSet, maModel.mnFontId, bSkipPoolDefs );
    2319             :     }
    2320             : 
    2321             :     // value format
    2322         496 :     if( maModel.mbNumFmtUsed )
    2323             :     {
    2324         222 :         mnScNumFmt = rStyles.writeNumFmtToItemSet( rItemSet, maModel.mnNumFmtId, bSkipPoolDefs );
    2325             :     }
    2326             :     // alignment
    2327         496 :     if( maModel.mbAlignUsed )
    2328             :     {
    2329         168 :         maAlignment.fillToItemSet( rItemSet, bSkipPoolDefs );
    2330             :     }
    2331             : 
    2332             :     // border
    2333         496 :     if( maModel.mbBorderUsed )
    2334             :     {
    2335         314 :         rStyles.writeBorderToItemSet( rItemSet, maModel.mnBorderId, bSkipPoolDefs );
    2336             :     }
    2337             : 
    2338             :     // area
    2339         496 :     if( maModel.mbAreaUsed )
    2340             :     {
    2341         144 :         rStyles.writeFillToItemSet( rItemSet, maModel.mnFillId, bSkipPoolDefs );
    2342             :     }
    2343             : 
    2344             :     /*  #i38709# Decide which rotation reference mode to use. If any outer
    2345             :         border line of the cell is set (either explicitly or via cell style),
    2346             :         and the cell contents are rotated, set rotation reference to bottom of
    2347             :         cell. This causes the borders to be painted rotated with the text. */
    2348         496 :     if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : 0) )
    2349             :     {
    2350         486 :         SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
    2351         486 :         sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1);
    2352         486 :         if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() )
    2353             :         {
    2354         482 :             if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() )
    2355             :             {
    2356           0 :                 meRotationRef = ::com::sun::star::table::CellVertJustify2::BOTTOM;
    2357           0 :                 eRotateMode = SVX_ROTATE_MODE_BOTTOM;
    2358             :             }
    2359             :         }
    2360         486 :         ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs );
    2361             :     }
    2362             : 
    2363         496 :     return *mpPattern;
    2364             : }
    2365             : 
    2366          76 : Dxf::Dxf( const WorkbookHelper& rHelper ) :
    2367          76 :     WorkbookHelper( rHelper )
    2368             : {
    2369          76 : }
    2370             : 
    2371          20 : FontRef Dxf::createFont( bool bAlwaysNew )
    2372             : {
    2373          20 :     if( bAlwaysNew || !mxFont )
    2374          20 :         mxFont.reset( new Font( *this, true ) );
    2375          20 :     return mxFont;
    2376             : }
    2377             : 
    2378           0 : BorderRef Dxf::createBorder( bool bAlwaysNew )
    2379             : {
    2380           0 :     if( bAlwaysNew || !mxBorder )
    2381           0 :         mxBorder.reset( new Border( *this, true ) );
    2382           0 :     return mxBorder;
    2383             : }
    2384             : 
    2385           0 : FillRef Dxf::createFill( bool bAlwaysNew )
    2386             : {
    2387           0 :     if( bAlwaysNew || !mxFill )
    2388           0 :         mxFill.reset( new Fill( *this, true ) );
    2389           0 :     return mxFill;
    2390             : }
    2391             : 
    2392          76 : void Dxf::importNumFmt( const AttributeList& rAttribs )
    2393             : {
    2394             :     // don't propagate number formats defined in Dxf entries
    2395             :     // they can have the same id ( but different format codes ) as those
    2396             :     // defined globally earlier. We discard the id defined in XML_numFmtId
    2397             :     // and generate one ourselves ( this assumes that the normal numberformat
    2398             :     // import has already taken place )
    2399          76 :     sal_Int32 nNumFmtId  = getStyles().nextFreeNumFmtId();
    2400          76 :     OUString aFmtCode = rAttribs.getXString( XML_formatCode, OUString() );
    2401          76 :     mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode );
    2402          76 : }
    2403             : 
    2404           0 : void Dxf::importDxf( SequenceInputStream& rStrm )
    2405             : {
    2406           0 :     sal_Int32 nNumFmtId = -1;
    2407           0 :     OUString aFmtCode;
    2408             :     sal_uInt16 nRecCount;
    2409           0 :     rStrm.skip( 4 );    // flags
    2410           0 :     rStrm >> nRecCount;
    2411           0 :     for( sal_uInt16 nRec = 0; !rStrm.isEof() && (nRec < nRecCount); ++nRec )
    2412             :     {
    2413             :         sal_uInt16 nSubRecId, nSubRecSize;
    2414           0 :         sal_Int64 nRecEnd = rStrm.tell();
    2415           0 :         rStrm >> nSubRecId >> nSubRecSize;
    2416           0 :         nRecEnd += nSubRecSize;
    2417           0 :         switch( nSubRecId )
    2418             :         {
    2419           0 :             case BIFF12_DXF_FILL_PATTERN:       createFill( false )->importDxfPattern( rStrm );                         break;
    2420           0 :             case BIFF12_DXF_FILL_FGCOLOR:       createFill( false )->importDxfFgColor( rStrm );                         break;
    2421           0 :             case BIFF12_DXF_FILL_BGCOLOR:       createFill( false )->importDxfBgColor( rStrm );                         break;
    2422           0 :             case BIFF12_DXF_FILL_GRADIENT:      createFill( false )->importDxfGradient( rStrm );                        break;
    2423           0 :             case BIFF12_DXF_FILL_STOP:          createFill( false )->importDxfStop( rStrm );                            break;
    2424           0 :             case BIFF12_DXF_FONT_COLOR:         createFont( false )->importDxfColor( rStrm );                           break;
    2425           0 :             case BIFF12_DXF_BORDER_TOP:         createBorder( false )->importDxfBorder( XLS_TOKEN( top ), rStrm );      break;
    2426           0 :             case BIFF12_DXF_BORDER_BOTTOM:      createBorder( false )->importDxfBorder( XLS_TOKEN( bottom ), rStrm );   break;
    2427           0 :             case BIFF12_DXF_BORDER_LEFT:        createBorder( false )->importDxfBorder( XLS_TOKEN( left ), rStrm );     break;
    2428           0 :             case BIFF12_DXF_BORDER_RIGHT:       createBorder( false )->importDxfBorder( XLS_TOKEN( right ), rStrm );    break;
    2429           0 :             case BIFF12_DXF_FONT_NAME:          createFont( false )->importDxfName( rStrm );                            break;
    2430           0 :             case BIFF12_DXF_FONT_WEIGHT:        createFont( false )->importDxfWeight( rStrm );                          break;
    2431           0 :             case BIFF12_DXF_FONT_UNDERLINE:     createFont( false )->importDxfUnderline( rStrm );                       break;
    2432           0 :             case BIFF12_DXF_FONT_ESCAPEMENT:    createFont( false )->importDxfEscapement( rStrm );                      break;
    2433           0 :             case BIFF12_DXF_FONT_ITALIC:        createFont( false )->importDxfFlag( XML_i, rStrm );                     break;
    2434           0 :             case BIFF12_DXF_FONT_STRIKE:        createFont( false )->importDxfFlag( XML_strike, rStrm );                break;
    2435           0 :             case BIFF12_DXF_FONT_OUTLINE:       createFont( false )->importDxfFlag( XML_outline, rStrm );               break;
    2436           0 :             case BIFF12_DXF_FONT_SHADOW:        createFont( false )->importDxfFlag( XML_shadow, rStrm );                break;
    2437           0 :             case BIFF12_DXF_FONT_HEIGHT:        createFont( false )->importDxfHeight( rStrm );                          break;
    2438           0 :             case BIFF12_DXF_FONT_SCHEME:        createFont( false )->importDxfScheme( rStrm );                          break;
    2439           0 :             case BIFF12_DXF_NUMFMT_CODE:        aFmtCode = BiffHelper::readString( rStrm, false );                      break;
    2440           0 :             case BIFF12_DXF_NUMFMT_ID:          nNumFmtId = rStrm.readuInt16();                                         break;
    2441             :         }
    2442           0 :         rStrm.seek( nRecEnd );
    2443             :     }
    2444             :     OSL_ENSURE( !rStrm.isEof() && (rStrm.getRemaining() == 0), "Dxf::importDxf - unexpected remaining data" );
    2445           0 :     mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode );
    2446           0 : }
    2447             : 
    2448          76 : void Dxf::finalizeImport()
    2449             : {
    2450          76 :     if( mxFont.get() )
    2451          20 :         mxFont->finalizeImport();
    2452          76 :     bool bRTL = false;
    2453             :     // number format already finalized by the number formats buffer
    2454          76 :     if( mxAlignment.get() )
    2455             :     {
    2456           0 :         mxAlignment->finalizeImport();
    2457             :         // how do we detect RTL when text dir is OOX_XF_CONTEXT? ( seems you
    2458             :         // would need access to the cell content, which we don't here )
    2459           0 :         if ( mxAlignment->getModel().mnTextDir == OOX_XF_TEXTDIR_RTL )
    2460           0 :             bRTL = true;
    2461             :     }
    2462          76 :     if( mxProtection.get() )
    2463           0 :         mxProtection->finalizeImport();
    2464          76 :     if( mxBorder.get() )
    2465             :     {
    2466           0 :         mxBorder->finalizeImport( bRTL );
    2467             :     }
    2468          76 :     if( mxFill.get() )
    2469           0 :         mxFill->finalizeImport();
    2470          76 : }
    2471             : 
    2472          56 : void Dxf::fillToItemSet( SfxItemSet& rSet ) const
    2473             : {
    2474          56 :     if (mxFont)
    2475          16 :         mxFont->fillToItemSet(rSet, FONT_PROPTYPE_CELL);
    2476          56 :     if (mxNumFmt)
    2477          56 :         mxNumFmt->fillToItemSet(rSet);
    2478          56 :     if (mxAlignment)
    2479           0 :         mxAlignment->fillToItemSet(rSet);
    2480          56 :     if (mxProtection)
    2481           0 :         mxProtection->fillToItemSet(rSet);
    2482          56 :     if (mxBorder)
    2483           0 :         mxBorder->fillToItemSet(rSet);
    2484          56 :     if (mxFill)
    2485           0 :         mxFill->fillToItemSet(rSet);
    2486          56 : }
    2487             : 
    2488             : namespace {
    2489             : 
    2490             : const sal_Char* const spcStyleNamePrefix = "Excel Built-in ";
    2491             : const sal_Char* const sppcStyleNames[] =
    2492             : {
    2493             :     "Normal",
    2494             :     "RowLevel_",            // outline level will be appended
    2495             :     "ColLevel_",            // outline level will be appended
    2496             :     "Comma",
    2497             :     "Currency",
    2498             :     "Percent",
    2499             :     "Comma [0]",            // new in BIFF4
    2500             :     "Currency [0]",
    2501             :     "Hyperlink",            // new in BIFF8
    2502             :     "Followed Hyperlink",
    2503             :     "Note",                 // new in OOX
    2504             :     "Warning Text",
    2505             :     0,
    2506             :     0,
    2507             :     0,
    2508             :     "Title",
    2509             :     "Heading 1",
    2510             :     "Heading 2",
    2511             :     "Heading 3",
    2512             :     "Heading 4",
    2513             :     "Input",
    2514             :     "Output",
    2515             :     "Calculation",
    2516             :     "Check Cell",
    2517             :     "Linked Cell",
    2518             :     "Total",
    2519             :     "Good",
    2520             :     "Bad",
    2521             :     "Neutral",
    2522             :     "Accent1",
    2523             :     "20% - Accent1",
    2524             :     "40% - Accent1",
    2525             :     "60% - Accent1",
    2526             :     "Accent2",
    2527             :     "20% - Accent2",
    2528             :     "40% - Accent2",
    2529             :     "60% - Accent2",
    2530             :     "Accent3",
    2531             :     "20% - Accent3",
    2532             :     "40% - Accent3",
    2533             :     "60% - Accent3",
    2534             :     "Accent4",
    2535             :     "20% - Accent4",
    2536             :     "40% - Accent4",
    2537             :     "60% - Accent4",
    2538             :     "Accent5",
    2539             :     "20% - Accent5",
    2540             :     "40% - Accent5",
    2541             :     "60% - Accent5",
    2542             :     "Accent6",
    2543             :     "20% - Accent6",
    2544             :     "40% - Accent6",
    2545             :     "60% - Accent6",
    2546             :     "Explanatory Text"
    2547             : };
    2548             : const sal_Int32 snStyleNamesCount = static_cast< sal_Int32 >( SAL_N_ELEMENTS( sppcStyleNames ) );
    2549             : 
    2550         450 : OUString lclGetBuiltinStyleName( sal_Int32 nBuiltinId, const OUString& rName, sal_Int32 nLevel = 0 )
    2551             : {
    2552             :     OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown built-in style" );
    2553         450 :     OUStringBuffer aStyleName;
    2554         450 :     aStyleName.appendAscii( spcStyleNamePrefix );
    2555         450 :     if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ] != 0) )
    2556         450 :         aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] );
    2557           0 :     else if( !rName.isEmpty() )
    2558           0 :         aStyleName.append( rName );
    2559             :     else
    2560           0 :         aStyleName.append( nBuiltinId );
    2561         450 :     if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) )
    2562           0 :         aStyleName.append( nLevel );
    2563         450 :     return aStyleName.makeStringAndClear();
    2564             : }
    2565             : 
    2566         352 : OUString lclCreateStyleName( const CellStyleModel& rModel )
    2567             : {
    2568         352 :     return rModel.mbBuiltin ? lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel ) : rModel.maName;
    2569             : }
    2570             : 
    2571             : } // namespace
    2572             : 
    2573         470 : CellStyleModel::CellStyleModel() :
    2574             :     mnXfId( -1 ),
    2575             :     mnBuiltinId( -1 ),
    2576             :     mnLevel( 0 ),
    2577             :     mbBuiltin( false ),
    2578             :     mbCustom( false ),
    2579         470 :     mbHidden( false )
    2580             : {
    2581         470 : }
    2582             : 
    2583         794 : bool CellStyleModel::isBuiltin() const
    2584             : {
    2585         794 :     return mbBuiltin && (mnBuiltinId >= 0);
    2586             : }
    2587             : 
    2588        3104 : bool CellStyleModel::isDefaultStyle() const
    2589             : {
    2590        3104 :     return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL);
    2591             : }
    2592             : 
    2593         470 : CellStyle::CellStyle( const WorkbookHelper& rHelper ) :
    2594             :     WorkbookHelper( rHelper ),
    2595             :     mbCreated( false ),
    2596         470 :     mpStyleSheet( NULL )
    2597             : {
    2598         470 : }
    2599             : 
    2600         470 : void CellStyle::importCellStyle( const AttributeList& rAttribs )
    2601             : {
    2602         470 :     maModel.maName      = rAttribs.getXString( XML_name, OUString() );
    2603         470 :     maModel.mnXfId      = rAttribs.getInteger( XML_xfId, -1 );
    2604         470 :     maModel.mnBuiltinId = rAttribs.getInteger( XML_builtinId, -1 );
    2605         470 :     maModel.mnLevel     = rAttribs.getInteger( XML_iLevel, 0 );
    2606         470 :     maModel.mbBuiltin   = rAttribs.hasAttribute( XML_builtinId );
    2607         470 :     maModel.mbCustom    = rAttribs.getBool( XML_customBuiltin, false );
    2608         470 :     maModel.mbHidden    = rAttribs.getBool( XML_hidden, false );
    2609         470 : }
    2610             : 
    2611           0 : void CellStyle::importCellStyle( SequenceInputStream& rStrm )
    2612             : {
    2613             :     sal_uInt16 nFlags;
    2614           0 :     rStrm >> maModel.mnXfId >> nFlags;
    2615           0 :     maModel.mnBuiltinId = rStrm.readInt8();
    2616           0 :     maModel.mnLevel = rStrm.readInt8();
    2617           0 :     rStrm >> maModel.maName;
    2618           0 :     maModel.mbBuiltin = getFlag( nFlags, BIFF12_CELLSTYLE_BUILTIN );
    2619           0 :     maModel.mbCustom = getFlag( nFlags, BIFF12_CELLSTYLE_CUSTOM );
    2620           0 :     maModel.mbHidden = getFlag( nFlags, BIFF12_CELLSTYLE_HIDDEN );
    2621           0 : }
    2622             : 
    2623        2184 : void CellStyle::createCellStyle()
    2624             : {
    2625             : 
    2626             :     // #i1624# #i1768# ignore unnamed user styles
    2627        2184 :     bool bDefStyle = maModel.isDefaultStyle();
    2628        2184 :     if( !mbCreated )
    2629             :     {
    2630        2080 :         if ( bDefStyle && maFinalName.isEmpty() )
    2631         126 :             maFinalName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
    2632        2080 :         mbCreated = maFinalName.isEmpty();
    2633             :     }
    2634             : 
    2635        2184 :     if( !mbCreated && !mpStyleSheet )
    2636             :     {
    2637         150 :         bool bCreatePattern = false;
    2638         150 :         Xf* pXF = getStyles().getStyleXf( maModel.mnXfId ).get();
    2639         150 :         ::ScDocument& rDoc = getScDocument();
    2640             : 
    2641         150 :         if( bDefStyle )
    2642             :         {
    2643             :             // use existing "Default" style sheet
    2644         126 :             mpStyleSheet = static_cast< ScStyleSheet* >( static_cast< ScStyleSheetPool* >( rDoc.GetStyleSheetPool() )->Find(
    2645         126 :                 ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) );
    2646             :             OSL_ENSURE( mpStyleSheet, "CellStyle::createStyle - Default style not found" );
    2647         126 :             bCreatePattern = true;
    2648             :         }
    2649             :         else
    2650             :         {
    2651          24 :             mpStyleSheet = static_cast< ScStyleSheet* >( static_cast< ScStyleSheetPool* >( rDoc.GetStyleSheetPool() )->Find( maFinalName, SFX_STYLE_FAMILY_PARA ) );
    2652          24 :             if( !mpStyleSheet )
    2653             :             {
    2654          24 :                 mpStyleSheet = &static_cast< ScStyleSheet& >( rDoc.GetStyleSheetPool()->Make( maFinalName, SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_USERDEF ) );
    2655          24 :                 bCreatePattern = true;
    2656             :             }
    2657             :         }
    2658             : 
    2659             :         // bDefStyle==true omits default pool items in CreatePattern()
    2660         150 :         if( bCreatePattern && mpStyleSheet && pXF )
    2661         150 :             mpStyleSheet->GetItemSet().Put( pXF->createPattern( bDefStyle ).GetItemSet() );
    2662             :     }
    2663        2184 : }
    2664             : 
    2665         324 : void CellStyle::finalizeImport( const OUString& rFinalName )
    2666             : {
    2667         324 :     maFinalName = rFinalName;
    2668         324 :     if( !maModel.isBuiltin() || maModel.mbCustom )
    2669          24 :         createCellStyle();
    2670         324 : }
    2671             : 
    2672         128 : CellStyleBuffer::CellStyleBuffer( const WorkbookHelper& rHelper ) :
    2673         128 :     WorkbookHelper( rHelper )
    2674             : {
    2675         128 : }
    2676             : 
    2677         470 : CellStyleRef CellStyleBuffer::importCellStyle( const AttributeList& rAttribs )
    2678             : {
    2679         470 :     CellStyleRef xCellStyle( new CellStyle( *this ) );
    2680         470 :     xCellStyle->importCellStyle( rAttribs );
    2681         470 :     insertCellStyle( xCellStyle );
    2682         470 :     return xCellStyle;
    2683             : }
    2684             : 
    2685           0 : CellStyleRef CellStyleBuffer::importCellStyle( SequenceInputStream& rStrm )
    2686             : {
    2687           0 :     CellStyleRef xCellStyle( new CellStyle( *this ) );
    2688           0 :     xCellStyle->importCellStyle( rStrm );
    2689           0 :     insertCellStyle( xCellStyle );
    2690           0 :     return xCellStyle;
    2691             : }
    2692             : 
    2693         128 : void CellStyleBuffer::finalizeImport()
    2694             : {
    2695             :     // calculate final names of all styles
    2696             :     typedef RefMap< OUString, CellStyle, IgnoreCaseCompare > CellStyleNameMap;
    2697         128 :     CellStyleNameMap aCellStyles;
    2698         256 :     CellStyleVector aConflictNameStyles;
    2699             : 
    2700             :     /*  First, reserve style names that are built-in in Calc. This causes that
    2701             :         imported cell styles get different unused names and thus do not try to
    2702             :         overwrite these built-in styles. For BIFF4 workbooks (which contain a
    2703             :         separate list of cell styles per sheet), reserve all existing styles if
    2704             :         current sheet is not the first sheet (this styles buffer will be
    2705             :         constructed again for every new sheet). This will create unique names
    2706             :         for styles in different sheets with the same name. Assuming that the
    2707             :         BIFF4W import filter is never used to import from clipboard... */
    2708         128 :     bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0);
    2709             :     try
    2710             :     {
    2711             :         // unfortunately, com.sun.star.style.StyleFamily does not implement XEnumerationAccess...
    2712         128 :         Reference< XIndexAccess > xStyleFamilyIA( getStyleFamily( false ), UNO_QUERY_THROW );
    2713         768 :         for( sal_Int32 nIndex = 0, nCount = xStyleFamilyIA->getCount(); nIndex < nCount; ++nIndex )
    2714             :         {
    2715         640 :             Reference< XStyle > xStyle( xStyleFamilyIA->getByIndex( nIndex ), UNO_QUERY_THROW );
    2716         640 :             if( bReserveAll || !xStyle->isUserDefined() )
    2717             :             {
    2718             :                 // create an empty entry by using ::std::map<>::operator[]
    2719         640 :                 aCellStyles[ xStyle->getName() ];
    2720             :             }
    2721         768 :         }
    2722             :     }
    2723           0 :     catch( Exception& )
    2724             :     {
    2725             :     }
    2726             : 
    2727             :     /*  Calculate names of built-in styles. Store styles with reserved names
    2728             :         in the aConflictNameStyles list. */
    2729         578 :     for( CellStyleVector::iterator aIt = maBuiltinStyles.begin(), aEnd = maBuiltinStyles.end(); aIt != aEnd; ++aIt )
    2730             :     {
    2731         450 :         const CellStyleModel& rModel = (*aIt)->getModel();
    2732         450 :         if (rModel.isDefaultStyle())
    2733         126 :             continue;
    2734             : 
    2735         324 :         OUString aStyleName = lclCreateStyleName( rModel );
    2736             :         /*  If a builtin style entry already exists, and we do not reserve all
    2737             :             existing styles, we just stick with the last definition and ignore
    2738             :             the preceding ones. */
    2739         324 :         if( bReserveAll && (aCellStyles.count( aStyleName ) > 0) )
    2740           0 :             aConflictNameStyles.push_back( *aIt );
    2741             :         else
    2742         324 :             aCellStyles[ aStyleName ] = *aIt;
    2743         324 :     }
    2744             : 
    2745             :     /*  Calculate names of user defined styles. Store styles with reserved
    2746             :         names in the aConflictNameStyles list. */
    2747         148 :     for( CellStyleVector::iterator aIt = maUserStyles.begin(), aEnd = maUserStyles.end(); aIt != aEnd; ++aIt )
    2748             :     {
    2749          20 :         const CellStyleModel& rModel = (*aIt)->getModel();
    2750          20 :         OUString aStyleName = lclCreateStyleName( rModel );
    2751             :         // #i1624# #i1768# ignore unnamed user styles
    2752          20 :         if( aStyleName.getLength() > 0 )
    2753             :         {
    2754          20 :             if( aCellStyles.count( aStyleName ) > 0 )
    2755           8 :                 aConflictNameStyles.push_back( *aIt );
    2756             :             else
    2757          12 :                 aCellStyles[ aStyleName ] = *aIt;
    2758             :         }
    2759          20 :     }
    2760             : 
    2761             :     // find unused names for all styles with conflicting names
    2762         136 :     for( CellStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt )
    2763             :     {
    2764           8 :         const CellStyleModel& rModel = (*aIt)->getModel();
    2765           8 :         OUString aStyleName = lclCreateStyleName( rModel );
    2766          16 :         OUString aUnusedName;
    2767           8 :         sal_Int32 nIndex = 0;
    2768           8 :         do
    2769             :         {
    2770           8 :             aUnusedName = OUStringBuffer( aStyleName ).append( ' ' ).append( ++nIndex ).makeStringAndClear();
    2771             :         }
    2772           8 :         while( aCellStyles.count( aUnusedName ) > 0 );
    2773           8 :         aCellStyles[ aUnusedName ] = *aIt;
    2774           8 :     }
    2775             : 
    2776             :     // set final names and create user-defined and modified built-in cell styles
    2777         256 :     aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport );
    2778         128 : }
    2779             : 
    2780         260 : sal_Int32 CellStyleBuffer::getDefaultXfId() const
    2781             : {
    2782         260 :     return mxDefStyle.get() ? mxDefStyle->getModel().mnXfId : -1;
    2783             : }
    2784             : 
    2785         260 : OUString CellStyleBuffer::getDefaultStyleName() const
    2786             : {
    2787         260 :     return createCellStyle( mxDefStyle );
    2788             : }
    2789             : 
    2790        1902 : OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const
    2791             : {
    2792        1902 :     return createCellStyle( maStylesByXf.get( nXfId ) );
    2793             : }
    2794             : 
    2795        1712 : ::ScStyleSheet*   CellStyleBuffer::getCellStyleSheet( sal_Int32 nXfId ) const
    2796             : {
    2797        1712 :     return getCellStyleSheet( maStylesByXf.get( nXfId ) );
    2798             : }
    2799             : 
    2800             : // private --------------------------------------------------------------------
    2801             : 
    2802         470 : void CellStyleBuffer::insertCellStyle( CellStyleRef xCellStyle )
    2803             : {
    2804         470 :     const CellStyleModel& rModel = xCellStyle->getModel();
    2805         470 :     if( rModel.mnXfId >= 0 )
    2806             :     {
    2807             :         // insert into the built-in map or user defined map
    2808         470 :         (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle );
    2809             : 
    2810             :         // insert into the XF identifier map
    2811             :         OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" );
    2812         470 :         maStylesByXf[ rModel.mnXfId ] = xCellStyle;
    2813             : 
    2814             :         // remember default cell style
    2815         470 :         if( rModel.isDefaultStyle() )
    2816         126 :             mxDefStyle = xCellStyle;
    2817             :     }
    2818         470 : }
    2819             : 
    2820        1712 : ::ScStyleSheet* CellStyleBuffer::getCellStyleSheet( const CellStyleRef& rxCellStyle ) const
    2821             : {
    2822        1712 :     ::ScStyleSheet* pStyleSheet = NULL;
    2823        1712 :     if ( rxCellStyle.get() )
    2824        1712 :         pStyleSheet = rxCellStyle->getStyleSheet();
    2825        1712 :     return pStyleSheet;
    2826             : }
    2827             : 
    2828        2162 : OUString CellStyleBuffer::createCellStyle( const CellStyleRef& rxCellStyle ) const
    2829             : {
    2830        2162 :     if( rxCellStyle.get() )
    2831             :     {
    2832        2160 :         rxCellStyle->createCellStyle();
    2833        2160 :         const OUString& rStyleName = rxCellStyle->getFinalStyleName();
    2834        2160 :         if( !rStyleName.isEmpty() )
    2835        2036 :             return rStyleName;
    2836             :     }
    2837             :     // on error: fallback to default style
    2838         126 :     return lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() );
    2839             : }
    2840             : 
    2841           8 : AutoFormatModel::AutoFormatModel() :
    2842             :     mnAutoFormatId( 0 ),
    2843             :     mbApplyNumFmt( false ),
    2844             :     mbApplyFont( false ),
    2845             :     mbApplyAlignment( false ),
    2846             :     mbApplyBorder( false ),
    2847             :     mbApplyFill( false ),
    2848           8 :     mbApplyProtection( false )
    2849             : {
    2850           8 : }
    2851             : 
    2852         128 : StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) :
    2853             :     WorkbookHelper( rHelper ),
    2854             :     maPalette( rHelper ),
    2855             :     maNumFmts( rHelper ),
    2856         128 :     maCellStyles( rHelper )
    2857             : {
    2858         128 : }
    2859             : 
    2860         382 : FontRef StylesBuffer::createFont( sal_Int32* opnFontId )
    2861             : {
    2862         382 :     if( opnFontId ) *opnFontId = static_cast< sal_Int32 >( maFonts.size() );
    2863         382 :     FontRef xFont( new Font( *this, false ) );
    2864         382 :     maFonts.push_back( xFont );
    2865         382 :     return xFont;
    2866             : }
    2867             : 
    2868          76 : NumberFormatRef StylesBuffer::createNumFmt( sal_Int32 nNumFmtId, const OUString& rFmtCode )
    2869             : {
    2870          76 :     return maNumFmts.createNumFmt( nNumFmtId, rFmtCode );
    2871             : }
    2872             : 
    2873          76 : sal_Int32 StylesBuffer::nextFreeNumFmtId()
    2874             : {
    2875          76 :     return maNumFmts.nextFreeId();
    2876             : }
    2877             : 
    2878         250 : BorderRef StylesBuffer::createBorder( sal_Int32* opnBorderId )
    2879             : {
    2880         250 :     if( opnBorderId ) *opnBorderId = static_cast< sal_Int32 >( maBorders.size() );
    2881         250 :     BorderRef xBorder( new Border( *this, false ) );
    2882         250 :     maBorders.push_back( xBorder );
    2883         250 :     return xBorder;
    2884             : }
    2885             : 
    2886         260 : FillRef StylesBuffer::createFill( sal_Int32* opnFillId )
    2887             : {
    2888         260 :     if( opnFillId ) *opnFillId = static_cast< sal_Int32 >( maFills.size() );
    2889         260 :     FillRef xFill( new Fill( *this, false ) );
    2890         260 :     maFills.push_back( xFill );
    2891         260 :     return xFill;
    2892             : }
    2893             : 
    2894         420 : XfRef StylesBuffer::createCellXf( sal_Int32* opnXfId )
    2895             : {
    2896         420 :     if( opnXfId ) *opnXfId = static_cast< sal_Int32 >( maCellXfs.size() );
    2897         420 :     XfRef xXf( new Xf( *this ) );
    2898         420 :     maCellXfs.push_back( xXf );
    2899         420 :     return xXf;
    2900             : }
    2901             : 
    2902        1338 : XfRef StylesBuffer::createStyleXf( sal_Int32* opnXfId )
    2903             : {
    2904        1338 :     if( opnXfId ) *opnXfId = static_cast< sal_Int32 >( maStyleXfs.size() );
    2905        1338 :     XfRef xXf( new Xf( *this ) );
    2906        1338 :     maStyleXfs.push_back( xXf );
    2907        1338 :     return xXf;
    2908             : }
    2909             : 
    2910          76 : DxfRef StylesBuffer::createDxf( sal_Int32* opnDxfId )
    2911             : {
    2912          76 :     if( opnDxfId ) *opnDxfId = static_cast< sal_Int32 >( maDxfs.size() );
    2913          76 :     DxfRef xDxf( new Dxf( *this ) );
    2914          76 :     maDxfs.push_back( xDxf );
    2915          76 :     return xDxf;
    2916             : }
    2917             : 
    2918        1024 : void StylesBuffer::importPaletteColor( const AttributeList& rAttribs )
    2919             : {
    2920        1024 :     maPalette.importPaletteColor( rAttribs );
    2921        1024 : }
    2922             : 
    2923         104 : NumberFormatRef StylesBuffer::importNumFmt( const AttributeList& rAttribs )
    2924             : {
    2925         104 :     return maNumFmts.importNumFmt( rAttribs );
    2926             : }
    2927             : 
    2928         470 : CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs )
    2929             : {
    2930         470 :     return maCellStyles.importCellStyle( rAttribs );
    2931             : }
    2932             : 
    2933           0 : void StylesBuffer::importPaletteColor( SequenceInputStream& rStrm )
    2934             : {
    2935           0 :     maPalette.importPaletteColor( rStrm );
    2936           0 : }
    2937             : 
    2938           0 : void StylesBuffer::importNumFmt( SequenceInputStream& rStrm )
    2939             : {
    2940           0 :     maNumFmts.importNumFmt( rStrm );
    2941           0 : }
    2942             : 
    2943           0 : void StylesBuffer::importCellStyle( SequenceInputStream& rStrm )
    2944             : {
    2945           0 :     maCellStyles.importCellStyle( rStrm );
    2946           0 : }
    2947             : 
    2948         128 : void StylesBuffer::finalizeImport()
    2949             : {
    2950             :     // fonts first, are needed to finalize unit converter and XFs below
    2951         128 :     maFonts.forEachMem( &Font::finalizeImport );
    2952             :     // finalize unit coefficients after default font is known
    2953         128 :     getUnitConverter().finalizeImport();
    2954             :     // number formats
    2955         128 :     maNumFmts.finalizeImport();
    2956             :     // borders and fills
    2957             :     // is there a document wide RTL setting that we
    2958             :     // would/could need to pass to finalizeImport here ?
    2959         128 :     maBorders.forEachMem( &Border::finalizeImport, false );
    2960         128 :     maFills.forEachMem( &Fill::finalizeImport );
    2961             :     // style XFs and cell XFs
    2962         128 :     maStyleXfs.forEachMem( &Xf::finalizeImport );
    2963         128 :     maCellXfs.forEachMem( &Xf::finalizeImport );
    2964             :     // built-in and user defined cell styles
    2965         128 :     maCellStyles.finalizeImport();
    2966             :     // differential formatting (for conditional formatting)
    2967         128 :     maDxfs.forEachMem( &Dxf::finalizeImport );
    2968         128 : }
    2969             : 
    2970        1262 : sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const
    2971             : {
    2972        1262 :     return maPalette.getColor( nPaletteIdx );
    2973             : }
    2974             : 
    2975        1382 : FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const
    2976             : {
    2977        1382 :     return maFonts.get( nFontId );
    2978             : }
    2979             : 
    2980         486 : BorderRef StylesBuffer::getBorder( sal_Int32 nBorderId ) const
    2981             : {
    2982         486 :     return maBorders.get( nBorderId );
    2983             : }
    2984             : 
    2985       13140 : XfRef StylesBuffer::getCellXf( sal_Int32 nXfId ) const
    2986             : {
    2987       13140 :     return maCellXfs.get( nXfId );
    2988             : }
    2989             : 
    2990         756 : XfRef StylesBuffer::getStyleXf( sal_Int32 nXfId ) const
    2991             : {
    2992         756 :     return maStyleXfs.get( nXfId );
    2993             : }
    2994             : 
    2995        1610 : FontRef StylesBuffer::getFontFromCellXf( sal_Int32 nXfId ) const
    2996             : {
    2997        1610 :     FontRef xFont;
    2998        1610 :     if( const Xf* pXf = getCellXf( nXfId ).get() )
    2999        1124 :         xFont = pXf->getFont();
    3000        1610 :     return xFont;
    3001             : }
    3002             : 
    3003         260 : FontRef StylesBuffer::getDefaultFont() const
    3004             : {
    3005         260 :     FontRef xDefFont;
    3006         260 :     if( const Xf* pXf = getStyleXf( maCellStyles.getDefaultXfId() ).get() )
    3007         258 :         xDefFont = pXf->getFont();
    3008             :     // no font from styles - try first loaded font (e.g. BIFF2)
    3009         260 :     if( !xDefFont )
    3010           2 :         xDefFont = maFonts.get( 0 );
    3011             :     OSL_ENSURE( xDefFont.get(), "StylesBuffer::getDefaultFont - no default font found" );
    3012         260 :     return xDefFont;
    3013             : }
    3014             : 
    3015         132 : const FontModel& StylesBuffer::getDefaultFontModel() const
    3016             : {
    3017         132 :     FontRef xDefFont = getDefaultFont();
    3018         132 :     return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel();
    3019             : }
    3020             : 
    3021         168 : bool StylesBuffer::equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const
    3022             : {
    3023         168 :     if( nBorderId1 == nBorderId2 )
    3024         168 :         return true;
    3025             : 
    3026           0 :     switch( getFilterType() )
    3027             :     {
    3028             :         case FILTER_OOXML:
    3029             :             // in OOXML, borders are assumed to be unique
    3030           0 :             return false;
    3031             : 
    3032             :         case FILTER_BIFF:
    3033             :         {
    3034             :             // in BIFF, a new border entry has been created for every XF
    3035           0 :             const Border* pBorder1 = maBorders.get( nBorderId1 ).get();
    3036           0 :             const Border* pBorder2 = maBorders.get( nBorderId2 ).get();
    3037           0 :             return pBorder1 && pBorder2 && (pBorder1->getApiData() == pBorder2->getApiData());
    3038             :         }
    3039             : 
    3040             :         case FILTER_UNKNOWN:
    3041           0 :         break;
    3042             :     }
    3043           0 :     return false;
    3044             : }
    3045             : 
    3046         342 : bool StylesBuffer::equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const
    3047             : {
    3048         342 :     if( nFillId1 == nFillId2 )
    3049         342 :         return true;
    3050             : 
    3051           0 :     switch( getFilterType() )
    3052             :     {
    3053             :         case FILTER_OOXML:
    3054             :             // in OOXML, fills are assumed to be unique
    3055           0 :             return false;
    3056             : 
    3057             :         case FILTER_BIFF:
    3058             :         {
    3059             :             // in BIFF, a new fill entry has been created for every XF
    3060           0 :             const Fill* pFill1 = maFills.get( nFillId1 ).get();
    3061           0 :             const Fill* pFill2 = maFills.get( nFillId2 ).get();
    3062           0 :             return pFill1 && pFill2 && (pFill1->getApiData() == pFill2->getApiData());
    3063             :         }
    3064             : 
    3065             :         case FILTER_UNKNOWN:
    3066           0 :         break;
    3067             :     }
    3068           0 :     return false;
    3069             : }
    3070             : 
    3071         260 : OUString StylesBuffer::getDefaultStyleName() const
    3072             : {
    3073         260 :     return maCellStyles.getDefaultStyleName();
    3074             : }
    3075             : 
    3076        1902 : OUString StylesBuffer::createCellStyle( sal_Int32 nXfId ) const
    3077             : {
    3078        1902 :     return maCellStyles.createCellStyle( nXfId );
    3079             : }
    3080             : 
    3081        1712 : ::ScStyleSheet* StylesBuffer::getCellStyleSheet( sal_Int32 nXfId ) const
    3082             : {
    3083        1712 :     return maCellStyles.getCellStyleSheet( nXfId );
    3084             : }
    3085             : 
    3086          60 : OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const
    3087             : {
    3088          60 :     OUString& rStyleName = maDxfStyles[ nDxfId ];
    3089          60 :     if (!rStyleName.isEmpty())
    3090           4 :         return rStyleName;
    3091             : 
    3092          56 :     if (Dxf* pDxf = maDxfs.get(nDxfId).get())
    3093             :     {
    3094          56 :         rStyleName = OUStringBuffer("ConditionalStyle_").append(nDxfId + 1).makeStringAndClear();
    3095             : 
    3096             :         // Create a cell style. This may overwrite an existing style if
    3097             :         // one with the same name exists.
    3098             :         SfxItemSet& rStyleItemSet =
    3099             :             ScfTools::MakeCellStyleSheet(
    3100          56 :                 *getScDocument().GetStyleSheetPool(), rStyleName, true).GetItemSet();
    3101             : 
    3102          56 :         pDxf->fillToItemSet(rStyleItemSet);
    3103             :     }
    3104             : 
    3105             :     // on error: fallback to default style
    3106          56 :     if (rStyleName.isEmpty())
    3107           0 :         rStyleName = maCellStyles.getDefaultStyleName();
    3108             : 
    3109          56 :     return rStyleName;
    3110             : }
    3111             : 
    3112         286 : void StylesBuffer::writeFontToItemSet( SfxItemSet& rItemSet, sal_Int32 nFontId, bool bSkipPoolDefs ) const
    3113             : {
    3114         286 :     if( Font* pFont = maFonts.get( nFontId ).get() )
    3115         286 :         pFont->fillToItemSet( rItemSet, FONT_PROPTYPE_CELL, bSkipPoolDefs );
    3116         286 : }
    3117             : 
    3118           0 : void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const
    3119             : {
    3120           0 :     if( Font* pFont = maFonts.get( nFontId ).get() )
    3121           0 :         pFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL );
    3122           0 : }
    3123             : 
    3124         222 : sal_uLong StylesBuffer::writeNumFmtToItemSet( SfxItemSet& rItemSet, sal_Int32 nNumFmtId, bool bSkipPoolDefs ) const
    3125             : {
    3126         222 :     return maNumFmts.fillToItemSet( rItemSet, nNumFmtId, bSkipPoolDefs );
    3127             : }
    3128             : 
    3129           0 : void StylesBuffer::writeNumFmtToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const
    3130             : {
    3131           0 :     maNumFmts.writeToPropertyMap( rPropMap, nNumFmtId );
    3132           0 : }
    3133             : 
    3134         314 : void StylesBuffer::writeBorderToItemSet( SfxItemSet& rItemSet, sal_Int32 nBorderId, bool bSkipPoolDefs ) const
    3135             : {
    3136         314 :     if( Border* pBorder = maBorders.get( nBorderId ).get() )
    3137         314 :         pBorder->fillToItemSet( rItemSet, bSkipPoolDefs );
    3138         314 : }
    3139             : 
    3140           0 : void StylesBuffer::writeBorderToPropertyMap( PropertyMap& rPropMap, sal_Int32 nBorderId ) const
    3141             : {
    3142           0 :     if( Border* pBorder = maBorders.get( nBorderId ).get() )
    3143           0 :         pBorder->writeToPropertyMap( rPropMap );
    3144           0 : }
    3145             : 
    3146         144 : void StylesBuffer::writeFillToItemSet( SfxItemSet& rItemSet, sal_Int32 nFillId, bool bSkipPoolDefs ) const
    3147             : {
    3148         144 :     if( Fill* pFill = maFills.get( nFillId ).get() )
    3149         144 :         pFill->fillToItemSet( rItemSet, bSkipPoolDefs );
    3150         144 : }
    3151             : 
    3152           0 : void StylesBuffer::writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFillId ) const
    3153             : {
    3154           0 :     if( Fill* pFill = maFills.get( nFillId ).get() )
    3155           0 :         pFill->writeToPropertyMap( rPropMap );
    3156           0 : }
    3157             : 
    3158        1724 : bool operator==( const XfModel& rXfModel1,  const XfModel& rXfModel2 )
    3159             : {
    3160        3448 :     return ( rXfModel1.mbCellXf == rXfModel2.mbCellXf &&
    3161        2778 :         rXfModel1.mnStyleXfId == rXfModel2.mnStyleXfId &&
    3162        1856 :         rXfModel1.mbFontUsed == rXfModel2.mbFontUsed &&
    3163        1376 :         rXfModel1.mnFontId == rXfModel2.mnFontId &&
    3164        1100 :         rXfModel1.mbNumFmtUsed == rXfModel2.mbNumFmtUsed &&
    3165        1014 :         rXfModel1.mnNumFmtId == rXfModel2.mnNumFmtId &&
    3166         960 :         rXfModel1.mbAlignUsed == rXfModel2.mbAlignUsed &&
    3167         910 :         rXfModel1.mbBorderUsed == rXfModel2.mbBorderUsed &&
    3168         440 :         rXfModel1.mnBorderId == rXfModel2.mnBorderId &&
    3169           4 :         rXfModel1.mbAreaUsed == rXfModel2.mbAreaUsed &&
    3170        1726 :         rXfModel1.mnFillId == rXfModel2.mnFillId &&
    3171        1724 :         rXfModel1.mbProtUsed == rXfModel2.mbProtUsed );
    3172             : }
    3173             : 
    3174        1724 : bool operator==( const Xf& rXf1, const Xf& rXf2 )
    3175             : {
    3176        1724 :     if ( rXf1.maModel == rXf2.maModel )
    3177             :     {
    3178           0 :         if ( rXf1.maModel.mbAlignUsed )
    3179             :         {
    3180           0 :             if ( !( rXf1.maAlignment.getApiData() == rXf2.maAlignment.getApiData() ) )
    3181           0 :                 return false;
    3182             :         }
    3183           0 :         if ( rXf1.maModel.mbProtUsed )
    3184             :         {
    3185           0 :             if ( !( rXf1.maProtection.getApiData() == rXf2.maProtection.getApiData() ) )
    3186           0 :                 return false;
    3187             :         }
    3188           0 :         return true;
    3189             :     }
    3190        1724 :     return false;
    3191             : }
    3192             : 
    3193         324 : void StylesBuffer::writeCellXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const
    3194             : {
    3195         324 :     if( Xf* pXf = maCellXfs.get( nXfId ).get() )
    3196         190 :         pXf->writeToPropertySet( rPropSet );
    3197         324 : }
    3198             : 
    3199         324 : void StylesBuffer::writeCellXfToDoc(
    3200             :     ScDocumentImport& rDoc, const table::CellRangeAddress& rRange, sal_Int32 nXfId ) const
    3201             : {
    3202         324 :     Xf* pXf = maCellXfs.get(nXfId).get();
    3203         324 :     if (!pXf)
    3204         458 :         return;
    3205             : 
    3206         190 :     pXf->writeToDoc(rDoc, rRange);
    3207             : }
    3208             : 
    3209           0 : bool StylesBuffer::hasBorder( sal_Int32 nBorderId ) const
    3210             : {
    3211           0 :     Border* pBorder = maBorders.get( nBorderId ).get();
    3212           0 :     return pBorder && pBorder->hasBorder();
    3213             : }
    3214             : 
    3215             : } // namespace xls
    3216          48 : } // namespace oox
    3217             : 
    3218             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10