LibreOffice Module sw (master) 1
scriptinfo.hxx
Go to the documentation of this file.
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 INCLUDED_SW_SOURCE_CORE_INC_SCRIPTINFO_HXX
21#define INCLUDED_SW_SOURCE_CORE_INC_SCRIPTINFO_HXX
22
23#include <vector>
24#include <deque>
25#include <unordered_set>
26#include <rtl/ustrbuf.hxx>
28#include <i18nlangtag/lang.h>
29#include <tools/long.hxx>
30#include "TextFrameIndex.hxx"
31#include <doc.hxx>
32
33class SwTextNode;
34class SwTextFrame;
35class Point;
36class MultiSelection;
37enum class SwFontScript;
38namespace sw { struct MergedPara; }
39namespace sw::mark { class IBookmark; }
40
41#define SPACING_PRECISION_FACTOR 100
42
43// encapsulates information about script changes
45{
46public:
48 enum class MarkKind { Start = (1<<0), End = (1<<1), Point = (1<<2) };
49
50private:
53 {
57 };
58 //TODO - This is sorted, so should probably be a std::set rather than vector.
59 // But we also use random access (probably unnecessarily).
60 std::vector<ScriptChangeInfo> m_ScriptChanges;
63 {
67 };
68 std::vector<DirectionChangeInfo> m_DirectionChanges;
69 std::deque<TextFrameIndex> m_Kashida;
71 std::unordered_set<size_t> m_KashidaInvalid;
72 std::deque<TextFrameIndex> m_NoKashidaLine;
73 std::deque<TextFrameIndex> m_NoKashidaLineEnd;
74 std::vector<TextFrameIndex> m_HiddenChg;
75 std::vector<std::tuple<TextFrameIndex, MarkKind, Color, OUString>> m_Bookmarks;
78 {
83 };
84 std::vector<CompressionChangeInfo> m_CompressionChanges;
85#ifdef DBG_UTIL
86 CompType DbgCompType(const TextFrameIndex nPos) const;
87#endif
88
91
92 void UpdateBidiInfo( const OUString& rText );
93 bool IsKashidaValid(size_t nKashPos) const;
94 // returns true if nKashPos is newly marked invalid
95 bool MarkKashidaInvalid(size_t nKashPos);
96 void ClearKashidaInvalid(size_t nKashPos);
98 bool bMark, sal_Int32 nMarkCount);
99 bool IsKashidaLine(TextFrameIndex nCharIdx) const;
100 // examines the range [ nStart, nStart + nEnd ] if there are kanas
101 // returns start index of kana entry in array, otherwise SAL_MAX_SIZE
102 size_t HasKana(TextFrameIndex nStart, TextFrameIndex nEnd) const;
103
104public:
105
106 SwScriptInfo();
108
109 // determines script changes
110 void InitScriptInfo(const SwTextNode& rNode, sw::MergedPara const* pMerged, bool bRTL);
111 void InitScriptInfo(const SwTextNode& rNode, sw::MergedPara const* pMerged);
112
113 // set/get position from which data is invalid
115 {
118 }
120 {
121 return m_nInvalidityPos;
122 }
123
124 // get default direction for paragraph
126
127 // array operations, nCnt refers to array position
128 size_t CountScriptChg() const { return m_ScriptChanges.size(); }
129 TextFrameIndex GetScriptChg(const size_t nCnt) const
130 {
131 assert(nCnt < m_ScriptChanges.size());
132 return m_ScriptChanges[nCnt].position;
133 }
134 sal_uInt8 GetScriptType( const size_t nCnt ) const
135 {
136 assert( nCnt < m_ScriptChanges.size());
137 return m_ScriptChanges[nCnt].type;
138 }
139
140 size_t CountDirChg() const { return m_DirectionChanges.size(); }
141 TextFrameIndex GetDirChg(const size_t nCnt) const
142 {
143 assert(nCnt < m_DirectionChanges.size());
144 return m_DirectionChanges[ nCnt ].position;
145 }
146 sal_uInt8 GetDirType( const size_t nCnt ) const
147 {
148 assert(nCnt < m_DirectionChanges.size());
149 return m_DirectionChanges[ nCnt ].type;
150 }
151
152 size_t CountKashida() const
153 {
154 return m_Kashida.size();
155 }
156
157 TextFrameIndex GetKashida(const size_t nCnt) const
158 {
159 assert(nCnt < m_Kashida.size());
160 return m_Kashida[nCnt];
161 }
162
163 size_t CountCompChg() const { return m_CompressionChanges.size(); };
164 TextFrameIndex GetCompStart(const size_t nCnt) const
165 {
166 assert(nCnt < m_CompressionChanges.size());
167 return m_CompressionChanges[ nCnt ].position;
168 }
169 TextFrameIndex GetCompLen(const size_t nCnt) const
170 {
171 assert(nCnt < m_CompressionChanges.size());
172 return m_CompressionChanges[ nCnt ].length;
173 }
174 CompType GetCompType( const size_t nCnt ) const
175 {
176 assert(nCnt < m_CompressionChanges.size());
177 return m_CompressionChanges[ nCnt ].type;
178 }
179
180 size_t CountHiddenChg() const { return m_HiddenChg.size(); };
181 TextFrameIndex GetHiddenChg(const size_t nCnt) const
182 {
183 assert(nCnt < m_HiddenChg.size());
184 return m_HiddenChg[ nCnt ];
185 }
188 std::vector<std::tuple<MarkKind, Color, OUString>>
189 GetBookmarks(TextFrameIndex const nPos);
190 static void CalcHiddenRanges(const SwTextNode& rNode,
191 MultiSelection& rHiddenMulti,
192 std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> * pBookmarks);
193 static void selectHiddenTextProperty(const SwTextNode& rNode,
194 MultiSelection &rHiddenMulti,
195 std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> * pBookmarks);
196 static void selectRedLineDeleted(const SwTextNode& rNode, MultiSelection &rHiddenMulti, bool bSelect=true);
197
198 // "high" level operations, nPos refers to string position
200 sal_Int16 ScriptType(const TextFrameIndex nPos) const;
201
202 // Returns the position of the next direction level change.
203 // If bLevel is set, the position of the next level which is smaller
204 // than the level at position nPos is returned. This is required to
205 // obtain the end of a SwBidiPortion
207 const sal_uInt8* pLevel = nullptr) const;
208 sal_uInt8 DirType(const TextFrameIndex nPos) const;
209
210 // HIDDEN TEXT STUFF START
211
236 static bool GetBoundsOfHiddenRange( const SwTextNode& rNode, sal_Int32 nPos,
237 sal_Int32& rnStartPos, sal_Int32& rnEndPos,
238 std::vector<sal_Int32>* pList = nullptr );
240 TextFrameIndex & rnEndPos) const;
241
242 static bool IsInHiddenRange( const SwTextNode& rNode, sal_Int32 nPos );
243
258 static sal_Int32 MaskHiddenRanges(
259 const SwTextNode& rNode, OUStringBuffer& rText,
260 const sal_Int32 nStt, const sal_Int32 nEnd,
261 const sal_Unicode cChar );
262
270 static void DeleteHiddenRanges( SwTextNode& rNode );
271
272 // HIDDEN TEXT STUFF END
273
274 // modifies the kerning array according to a given compress value
275 tools::Long Compress( sal_Int32* pKernArray, TextFrameIndex nIdx, TextFrameIndex nLen,
276 const sal_uInt16 nCompress, const sal_uInt16 nFontHeight,
277 const bool bCentered,
278 Point* pPoint = nullptr ) const;
279
294 sal_Int32 KashidaJustify( sal_Int32* pKernArray, sal_Bool* pKashidaArray,
295 TextFrameIndex nStt, TextFrameIndex nLen, tools::Long nSpaceAdd = 0) const;
296
300 {
301 MarkOrClearKashidaInvalid(nStt, nLen, false, 0);
302 }
303
307 void MarkKashidasInvalid(sal_Int32 nCnt, const TextFrameIndex* pKashidaPositions);
308
312 bool MarkKashidasInvalid(sal_Int32 const nCnt,
313 TextFrameIndex const nStt, TextFrameIndex const nLen)
314 {
315 return MarkOrClearKashidaInvalid(nStt, nLen, true, nCnt);
316 }
317
324 std::vector<TextFrameIndex>& rKashidaPosition);
325
331
337
347 static bool IsArabicText(const OUString& rText, TextFrameIndex nStt, TextFrameIndex nLen);
348
365 static TextFrameIndex ThaiJustify( const OUString& rText, sal_Int32* pKernArray,
366 TextFrameIndex nIdx,
367 TextFrameIndex nLen,
368 TextFrameIndex nNumberOfBlanks = TextFrameIndex(0),
369 tools::Long nSpaceAdd = 0 );
370
371 static TextFrameIndex CountCJKCharacters(const OUString &rText,
372 TextFrameIndex nPos, TextFrameIndex nEnd, LanguageType aLang);
373
374 static void CJKJustify( const OUString& rText, sal_Int32* pKernArray,
375 TextFrameIndex nStt,
376 TextFrameIndex nLen, LanguageType aLang,
377 tools::Long nSpaceAdd, bool bIsSpaceStop );
378
381 static SwScriptInfo* GetScriptInfo( const SwTextNode& rNode,
382 SwTextFrame const** o_pFrame = nullptr,
383 bool bAllowInvalid = false);
384
386 static SwFontScript WhichFont(sal_Int32 nIdx, OUString const & rText);
387};
388
389namespace o3tl
390{
391
392template<> struct typed_flags<SwScriptInfo::MarkKind> : is_typed_flags<SwScriptInfo::MarkKind, 0x07> {};
393
394}
395
396#endif
397
398/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
std::unordered_set< size_t > m_KashidaInvalid
indexes into m_Kashida
Definition: scriptinfo.hxx:71
TextFrameIndex m_nInvalidityPos
Definition: scriptinfo.hxx:89
static void DeleteHiddenRanges(SwTextNode &rNode)
Hidden text attribute handling.
Definition: porlay.cxx:2017
sal_Int16 ScriptType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1881
void ClearNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen)
Clear forced blank justification for a given line.
Definition: porlay.cxx:2537
CompType GetCompType(const size_t nCnt) const
Definition: scriptinfo.hxx:174
void MarkKashidasInvalid(sal_Int32 nCnt, const TextFrameIndex *pKashidaPositions)
Marks nCnt kashida positions as invalid pKashidaPositions: array of char indices relative to the para...
Definition: porlay.cxx:2553
TextFrameIndex GetCompStart(const size_t nCnt) const
Definition: scriptinfo.hxx:164
std::deque< TextFrameIndex > m_NoKashidaLineEnd
Definition: scriptinfo.hxx:73
static void selectHiddenTextProperty(const SwTextNode &rNode, MultiSelection &rHiddenMulti, std::vector< std::pair< sw::mark::IBookmark const *, MarkKind > > *pBookmarks)
Definition: porlay.cxx:2749
TextFrameIndex GetCompLen(const size_t nCnt) const
Definition: scriptinfo.hxx:169
TextFrameIndex NextDirChg(const TextFrameIndex nPos, const sal_uInt8 *pLevel=nullptr) const
Definition: porlay.cxx:1894
static bool GetBoundsOfHiddenRange(const SwTextNode &rNode, sal_Int32 nPos, sal_Int32 &rnStartPos, sal_Int32 &rnEndPos, std::vector< sal_Int32 > *pList=nullptr)
Hidden text range information - static and non-version.
Definition: porlay.cxx:2035
std::deque< TextFrameIndex > m_Kashida
Definition: scriptinfo.hxx:69
TextFrameIndex GetHiddenChg(const size_t nCnt) const
Definition: scriptinfo.hxx:181
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:892
sal_uInt8 m_nDefaultDir
Definition: scriptinfo.hxx:90
std::vector< ScriptChangeInfo > m_ScriptChanges
Definition: scriptinfo.hxx:60
std::vector< std::tuple< MarkKind, Color, OUString > > GetBookmarks(TextFrameIndex const nPos)
Definition: porlay.cxx:1946
void UpdateBidiInfo(const OUString &rText)
Definition: porlay.cxx:1833
sal_uInt8 GetDefaultDir() const
Definition: scriptinfo.hxx:125
std::vector< DirectionChangeInfo > m_DirectionChanges
Definition: scriptinfo.hxx:68
static bool IsInHiddenRange(const SwTextNode &rNode, sal_Int32 nPos)
Definition: porlay.cxx:2149
sal_uInt8 DirType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1909
CompType DbgCompType(const TextFrameIndex nPos) const
Definition: porlay.cxx:2159
bool MarkOrClearKashidaInvalid(TextFrameIndex nStt, TextFrameIndex nLen, bool bMark, sal_Int32 nMarkCount)
Definition: porlay.cxx:2454
size_t CountScriptChg() const
Definition: scriptinfo.hxx:128
static sal_Int32 MaskHiddenRanges(const SwTextNode &rNode, OUStringBuffer &rText, const sal_Int32 nStt, const sal_Int32 nEnd, const sal_Unicode cChar)
Hidden text attribute handling.
Definition: porlay.cxx:1981
static TextFrameIndex CountCJKCharacters(const OUString &rText, TextFrameIndex nPos, TextFrameIndex nEnd, LanguageType aLang)
Definition: porlay.cxx:2881
bool IsKashidaLine(TextFrameIndex nCharIdx) const
Definition: porlay.cxx:2527
TextFrameIndex GetInvalidityA() const
Definition: scriptinfo.hxx:119
void ClearKashidaInvalid(size_t nKashPos)
Definition: porlay.cxx:2445
void GetKashidaPositions(TextFrameIndex nStt, TextFrameIndex nLen, std::vector< TextFrameIndex > &rKashidaPosition)
retrieves kashida opportunities for a given text range.
Definition: porlay.cxx:2496
TextFrameIndex GetScriptChg(const size_t nCnt) const
Definition: scriptinfo.hxx:129
static TextFrameIndex ThaiJustify(const OUString &rText, sal_Int32 *pKernArray, TextFrameIndex nIdx, TextFrameIndex nLen, TextFrameIndex nNumberOfBlanks=TextFrameIndex(0), tools::Long nSpaceAdd=0)
Performs a thai justification on the kerning array.
Definition: porlay.cxx:2577
bool IsKashidaValid(size_t nKashPos) const
Definition: porlay.cxx:2440
tools::Long Compress(sal_Int32 *pKernArray, TextFrameIndex nIdx, TextFrameIndex nLen, const sal_uInt16 nCompress, const sal_uInt16 nFontHeight, const bool bCentered, Point *pPoint=nullptr) const
Definition: porlay.cxx:2198
sal_uInt8 GetScriptType(const size_t nCnt) const
Definition: scriptinfo.hxx:134
TextFrameIndex NextHiddenChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1921
sal_Int32 KashidaJustify(sal_Int32 *pKernArray, sal_Bool *pKashidaArray, TextFrameIndex nStt, TextFrameIndex nLen, tools::Long nSpaceAdd=0) const
Performs a kashida justification on the kerning array.
Definition: porlay.cxx:2315
size_t CountKashida() const
Definition: scriptinfo.hxx:152
bool MarkKashidaInvalid(size_t nKashPos)
Definition: porlay.cxx:2490
static bool IsArabicText(const OUString &rText, TextFrameIndex nStt, TextFrameIndex nLen)
Checks if text is Arabic text.
Definition: porlay.cxx:2403
void ClearKashidaInvalid(TextFrameIndex const nStt, TextFrameIndex const nLen)
Clears array of kashidas marked as invalid.
Definition: scriptinfo.hxx:299
static SwScriptInfo * GetScriptInfo(const SwTextNode &rNode, SwTextFrame const **o_pFrame=nullptr, bool bAllowInvalid=false)
return a frame for the node, ScriptInfo is its member... (many clients need both frame and SI,...
Definition: porlay.cxx:2615
void SetNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen)
Use regular blank justification instead of kashdida justification for the given line of text.
Definition: porlay.cxx:2520
size_t CountDirChg() const
Definition: scriptinfo.hxx:140
static void CalcHiddenRanges(const SwTextNode &rNode, MultiSelection &rHiddenMulti, std::vector< std::pair< sw::mark::IBookmark const *, MarkKind > > *pBookmarks)
Definition: porlay.cxx:2856
TextFrameIndex GetDirChg(const size_t nCnt) const
Definition: scriptinfo.hxx:141
TextFrameIndex NextScriptChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1868
static void CJKJustify(const OUString &rText, sal_Int32 *pKernArray, TextFrameIndex nStt, TextFrameIndex nLen, LanguageType aLang, tools::Long nSpaceAdd, bool bIsSpaceStop)
Definition: porlay.cxx:2904
size_t CountCompChg() const
Definition: scriptinfo.hxx:163
size_t CountHiddenChg() const
Definition: scriptinfo.hxx:180
std::deque< TextFrameIndex > m_NoKashidaLine
Definition: scriptinfo.hxx:72
TextFrameIndex NextBookmark(TextFrameIndex nPos) const
Definition: porlay.cxx:1933
bool MarkKashidasInvalid(sal_Int32 const nCnt, TextFrameIndex const nStt, TextFrameIndex const nLen)
Marks nCnt kashida positions as invalid in the given text range.
Definition: scriptinfo.hxx:312
std::vector< TextFrameIndex > m_HiddenChg
Definition: scriptinfo.hxx:74
static void selectRedLineDeleted(const SwTextNode &rNode, MultiSelection &rHiddenMulti, bool bSelect=true)
Definition: porlay.cxx:2821
size_t HasKana(TextFrameIndex nStart, TextFrameIndex nEnd) const
Definition: porlay.cxx:2178
std::vector< CompressionChangeInfo > m_CompressionChanges
Definition: scriptinfo.hxx:84
void InitScriptInfo(const SwTextNode &rNode, sw::MergedPara const *pMerged, bool bRTL)
Definition: porlay.cxx:1127
std::vector< std::tuple< TextFrameIndex, MarkKind, Color, OUString > > m_Bookmarks
Definition: scriptinfo.hxx:75
sal_uInt8 GetDirType(const size_t nCnt) const
Definition: scriptinfo.hxx:146
TextFrameIndex GetKashida(const size_t nCnt) const
Definition: scriptinfo.hxx:157
void SetInvalidityA(const TextFrameIndex nPos)
Definition: scriptinfo.hxx:114
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:89
sal_uInt16 nPos
Dialog to specify the properties of date form field.
long Long
Records a single change in compression.
Definition: scriptinfo.hxx:78
TextFrameIndex position
Character position where the change occurs.
Definition: scriptinfo.hxx:79
CompressionChangeInfo(TextFrameIndex pos, TextFrameIndex len, CompType typ)
Definition: scriptinfo.hxx:82
CompType type
Type of compression that we change to.
Definition: scriptinfo.hxx:81
TextFrameIndex length
Length of the segment.
Definition: scriptinfo.hxx:80
Records a single change in direction.
Definition: scriptinfo.hxx:63
sal_uInt8 type
Direction that we change to.
Definition: scriptinfo.hxx:65
DirectionChangeInfo(TextFrameIndex pos, sal_uInt8 typ)
Definition: scriptinfo.hxx:66
TextFrameIndex position
Character position at which we change direction.
Definition: scriptinfo.hxx:64
Records a single change in script type.
Definition: scriptinfo.hxx:53
TextFrameIndex position
Character position at which we change script.
Definition: scriptinfo.hxx:54
ScriptChangeInfo(TextFrameIndex pos, sal_uInt8 typ)
Definition: scriptinfo.hxx:56
sal_uInt8 type
Script type (Latin/Asian/Complex) that we change to.
Definition: scriptinfo.hxx:55
Describes parts of multiple text nodes, which will form a text frame, even when redlines are hidden a...
Definition: txtfrm.hxx:963
SwFontScript
Definition: swfont.hxx:124
unsigned char sal_uInt8
unsigned char sal_Bool
sal_uInt16 sal_Unicode
size_t pos