Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef SW_SCRIPTINFO_HXX
30 : : #define SW_SCRIPTINFO_HXX
31 : :
32 : : #include <list>
33 : : #include <deque>
34 : : #include "swscanner.hxx"
35 : :
36 : : class SwTxtNode;
37 : : class Point;
38 : : class MultiSelection;
39 : : class String;
40 : : typedef std::list< xub_StrLen > PositionList;
41 : : typedef std::deque< xub_StrLen > SvXub_StrLens;
42 : :
43 : : #define SPACING_PRECISION_FACTOR 100
44 : :
45 : : /*************************************************************************
46 : : * class SwScriptInfo
47 : : *
48 : : * encapsultes information about script changes
49 : : *************************************************************************/
50 : :
51 : : class SwScriptInfo
52 : : {
53 : : private:
54 : : //! Records a single change in script type.
55 : : struct ScriptChangeInfo
56 : : {
57 : : xub_StrLen position; //!< Character position at which we change script
58 : : sal_uInt8 type; //!< Script type (Latin/Asian/Complex) that we change to.
59 : 13602 : inline ScriptChangeInfo(xub_StrLen pos, sal_uInt8 typ) : position(pos), type(typ) {};
60 : : };
61 : : //TODO - This is sorted, so should probably be a std::set rather than vector.
62 : : // But we also use random access (probably unnecessarily).
63 : : std::vector<ScriptChangeInfo> aScriptChanges;
64 : : //! Records a single change in direction.
65 : : struct DirectionChangeInfo
66 : : {
67 : : xub_StrLen position; //!< Character position at which we change direction.
68 : : sal_uInt8 type; //!< Direction that we change to.
69 : 0 : inline DirectionChangeInfo(xub_StrLen pos, sal_uInt8 typ) : position(pos), type(typ) {};
70 : : };
71 : : std::vector<DirectionChangeInfo> aDirectionChanges;
72 : : SvXub_StrLens aKashida;
73 : : SvXub_StrLens aKashidaInvalid;
74 : : SvXub_StrLens aNoKashidaLine;
75 : : SvXub_StrLens aNoKashidaLineEnd;
76 : : SvXub_StrLens aHiddenChg;
77 : : //! Records a single change in compression.
78 : : struct CompressionChangeInfo
79 : : {
80 : : xub_StrLen position; //!< Character position where the change occurs.
81 : : xub_StrLen length; //!< Length of the segment.
82 : : sal_uInt8 type; //!< Type of compression that we change to.
83 : 0 : inline CompressionChangeInfo(xub_StrLen pos, xub_StrLen len, sal_uInt8 typ) : position(pos), length(len), type(typ) {};
84 : : };
85 : : std::vector<CompressionChangeInfo> aCompressionChanges;
86 : : xub_StrLen nInvalidityPos;
87 : : sal_uInt8 nDefaultDir;
88 : :
89 : : void UpdateBidiInfo( const String& rTxt );
90 : :
91 : : sal_Bool IsKashidaValid ( xub_StrLen nKashPos ) const;
92 : : void MarkKashidaInvalid ( xub_StrLen nKashPos );
93 : : void ClearKashidaInvalid ( xub_StrLen nKashPos );
94 : : bool MarkOrClearKashidaInvalid( xub_StrLen nStt, xub_StrLen nLen, bool bMark, xub_StrLen nMarkCount );
95 : : bool IsKashidaLine ( xub_StrLen nCharIdx ) const;
96 : :
97 : : public:
98 : : enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE };
99 : :
100 : : SwScriptInfo();
101 : : ~SwScriptInfo();
102 : :
103 : : // determines script changes
104 : : void InitScriptInfo( const SwTxtNode& rNode, sal_Bool bRTL );
105 : : void InitScriptInfo( const SwTxtNode& rNode );
106 : :
107 : : // set/get position from which data is invalid
108 : : inline void SetInvalidity( const xub_StrLen nPos );
109 : 107828 : inline xub_StrLen GetInvalidity() const { return nInvalidityPos; };
110 : :
111 : : // get default direction for paragraph
112 : 326 : inline sal_uInt8 GetDefaultDir() const { return nDefaultDir; };
113 : :
114 : : // array operations, nCnt refers to array position
115 : : inline size_t CountScriptChg() const;
116 : : inline xub_StrLen GetScriptChg( const size_t nCnt ) const;
117 : : inline sal_uInt8 GetScriptType( const sal_uInt16 nCnt ) const;
118 : :
119 : : inline size_t CountDirChg() const;
120 : : inline xub_StrLen GetDirChg( const size_t nCnt ) const;
121 : : inline sal_uInt8 GetDirType( const size_t nCnt ) const;
122 : :
123 : : inline size_t CountKashida() const;
124 : : inline xub_StrLen GetKashida( const size_t nCnt ) const;
125 : :
126 : : inline size_t CountCompChg() const;
127 : : inline xub_StrLen GetCompStart( const size_t nCnt ) const;
128 : : inline xub_StrLen GetCompLen( const size_t nCnt ) const;
129 : : inline sal_uInt8 GetCompType( const size_t nCnt ) const;
130 : :
131 : : inline size_t CountHiddenChg() const;
132 : : inline xub_StrLen GetHiddenChg( const size_t nCnt ) const;
133 : : static void CalcHiddenRanges(const SwTxtNode& rNode, MultiSelection& rHiddenMulti);
134 : : static void selectHiddenTextProperty(const SwTxtNode& rNode, MultiSelection &rHiddenMulti);
135 : : static void selectRedLineDeleted(const SwTxtNode& rNode, MultiSelection &rHiddenMulti, bool bSelect=true);
136 : :
137 : : // "high" level operations, nPos refers to string position
138 : : xub_StrLen NextScriptChg( const xub_StrLen nPos ) const;
139 : : sal_uInt8 ScriptType( const xub_StrLen nPos ) const;
140 : :
141 : : // Returns the position of the next direction level change.
142 : : // If bLevel is set, the position of the next level which is smaller
143 : : // than the level at position nPos is returned. This is required to
144 : : // obtain the end of a SwBidiPortion
145 : : xub_StrLen NextDirChg( const xub_StrLen nPos,
146 : : const sal_uInt8* pLevel = 0 ) const;
147 : : sal_uInt8 DirType( const xub_StrLen nPos ) const;
148 : :
149 : : #ifdef DBG_UTIL
150 : : sal_uInt8 CompType( const xub_StrLen nPos ) const;
151 : : #endif
152 : :
153 : : //
154 : : // HIDDEN TEXT STUFF START
155 : : //
156 : :
157 : : /** Hidden text range information - static and non-version
158 : :
159 : : @descr Determines if a given position is inside a hidden text range. The
160 : : static version tries to obtain a valid SwScriptInfo object
161 : : via the SwTxtNode, otherwise it calculates the values from scratch.
162 : : The non-static version uses the internally cached informatio
163 : : for the calculation.
164 : :
165 : : @param rNode
166 : : The text node.
167 : : @param nPos
168 : : The given position that should be checked.
169 : : @param rnStartPos
170 : : Return parameter for the start position of the hidden range.
171 : : STRING_LEN if nPos is not inside a hidden range.
172 : : @param rnEndPos
173 : : Return parameter for the end position of the hidden range.
174 : : 0 if nPos is not inside a hidden range.
175 : : @param rnEndPos
176 : : Return parameter that contains all the hidden text ranges. Optional.
177 : : @return
178 : : returns true if there are any hidden characters in this paragraph.
179 : :
180 : : */
181 : : static bool GetBoundsOfHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos,
182 : : xub_StrLen& rnStartPos, xub_StrLen& rnEndPos,
183 : : PositionList* pList = 0 );
184 : : bool GetBoundsOfHiddenRange( xub_StrLen nPos, xub_StrLen& rnStartPos,
185 : : xub_StrLen& rnEndPos, PositionList* pList = 0 ) const;
186 : :
187 : : static bool IsInHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos );
188 : :
189 : : /** Hidden text attribute handling
190 : :
191 : : @descr Takes a string and either deletes the hidden ranges or sets
192 : : a given character in place of the hidden characters.
193 : :
194 : : @param rNode
195 : : The text node.
196 : : @param nPos
197 : : The string to modify.
198 : : @param cChar
199 : : The character that should replace the hidden characters.
200 : : @param bDel
201 : : If set, the hidden ranges will be deleted from the text node.
202 : : */
203 : : static sal_uInt16 MaskHiddenRanges( const SwTxtNode& rNode, XubString& rText,
204 : : const xub_StrLen nStt, const xub_StrLen nEnd,
205 : : const xub_Unicode cChar );
206 : :
207 : : /** Hidden text attribute handling
208 : :
209 : : @descr Takes a SwTxtNode and deletes the hidden ranges from the node.
210 : :
211 : : @param rNode
212 : : The text node.
213 : : */
214 : : static void DeleteHiddenRanges( SwTxtNode& rNode );
215 : :
216 : : //
217 : : // HIDDEN TEXT STUFF END
218 : : //
219 : :
220 : : // examines the range [ nStart, nStart + nEnd ] if there are kanas
221 : : // returns start index of kana entry in array, otherwise USHRT_MAX
222 : : sal_uInt16 HasKana( xub_StrLen nStart, const xub_StrLen nEnd ) const;
223 : :
224 : : // modifies the kerning array according to a given compress value
225 : : long Compress( sal_Int32* pKernArray, xub_StrLen nIdx, xub_StrLen nLen,
226 : : const sal_uInt16 nCompress, const sal_uInt16 nFontHeight,
227 : : Point* pPoint = NULL ) const;
228 : :
229 : : /** Performes a kashida justification on the kerning array
230 : :
231 : : @descr Add some extra space for kashida justification to the
232 : : positions in the kerning array.
233 : : @param pKernArray
234 : : The printers kerning array. Optional.
235 : : @param pScrArray
236 : : The screen kerning array. Optional.
237 : : @param nStt
238 : : Start referring to the paragraph.
239 : : @param nLen
240 : : The number of characters to be considered.
241 : : @param nSpaceAdd
242 : : The value which has to be added to a kashida opportunity.
243 : : @return The number of kashida opportunities in the given range
244 : : */
245 : : sal_uInt16 KashidaJustify( sal_Int32* pKernArray, sal_Int32* pScrArray,
246 : : xub_StrLen nStt, xub_StrLen nLen,
247 : : long nSpaceAdd = 0) const;
248 : :
249 : : /** Clears array of kashidas marked as invalid
250 : : */
251 : 0 : inline void ClearKashidaInvalid ( xub_StrLen nStt, xub_StrLen nLen ) { MarkOrClearKashidaInvalid( nStt, nLen, false, 0 ); }
252 : :
253 : : /** Marks nCnt kashida positions as invalid
254 : : pKashidaPositions: array of char indices relative to the paragraph
255 : : */
256 : : bool MarkKashidasInvalid ( xub_StrLen nCnt, xub_StrLen* pKashidaPositions );
257 : :
258 : : /** Marks nCnt kashida positions as invalid
259 : : in the given text range
260 : : */
261 : 0 : inline bool MarkKashidasInvalid ( xub_StrLen nCnt, xub_StrLen nStt, xub_StrLen nLen )
262 : 0 : { return MarkOrClearKashidaInvalid( nStt, nLen, true, nCnt ); }
263 : :
264 : : /** retrieves kashida opportunities for a given text range.
265 : : returns the number of kashida positions in the given text range
266 : :
267 : : pKashidaPositions: buffer to reveive the char indices of the
268 : : kashida opportunties relative to the paragraph
269 : : */
270 : : sal_uInt16 GetKashidaPositions ( xub_StrLen nStt, xub_StrLen nLen,
271 : : xub_StrLen* pKashidaPosition );
272 : :
273 : :
274 : :
275 : :
276 : : /** Use regular blank justification instead of kashdida justification for the given line of text.
277 : : nStt Start char index of the line referring to the paragraph.
278 : : nLen Number of characters in the line
279 : : */
280 : : void SetNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen );
281 : :
282 : : /** Clear forced blank justification for a given line.
283 : : nStt Start char index of the line referring to the paragraph.
284 : : nLen Number of characters in the line
285 : : */
286 : : void ClearNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen );
287 : :
288 : : /** Checks if text is Arabic text.
289 : :
290 : : @descr Checks if text is Arabic text.
291 : : @param rTxt
292 : : The text to check
293 : : @param nStt
294 : : Start index of the text
295 : : @return Returns if the language is an Arabic language
296 : : */
297 : : static bool IsArabicText( const rtl::OUString& rTxt, sal_Int32 nStt, sal_Int32 nLen );
298 : :
299 : : /** Performes a thai justification on the kerning array
300 : :
301 : : @descr Add some extra space for thai justification to the
302 : : positions in the kerning array.
303 : : @param rTxt
304 : : The String
305 : : @param pKernArray
306 : : The printers kerning array. Optional.
307 : : @param pScrArray
308 : : The screen kerning array. Optional.
309 : : @param nIdx
310 : : Start referring to the paragraph.
311 : : @param nLen
312 : : The number of characters to be considered.
313 : : @param nSpaceAdd
314 : : The value which has to be added to the cells.
315 : : @return The number of extra spaces in the given range
316 : : */
317 : : static sal_Int32 ThaiJustify( const rtl::OUString& rTxt, sal_Int32* pKernArray,
318 : : sal_Int32* pScrArray, sal_Int32 nIdx,
319 : : sal_Int32 nLen, sal_Int32 nNumberOfBlanks = 0,
320 : : long nSpaceAdd = 0 );
321 : :
322 : : static SwScriptInfo* GetScriptInfo( const SwTxtNode& rNode,
323 : : sal_Bool bAllowInvalid = sal_False );
324 : :
325 : : static sal_uInt8 WhichFont( xub_StrLen nIdx, const String* pTxt, const SwScriptInfo* pSI );
326 : : };
327 : :
328 : 10693 : inline void SwScriptInfo::SetInvalidity( const xub_StrLen nPos )
329 : : {
330 [ + + ]: 10693 : if ( nPos < nInvalidityPos )
331 : 8798 : nInvalidityPos = nPos;
332 : 10693 : };
333 : 426943 : inline size_t SwScriptInfo::CountScriptChg() const { return aScriptChanges.size(); }
334 : 556382 : inline xub_StrLen SwScriptInfo::GetScriptChg( const size_t nCnt ) const
335 : : {
336 : : OSL_ENSURE( nCnt < aScriptChanges.size(),"No ScriptChange today!");
337 : 556382 : return aScriptChanges[nCnt].position;
338 : : }
339 : 435968 : inline sal_uInt8 SwScriptInfo::GetScriptType( const xub_StrLen nCnt ) const
340 : : {
341 : : OSL_ENSURE( nCnt < aScriptChanges.size(),"No ScriptType today!");
342 : 435968 : return aScriptChanges[nCnt].type;
343 : : }
344 : :
345 : 143878 : inline size_t SwScriptInfo::CountDirChg() const { return aDirectionChanges.size(); }
346 : 0 : inline xub_StrLen SwScriptInfo::GetDirChg( const size_t nCnt ) const
347 : : {
348 : : OSL_ENSURE( nCnt < aDirectionChanges.size(),"No DirChange today!");
349 : 0 : return aDirectionChanges[ nCnt ].position;
350 : : }
351 : 0 : inline sal_uInt8 SwScriptInfo::GetDirType( const size_t nCnt ) const
352 : : {
353 : : OSL_ENSURE( nCnt < aDirectionChanges.size(),"No DirType today!");
354 : 0 : return aDirectionChanges[ nCnt ].type;
355 : : }
356 : :
357 : 20 : inline size_t SwScriptInfo::CountKashida() const { return aKashida.size(); }
358 : 0 : inline xub_StrLen SwScriptInfo::GetKashida( const size_t nCnt ) const
359 : : {
360 : : OSL_ENSURE( nCnt < aKashida.size(),"No Kashidas today!");
361 : 0 : return aKashida[ nCnt ];
362 : : }
363 : :
364 : 3 : inline size_t SwScriptInfo::CountCompChg() const { return aCompressionChanges.size(); };
365 : 0 : inline xub_StrLen SwScriptInfo::GetCompStart( const size_t nCnt ) const
366 : : {
367 : : OSL_ENSURE( nCnt < aCompressionChanges.size(),"No CompressionStart today!");
368 : 0 : return aCompressionChanges[ nCnt ].position;
369 : : }
370 : 0 : inline xub_StrLen SwScriptInfo::GetCompLen( const size_t nCnt ) const
371 : : {
372 : : OSL_ENSURE( nCnt < aCompressionChanges.size(),"No CompressionLen today!");
373 : 0 : return aCompressionChanges[ nCnt ].length;
374 : : }
375 : :
376 : 0 : inline sal_uInt8 SwScriptInfo::GetCompType( const size_t nCnt ) const
377 : : {
378 : : OSL_ENSURE( nCnt < aCompressionChanges.size(),"No CompressionType today!");
379 : 0 : return aCompressionChanges[ nCnt ].type;
380 : : }
381 : :
382 : 133994 : inline size_t SwScriptInfo::CountHiddenChg() const { return aHiddenChg.size(); };
383 : 0 : inline xub_StrLen SwScriptInfo::GetHiddenChg( const size_t nCnt ) const
384 : : {
385 : : OSL_ENSURE( nCnt < aHiddenChg.size(),"No HiddenChg today!");
386 : 0 : return aHiddenChg[ nCnt ];
387 : : }
388 : :
389 : :
390 : : #endif
391 : :
392 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|