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