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>
27 #include <o3tl/typed_flags_set.hxx>
28 #include <i18nlangtag/lang.h>
29 #include <tools/long.hxx>
30 #include "TextFrameIndex.hxx"
31 
32 class SwTextNode;
33 class SwTextFrame;
34 class Point;
35 class MultiSelection;
36 enum class SwFontScript;
37 namespace sw { struct MergedPara; }
38 namespace sw::mark { class IBookmark; }
39 
40 #define SPACING_PRECISION_FACTOR 100
41 
42 // encapsulates information about script changes
44 {
45 public:
47  enum class MarkKind { Start = (1<<0), End = (1<<1), Point = (1<<2) };
48 
49 private:
52  {
55  ScriptChangeInfo(TextFrameIndex pos, sal_uInt8 typ) : position(pos), type(typ) {};
56  };
57  //TODO - This is sorted, so should probably be a std::set rather than vector.
58  // But we also use random access (probably unnecessarily).
59  std::vector<ScriptChangeInfo> m_ScriptChanges;
62  {
65  DirectionChangeInfo(TextFrameIndex pos, sal_uInt8 typ) : position(pos), type(typ) {};
66  };
67  std::vector<DirectionChangeInfo> m_DirectionChanges;
68  std::deque<TextFrameIndex> m_Kashida;
70  std::unordered_set<size_t> m_KashidaInvalid;
71  std::deque<TextFrameIndex> m_NoKashidaLine;
72  std::deque<TextFrameIndex> m_NoKashidaLineEnd;
73  std::vector<TextFrameIndex> m_HiddenChg;
74  std::vector<std::pair<TextFrameIndex, MarkKind>> m_Bookmarks;
77  {
81  CompressionChangeInfo(TextFrameIndex pos, TextFrameIndex len, CompType typ) : position(pos), length(len), type(typ) {};
82  };
83  std::vector<CompressionChangeInfo> m_CompressionChanges;
84 #ifdef DBG_UTIL
85  CompType DbgCompType(const TextFrameIndex nPos) const;
86 #endif
87 
90 
91  void UpdateBidiInfo( const OUString& rText );
92  bool IsKashidaValid(size_t nKashPos) const;
93  // returns true if nKashPos is newly marked invalid
94  bool MarkKashidaInvalid(size_t nKashPos);
95  void ClearKashidaInvalid(size_t nKashPos);
97  bool bMark, sal_Int32 nMarkCount);
98  bool IsKashidaLine(TextFrameIndex nCharIdx) const;
99  // examines the range [ nStart, nStart + nEnd ] if there are kanas
100  // returns start index of kana entry in array, otherwise SAL_MAX_SIZE
101  size_t HasKana(TextFrameIndex nStart, TextFrameIndex nEnd) const;
102 
103 public:
104 
105  SwScriptInfo();
106  ~SwScriptInfo();
107 
108  // determines script changes
109  void InitScriptInfo(const SwTextNode& rNode, sw::MergedPara const* pMerged, bool bRTL);
110  void InitScriptInfo(const SwTextNode& rNode, sw::MergedPara const* pMerged);
111 
112  // set/get position from which data is invalid
114  {
115  if (nPos < m_nInvalidityPos)
116  m_nInvalidityPos = nPos;
117  }
119  {
120  return m_nInvalidityPos;
121  }
122 
123  // get default direction for paragraph
124  sal_uInt8 GetDefaultDir() const { return m_nDefaultDir; };
125 
126  // array operations, nCnt refers to array position
127  size_t CountScriptChg() const { return m_ScriptChanges.size(); }
128  TextFrameIndex GetScriptChg(const size_t nCnt) const
129  {
130  assert(nCnt < m_ScriptChanges.size());
131  return m_ScriptChanges[nCnt].position;
132  }
133  sal_uInt8 GetScriptType( const size_t nCnt ) const
134  {
135  assert( nCnt < m_ScriptChanges.size());
136  return m_ScriptChanges[nCnt].type;
137  }
138 
139  size_t CountDirChg() const { return m_DirectionChanges.size(); }
140  TextFrameIndex GetDirChg(const size_t nCnt) const
141  {
142  assert(nCnt < m_DirectionChanges.size());
143  return m_DirectionChanges[ nCnt ].position;
144  }
145  sal_uInt8 GetDirType( const size_t nCnt ) const
146  {
147  assert(nCnt < m_DirectionChanges.size());
148  return m_DirectionChanges[ nCnt ].type;
149  }
150 
151  size_t CountKashida() const
152  {
153  return m_Kashida.size();
154  }
155 
156  TextFrameIndex GetKashida(const size_t nCnt) const
157  {
158  assert(nCnt < m_Kashida.size());
159  return m_Kashida[nCnt];
160  }
161 
162  size_t CountCompChg() const { return m_CompressionChanges.size(); };
163  TextFrameIndex GetCompStart(const size_t nCnt) const
164  {
165  assert(nCnt < m_CompressionChanges.size());
166  return m_CompressionChanges[ nCnt ].position;
167  }
168  TextFrameIndex GetCompLen(const size_t nCnt) const
169  {
170  assert(nCnt < m_CompressionChanges.size());
171  return m_CompressionChanges[ nCnt ].length;
172  }
173  CompType GetCompType( const size_t nCnt ) const
174  {
175  assert(nCnt < m_CompressionChanges.size());
176  return m_CompressionChanges[ nCnt ].type;
177  }
178 
179  size_t CountHiddenChg() const { return m_HiddenChg.size(); };
180  TextFrameIndex GetHiddenChg(const size_t nCnt) const
181  {
182  assert(nCnt < m_HiddenChg.size());
183  return m_HiddenChg[ nCnt ];
184  }
187  MarkKind GetBookmark(TextFrameIndex nPos) const;
188  static void CalcHiddenRanges(const SwTextNode& rNode,
189  MultiSelection& rHiddenMulti,
190  std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> * pBookmarks);
191  static void selectHiddenTextProperty(const SwTextNode& rNode,
192  MultiSelection &rHiddenMulti,
193  std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> * pBookmarks);
194  static void selectRedLineDeleted(const SwTextNode& rNode, MultiSelection &rHiddenMulti, bool bSelect=true);
195 
196  // "high" level operations, nPos refers to string position
198  sal_Int16 ScriptType(const TextFrameIndex nPos) const;
199 
200  // Returns the position of the next direction level change.
201  // If bLevel is set, the position of the next level which is smaller
202  // than the level at position nPos is returned. This is required to
203  // obtain the end of a SwBidiPortion
205  const sal_uInt8* pLevel = nullptr) const;
206  sal_uInt8 DirType(const TextFrameIndex nPos) const;
207 
208  // HIDDEN TEXT STUFF START
209 
234  static bool GetBoundsOfHiddenRange( const SwTextNode& rNode, sal_Int32 nPos,
235  sal_Int32& rnStartPos, sal_Int32& rnEndPos,
236  std::vector<sal_Int32>* pList = nullptr );
237  bool GetBoundsOfHiddenRange(TextFrameIndex nPos, TextFrameIndex & rnStartPos,
238  TextFrameIndex & rnEndPos) const;
239 
240  static bool IsInHiddenRange( const SwTextNode& rNode, sal_Int32 nPos );
241 
256  static sal_Int32 MaskHiddenRanges(
257  const SwTextNode& rNode, OUStringBuffer& rText,
258  const sal_Int32 nStt, const sal_Int32 nEnd,
259  const sal_Unicode cChar );
260 
268  static void DeleteHiddenRanges( SwTextNode& rNode );
269 
270  // HIDDEN TEXT STUFF END
271 
272  // modifies the kerning array according to a given compress value
274  const sal_uInt16 nCompress, const sal_uInt16 nFontHeight,
275  const bool bCentered,
276  Point* pPoint = nullptr ) const;
277 
294  sal_Int32 KashidaJustify( tools::Long* pKernArray, tools::Long* pScrArray,
295  TextFrameIndex nStt, TextFrameIndex nLen, tools::Long nSpaceAdd = 0) const;
296 
299  void ClearKashidaInvalid(TextFrameIndex const nStt, TextFrameIndex const nLen)
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 
367  static TextFrameIndex ThaiJustify( const OUString& rText, tools::Long* pKernArray,
368  tools::Long* pScrArray, TextFrameIndex nIdx,
369  TextFrameIndex nLen,
370  TextFrameIndex nNumberOfBlanks = TextFrameIndex(0),
371  tools::Long nSpaceAdd = 0 );
372 
373  static TextFrameIndex CountCJKCharacters(const OUString &rText,
374  TextFrameIndex nPos, TextFrameIndex nEnd, LanguageType aLang);
375 
376  static void CJKJustify( const OUString& rText, tools::Long* pKernArray,
377  tools::Long* pScrArray, TextFrameIndex nStt,
378  TextFrameIndex nLen, LanguageType aLang,
379  tools::Long nSpaceAdd, bool bIsSpaceStop );
380 
383  static SwScriptInfo* GetScriptInfo( const SwTextNode& rNode,
384  SwTextFrame const** o_pFrame = nullptr,
385  bool bAllowInvalid = false);
386 
388  static SwFontScript WhichFont(sal_Int32 nIdx, OUString const & rText);
389 };
390 
391 namespace o3tl
392 {
393 
394 template<> struct typed_flags<SwScriptInfo::MarkKind> : is_typed_flags<SwScriptInfo::MarkKind, 0x07> {};
395 
396 }
397 
398 #endif
399 
400 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:750
Records a single change in compression.
Definition: scriptinfo.hxx:76
TextFrameIndex length
Length of the segment.
Definition: scriptinfo.hxx:79
TextFrameIndex GetInvalidityA() const
Definition: scriptinfo.hxx:118
TextFrameIndex NextScriptChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1643
tools::Long Compress(tools::Long *pKernArray, TextFrameIndex nIdx, TextFrameIndex nLen, const sal_uInt16 nCompress, const sal_uInt16 nFontHeight, const bool bCentered, Point *pPoint=nullptr) const
Definition: porlay.cxx:1955
TextFrameIndex position
Character position at which we change direction.
Definition: scriptinfo.hxx:63
sal_uInt8 GetDirType(const size_t nCnt) const
Definition: scriptinfo.hxx:145
sal_uInt8 type
Script type (Latin/Asian/Complex) that we change to.
Definition: scriptinfo.hxx:54
TextFrameIndex NextHiddenChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1696
long Long
void SetInvalidityA(const TextFrameIndex nPos)
Definition: scriptinfo.hxx:113
sal_uInt8 type
Direction that we change to.
Definition: scriptinfo.hxx:64
CompType GetCompType(const size_t nCnt) const
Definition: scriptinfo.hxx:173
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:2307
static SwScriptInfo * GetScriptInfo(const SwTextNode &rNode, SwTextFrame const **o_pFrame=nullptr, bool bAllowInvalid=false)
return a frame for the node, ScriptInfo is its member...
Definition: porlay.cxx:2370
std::vector< CompressionChangeInfo > m_CompressionChanges
Definition: scriptinfo.hxx:83
std::deque< TextFrameIndex > m_NoKashidaLine
Definition: scriptinfo.hxx:71
bool IsKashidaLine(TextFrameIndex nCharIdx) const
Definition: porlay.cxx:2281
std::vector< ScriptChangeInfo > m_ScriptChanges
Definition: scriptinfo.hxx:59
Dialog to specify the properties of date form field.
sal_uInt8 DirType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1684
Records a single change in direction.
Definition: scriptinfo.hxx:61
size_t CountCompChg() const
Definition: scriptinfo.hxx:162
void SetNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen)
Use regular blank justification instead of kashdida justification for the given line of text...
Definition: porlay.cxx:2274
sal_uInt16 sal_Unicode
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:1738
static void selectHiddenTextProperty(const SwTextNode &rNode, MultiSelection &rHiddenMulti, std::vector< std::pair< sw::mark::IBookmark const *, MarkKind >> *pBookmarks)
Definition: porlay.cxx:2494
std::vector< DirectionChangeInfo > m_DirectionChanges
Definition: scriptinfo.hxx:67
TextFrameIndex GetKashida(const size_t nCnt) const
Definition: scriptinfo.hxx:156
bool MarkOrClearKashidaInvalid(TextFrameIndex nStt, TextFrameIndex nLen, bool bMark, sal_Int32 nMarkCount)
Definition: porlay.cxx:2208
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
void UpdateBidiInfo(const OUString &rText)
Definition: porlay.cxx:1608
void InitScriptInfo(const SwTextNode &rNode, sw::MergedPara const *pMerged, bool bRTL)
Definition: porlay.cxx:936
Describes parts of multiple text nodes, which will form a text frame, even when redlines are hidden a...
Definition: txtfrm.hxx:947
static void CJKJustify(const OUString &rText, tools::Long *pKernArray, tools::Long *pScrArray, TextFrameIndex nStt, TextFrameIndex nLen, LanguageType aLang, tools::Long nSpaceAdd, bool bIsSpaceStop)
Definition: porlay.cxx:2670
MarkKind GetBookmark(TextFrameIndex nPos) const
Definition: porlay.cxx:1720
static bool IsArabicText(const OUString &rText, TextFrameIndex nStt, TextFrameIndex nLen)
Checks if text is Arabic text.
Definition: porlay.cxx:2157
TextFrameIndex NextDirChg(const TextFrameIndex nPos, const sal_uInt8 *pLevel=nullptr) const
Definition: porlay.cxx:1669
static void CalcHiddenRanges(const SwTextNode &rNode, MultiSelection &rHiddenMulti, std::vector< std::pair< sw::mark::IBookmark const *, MarkKind >> *pBookmarks)
Definition: porlay.cxx:2622
static void selectRedLineDeleted(const SwTextNode &rNode, MultiSelection &rHiddenMulti, bool bSelect=true)
Definition: porlay.cxx:2587
size_t CountHiddenChg() const
Definition: scriptinfo.hxx:179
CompType type
Type of compression that we change to.
Definition: scriptinfo.hxx:80
Records a single change in script type.
Definition: scriptinfo.hxx:51
sal_uInt8 m_nDefaultDir
Definition: scriptinfo.hxx:89
bool IsKashidaValid(size_t nKashPos) const
Definition: porlay.cxx:2194
size_t HasKana(TextFrameIndex nStart, TextFrameIndex nEnd) const
Definition: porlay.cxx:1935
CompressionChangeInfo(TextFrameIndex pos, TextFrameIndex len, CompType typ)
Definition: scriptinfo.hxx:81
TextFrameIndex GetCompLen(const size_t nCnt) const
Definition: scriptinfo.hxx:168
std::deque< TextFrameIndex > m_NoKashidaLineEnd
Definition: scriptinfo.hxx:72
static TextFrameIndex ThaiJustify(const OUString &rText, tools::Long *pKernArray, tools::Long *pScrArray, TextFrameIndex nIdx, TextFrameIndex nLen, TextFrameIndex nNumberOfBlanks=TextFrameIndex(0), tools::Long nSpaceAdd=0)
Performs a thai justification on the kerning array.
Definition: porlay.cxx:2331
CompType DbgCompType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1916
TextFrameIndex GetDirChg(const size_t nCnt) const
Definition: scriptinfo.hxx:140
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
void ClearNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen)
Clear forced blank justification for a given line.
Definition: porlay.cxx:2291
std::vector< TextFrameIndex > m_HiddenChg
Definition: scriptinfo.hxx:73
sal_Int16 ScriptType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1656
unsigned char sal_uInt8
TextFrameIndex GetHiddenChg(const size_t nCnt) const
Definition: scriptinfo.hxx:180
size_t CountDirChg() const
Definition: scriptinfo.hxx:139
TextFrameIndex m_nInvalidityPos
Definition: scriptinfo.hxx:88
sal_uInt8 GetScriptType(const size_t nCnt) const
Definition: scriptinfo.hxx:133
void ClearKashidaInvalid(TextFrameIndex const nStt, TextFrameIndex const nLen)
Clears array of kashidas marked as invalid.
Definition: scriptinfo.hxx:299
TextFrameIndex NextBookmark(TextFrameIndex nPos) const
Definition: porlay.cxx:1708
std::unordered_set< size_t > m_KashidaInvalid
indexes into m_Kashida
Definition: scriptinfo.hxx:70
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
void ClearKashidaInvalid(size_t nKashPos)
Definition: porlay.cxx:2199
std::vector< std::pair< TextFrameIndex, MarkKind > > m_Bookmarks
Definition: scriptinfo.hxx:74
SwFontScript
Definition: swfont.hxx:122
static void DeleteHiddenRanges(SwTextNode &rNode)
Hidden text attribute handling.
Definition: porlay.cxx:1774
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:1792
size_t CountKashida() const
Definition: scriptinfo.hxx:151
TextFrameIndex GetCompStart(const size_t nCnt) const
Definition: scriptinfo.hxx:163
sal_Int32 KashidaJustify(tools::Long *pKernArray, tools::Long *pScrArray, TextFrameIndex nStt, TextFrameIndex nLen, tools::Long nSpaceAdd=0) const
Performs a kashida justification on the kerning array.
Definition: porlay.cxx:2072
static bool IsInHiddenRange(const SwTextNode &rNode, sal_Int32 nPos)
Definition: porlay.cxx:1906
TextFrameIndex GetScriptChg(const size_t nCnt) const
Definition: scriptinfo.hxx:128
size_t CountScriptChg() const
Definition: scriptinfo.hxx:127
sal_uInt8 GetDefaultDir() const
Definition: scriptinfo.hxx:124
void GetKashidaPositions(TextFrameIndex nStt, TextFrameIndex nLen, std::vector< TextFrameIndex > &rKashidaPosition)
retrieves kashida opportunities for a given text range.
Definition: porlay.cxx:2250
static TextFrameIndex CountCJKCharacters(const OUString &rText, TextFrameIndex nPos, TextFrameIndex nEnd, LanguageType aLang)
Definition: porlay.cxx:2647
bool MarkKashidaInvalid(size_t nKashPos)
Definition: porlay.cxx:2244
TextFrameIndex position
Character position where the change occurs.
Definition: scriptinfo.hxx:78
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...
TextFrameIndex position
Character position at which we change script.
Definition: scriptinfo.hxx:53
ScriptChangeInfo(TextFrameIndex pos, sal_uInt8 typ)
Definition: scriptinfo.hxx:55
std::deque< TextFrameIndex > m_Kashida
Definition: scriptinfo.hxx:68
DirectionChangeInfo(TextFrameIndex pos, sal_uInt8 typ)
Definition: scriptinfo.hxx:65