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

Generated by: LCOV version 1.11