1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "xistring.hxx"
21 #include "xlstyle.hxx"
22 #include "xistream.hxx"
25 // Byte/Unicode strings =======================================================
27 /** All allowed flags for import. */
28 const XclStrFlags nAllowedFlags
= EXC_STR_8BITLENGTH
| EXC_STR_SMARTFLAGS
| EXC_STR_SEPARATEFORMATS
;
30 XclImpString::XclImpString()
34 XclImpString::XclImpString( const OUString
& rString
) :
39 XclImpString::~XclImpString()
43 void XclImpString::Read( XclImpStream
& rStrm
, XclStrFlags nFlags
)
45 if( !::get_flag( nFlags
, EXC_STR_SEPARATEFORMATS
) )
49 (nFlags
& ~nAllowedFlags
) != 0, "sc.filter",
50 "XclImpString::Read - unknown flag");
51 bool b16BitLen
= !::get_flag( nFlags
, EXC_STR_8BITLENGTH
);
53 switch( rStrm
.GetRoot().GetBiff() )
59 // no integrated formatting in BIFF2-BIFF7
60 maString
= rStrm
.ReadByteString( b16BitLen
);
65 // --- string header ---
66 sal_uInt16 nChars
= b16BitLen
? rStrm
.ReaduInt16() : rStrm
.ReaduInt8();
67 sal_uInt8 nFlagField
= 0;
68 if( nChars
|| !::get_flag( nFlags
, EXC_STR_SMARTFLAGS
) )
69 nFlagField
= rStrm
.ReaduInt8();
71 bool b16Bit
, bRich
, bFarEast
;
74 rStrm
.ReadUniStringExtHeader( b16Bit
, bRich
, bFarEast
, nRunCount
, nExtInf
, nFlagField
);
75 // ignore the flags, they may be wrong
77 // --- character array ---
78 maString
= rStrm
.ReadRawUniString( nChars
, b16Bit
);
82 ReadFormats( rStrm
, nRunCount
);
84 // --- extended (FarEast) information ---
85 rStrm
.Ignore( nExtInf
);
94 void XclImpString::AppendFormat( XclFormatRunVec
& rFormats
, sal_uInt16 nChar
, sal_uInt16 nFontIdx
)
96 // #i33341# real life -- same character index may occur several times
97 OSL_ENSURE( rFormats
.empty() || (rFormats
.back().mnChar
<= nChar
), "XclImpString::AppendFormat - wrong char order" );
98 if( rFormats
.empty() || (rFormats
.back().mnChar
< nChar
) )
99 rFormats
.push_back( XclFormatRun( nChar
, nFontIdx
) );
101 rFormats
.back().mnFontIdx
= nFontIdx
;
104 void XclImpString::ReadFormats( XclImpStream
& rStrm
, XclFormatRunVec
& rFormats
)
106 bool bBiff8
= rStrm
.GetRoot().GetBiff() == EXC_BIFF8
;
107 sal_uInt16 nRunCount
= bBiff8
? rStrm
.ReaduInt16() : rStrm
.ReaduInt8();
108 ReadFormats( rStrm
, rFormats
, nRunCount
);
111 void XclImpString::ReadFormats( XclImpStream
& rStrm
, XclFormatRunVec
& rFormats
, sal_uInt16 nRunCount
)
114 rFormats
.reserve( nRunCount
);
115 /* #i33341# real life -- same character index may occur several times
116 -> use AppendFormat() to validate formats */
117 if( rStrm
.GetRoot().GetBiff() == EXC_BIFF8
)
119 for( sal_uInt16 nIdx
= 0; nIdx
< nRunCount
; ++nIdx
)
121 sal_uInt16 nChar
= rStrm
.ReaduInt16();
122 sal_uInt16 nFontIdx
= rStrm
.ReaduInt16();
123 AppendFormat( rFormats
, nChar
, nFontIdx
);
128 for( sal_uInt16 nIdx
= 0; nIdx
< nRunCount
; ++nIdx
)
130 sal_uInt8 nChar
= rStrm
.ReaduInt8();
131 sal_uInt8 nFontIdx
= rStrm
.ReaduInt8();
132 AppendFormat( rFormats
, nChar
, nFontIdx
);
137 void XclImpString::ReadObjFormats( XclImpStream
& rStrm
, XclFormatRunVec
& rFormats
, sal_uInt16 nFormatSize
)
139 // number of formatting runs, each takes 8 bytes
140 sal_uInt16 nRunCount
= nFormatSize
/ 8;
142 rFormats
.reserve( nRunCount
);
143 for( sal_uInt16 nIdx
= 0; nIdx
< nRunCount
; ++nIdx
)
145 sal_uInt16 nChar
= rStrm
.ReaduInt16();
146 sal_uInt16 nFontIdx
= rStrm
.ReaduInt16();
148 AppendFormat( rFormats
, nChar
, nFontIdx
);
152 // String iterator ============================================================
154 XclImpStringIterator::XclImpStringIterator( const XclImpString
& rString
) :
155 mrText( rString
.GetText() ),
156 mrFormats( rString
.GetFormats() ),
163 // first portion is formatted, adjust vector index to next portion
164 if( !mrFormats
.empty() && (mrFormats
.front().mnChar
== 0) )
166 // find end position of the first portion
167 mnTextEnd
= (mnFormatsEnd
< mrFormats
.size() ?
168 mrFormats
[ mnFormatsEnd
].mnChar
: mrText
.getLength() );
171 OUString
XclImpStringIterator::GetPortionText() const
173 return mrText
.copy( mnTextBeg
, mnTextEnd
- mnTextBeg
);
176 sal_uInt16
XclImpStringIterator::GetPortionFont() const
178 return (mnFormatsBeg
< mnFormatsEnd
) ? mrFormats
[ mnFormatsBeg
].mnFontIdx
: EXC_FONT_NOTFOUND
;
181 XclImpStringIterator
& XclImpStringIterator::operator++()
188 // indexes into vector of formatting runs
189 if( mnFormatsBeg
< mnFormatsEnd
)
191 if( mnFormatsEnd
< mrFormats
.size() )
193 // character positions of next portion
194 mnTextBeg
= mnTextEnd
;
195 mnTextEnd
= (mnFormatsEnd
< mrFormats
.size()) ?
196 mrFormats
[ mnFormatsEnd
].mnChar
: mrText
.getLength();
198 while( Is() && (mnTextBeg
== mnTextEnd
) );
203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */