LibreOffice Module vcl (master)  1
sallayout.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_VCL_INC_SALLAYOUT_HXX
21 #define INCLUDED_VCL_INC_SALLAYOUT_HXX
22 
23 #include <iostream>
24 #include <memory>
25 #include <vector>
26 
27 #include <hb.h>
28 
29 #include <com/sun/star/i18n/XBreakIterator.hpp>
30 
33 #include <tools/gen.hxx>
34 #include <vcl/dllapi.h>
35 #include <vcl/vclenum.hxx> // for typedef sal_UCS4
36 #include <vcl/devicecoordinate.hxx>
37 #include <vcl/vcllayout.hxx>
38 
39 #include "impglyphitem.hxx"
40 
41 #define MAX_FALLBACK 16
42 
43 
44 class SalGraphics;
45 class PhysicalFontFace;
46 class GenericSalLayout;
47 enum class SalLayoutFlags;
48 namespace vcl {
49  class TextLayoutCache;
50 }
51 
52 // used for managing runs e.g. for BiDi, glyph and script fallback
54 {
55 private:
57  std::vector<int> maRuns;
58 
59 public:
60  ImplLayoutRuns() { mnRunIndex = 0; maRuns.reserve(8); }
61 
62  void Clear() { maRuns.clear(); }
63  void AddPos( int nCharPos, bool bRTL );
64  void AddRun( int nMinRunPos, int nEndRunPos, bool bRTL );
65 
66  bool IsEmpty() const { return maRuns.empty(); }
67  void ResetPos() { mnRunIndex = 0; }
68  void NextRun() { mnRunIndex += 2; }
69  bool GetRun( int* nMinRunPos, int* nEndRunPos, bool* bRTL ) const;
70  bool GetNextPos( int* nCharPos, bool* bRTL );
71  bool PosIsInRun( int nCharPos ) const;
72  bool PosIsInAnyRun( int nCharPos ) const;
73 };
74 
76 {
77 public:
78  // string related inputs
81  const OUString& mrStr;
84 
85  // performance hack
87 
88  // positioning related inputs
89  const DeviceCoordinate* mpDXArray; // in pixel units
90  DeviceCoordinate mnLayoutWidth; // in pixel units
91  int mnOrientation; // in 0-3600 system
92 
93  // data for bidi and glyph+script fallback
96 
97  ImplLayoutArgs( const OUString& rStr,
98  int nMinCharPos, int nEndCharPos, SalLayoutFlags nFlags,
99  const LanguageTag& rLanguageTag,
100  vcl::TextLayoutCache const* pLayoutCache);
101 
102  void SetLayoutWidth( DeviceCoordinate nWidth ) { mnLayoutWidth = nWidth; }
103  void SetDXArray( const DeviceCoordinate* pDXArray ) { mpDXArray = pDXArray; }
104  void SetOrientation( int nOrientation ) { mnOrientation = nOrientation; }
105 
106  void ResetPos()
107  { maRuns.ResetPos(); }
108  bool GetNextPos( int* nCharPos, bool* bRTL )
109  { return maRuns.GetNextPos( nCharPos, bRTL ); }
110  bool GetNextRun( int* nMinRunPos, int* nEndRunPos, bool* bRTL );
111  void NeedFallback( int nMinRunPos, int nEndRunPos, bool bRTL )
112  { maFallbackRuns.AddRun( nMinRunPos, nEndRunPos, bRTL ); }
113  // methods used by BiDi and glyph fallback
114  bool NeedFallback() const
115  { return !maFallbackRuns.IsEmpty(); }
116  bool PrepareFallback();
117 
118 private:
119  void AddRun( int nMinCharPos, int nEndCharPos, bool bRTL );
120 };
121 
122 // For nice SAL_INFO logging of ImplLayoutArgs values
123 std::ostream &operator <<(std::ostream& s, ImplLayoutArgs const &rArgs);
124 
125 class MultiSalLayout final : public SalLayout
126 {
127 public:
128  void DrawText(SalGraphics&) const override;
129  sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const override;
130  DeviceCoordinate FillDXArray(DeviceCoordinate* pDXArray) const override;
131  void GetCaretPositions(int nArraySize, long* pCaretXArray) const override;
132  bool GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart,
133  const PhysicalFontFace** pFallbackFont = nullptr) const override;
134  bool GetOutline(basegfx::B2DPolyPolygonVector&) const override;
135  bool IsKashidaPosValid(int nCharPos) const override;
136 
137  // used only by OutputDevice::ImplLayout, TODO: make friend
138  explicit MultiSalLayout( std::unique_ptr<SalLayout> pBaseLayout );
139  void AddFallback(std::unique_ptr<SalLayout> pFallbackLayout, ImplLayoutRuns const &);
140  bool LayoutText(ImplLayoutArgs&, const SalLayoutGlyphs*) override;
141  void AdjustLayout(ImplLayoutArgs&) override;
142  void InitFont() const override;
143 
144  void SetIncomplete(bool bIncomplete);
145 
146 public:
147  virtual ~MultiSalLayout() override;
148 
149 private:
150  MultiSalLayout( const MultiSalLayout& ) = delete;
151  MultiSalLayout& operator=( const MultiSalLayout& ) = delete;
152 
153  std::unique_ptr<GenericSalLayout> mpLayouts[ MAX_FALLBACK ];
155  int mnLevel;
157 };
158 
160 {
162 
163 public:
165  ~GenericSalLayout() override;
166 
167  void AdjustLayout(ImplLayoutArgs&) final override;
168  bool LayoutText(ImplLayoutArgs&, const SalLayoutGlyphs*) final override;
169  void DrawText(SalGraphics&) const final override;
170  static std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&);
171  const SalLayoutGlyphs* GetGlyphs() const final override;
172 
173  bool IsKashidaPosValid(int nCharPos) const final override;
174 
175  // used by upper layers
176  DeviceCoordinate GetTextWidth() const final override;
177  DeviceCoordinate FillDXArray(DeviceCoordinate* pDXArray) const final override;
178  sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const final override;
179  void GetCaretPositions(int nArraySize, long* pCaretXArray) const final override;
180 
181  // used by display layers
183  { return m_GlyphItems.Impl()->GetFont(); }
184 
185  bool GetNextGlyph(const GlyphItem** pGlyph, Point& rPos, int& nStart,
186  const PhysicalFontFace** pFallbackFont = nullptr) const override;
187 
188 private:
189  // for glyph+font+script fallback
190  void MoveGlyph(int nStart, long nNewXPos);
191  void DropGlyph(int nStart);
192  void Simplify(bool bIsBase);
193 
194  GenericSalLayout( const GenericSalLayout& ) = delete;
195  GenericSalLayout& operator=( const GenericSalLayout& ) = delete;
196 
197  void ApplyDXArray(const ImplLayoutArgs&);
198  void Justify(DeviceCoordinate nNewWidth);
199  void ApplyAsianKerning(const OUString& rStr);
200 
201  void GetCharWidths(DeviceCoordinate* pCharWidths) const;
202 
203  void SetNeedFallback(ImplLayoutArgs&, sal_Int32, bool);
204 
205  bool HasVerticalAlternate(sal_UCS4 aChar, sal_UCS4 aNextChar);
206 
207  void ParseFeatures(const OUString& name);
208 
209  css::uno::Reference<css::i18n::XBreakIterator> mxBreak;
210 
212 
213  OString msLanguage;
214  std::vector<hb_feature_t> maFeatures;
215 
216  hb_set_t* mpVertGlyphs;
217  const bool mbFuzzing;
218 };
219 
220 #undef SalGraphics
221 
222 #endif // INCLUDED_VCL_INC_SALLAYOUT_HXX
223 
224 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const =0
void SetOrientation(int nOrientation)
Definition: sallayout.hxx:104
MultiSalLayout & operator=(const MultiSalLayout &)=delete
void AddFallback(std::unique_ptr< SalLayout > pFallbackLayout, ImplLayoutRuns const &)
Definition: sallayout.cxx:1009
hb_set_t * mpVertGlyphs
Definition: sallayout.hxx:216
sal_uInt32 sal_UCS4
Definition: vclenum.hxx:196
bool GetNextPos(int *nCharPos, bool *bRTL)
Definition: sallayout.hxx:108
bool GetOutline(basegfx::B2DPolyPolygonVector &) const override
Definition: sallayout.cxx:1534
std::unique_ptr< GenericSalLayout > mpLayouts[MAX_FALLBACK]
Definition: sallayout.hxx:153
#define VCL_DLLPUBLIC
Definition: dllapi.h:29
#define MAX_FALLBACK
Definition: sallayout.hxx:41
void InitFont() const override
Definition: sallayout.cxx:1373
virtual DeviceCoordinate GetTextWidth() const
Definition: vcllayout.hxx:86
void SetLayoutWidth(DeviceCoordinate nWidth)
Definition: sallayout.hxx:102
LogicalFontInstance & GetFont() const
Definition: sallayout.hxx:182
MultiSalLayout(std::unique_ptr< SalLayout > pBaseLayout)
Definition: sallayout.cxx:988
void NeedFallback(int nMinRunPos, int nEndRunPos, bool bRTL)
Definition: sallayout.hxx:111
std::vector< int > maRuns
Definition: sallayout.hxx:57
void SetIncomplete(bool bIncomplete)
Definition: sallayout.cxx:999
void AddPos(int nCharPos, bool bRTL)
Definition: sallayout.cxx:231
bool IsEmpty() const
Definition: sallayout.hxx:66
ImplLayoutRuns maRuns
Definition: sallayout.hxx:94
SalLayout & operator=(const SalLayout &)=delete
long DeviceCoordinate
bool IsKashidaPosValid(int nCharPos) const override
Definition: sallayout.cxx:1551
virtual void AdjustLayout(ImplLayoutArgs &)
Definition: sallayout.cxx:553
DeviceCoordinate mnLayoutWidth
Definition: sallayout.hxx:90
virtual DeviceCoordinate FillDXArray(DeviceCoordinate *pDXArray) const =0
void GetCaretPositions(int nArraySize, long *pCaretXArray) const override
Definition: sallayout.cxx:1481
abstract base class for physical font faces
const OUString & mrStr
Definition: sallayout.hxx:81
std::ostream & operator<<(std::ostream &s, ImplLayoutArgs const &rArgs)
Definition: sallayout.cxx:52
virtual void DrawText(SalGraphics &) const =0
bool GetNextGlyph(const GlyphItem **pGlyph, Point &rPos, int &nStart, const PhysicalFontFace **pFallbackFont=nullptr) const override
Definition: sallayout.cxx:1505
OString msLanguage
Definition: sallayout.hxx:213
bool PosIsInRun(int nCharPos) const
Definition: sallayout.cxx:281
virtual ~MultiSalLayout() override
Definition: sallayout.cxx:1005
vcl::TextLayoutCache const * m_pTextLayoutCache
Definition: sallayout.hxx:86
bool NeedFallback() const
Definition: sallayout.hxx:114
LanguageTag maLanguageTag
Definition: sallayout.hxx:79
bool GetNextPos(int *nCharPos, bool *bRTL)
Definition: sallayout.cxx:323
virtual void GetCaretPositions(int nArraySize, long *pCaretXArray) const =0
bool GetRun(int *nMinRunPos, int *nEndRunPos, bool *bRTL) const
Definition: sallayout.cxx:367
void AdjustLayout(ImplLayoutArgs &) override
Definition: sallayout.cxx:1030
SalLayoutFlags
Definition: outdev.hxx:119
std::vector< hb_feature_t > maFeatures
Definition: sallayout.hxx:214
void NextRun()
Definition: sallayout.hxx:68
const bool mbFuzzing
Definition: sallayout.hxx:217
void DrawText(SalGraphics &) const override
Definition: sallayout.cxx:1379
bool LayoutText(ImplLayoutArgs &, const SalLayoutGlyphs *) override
Definition: sallayout.cxx:1021
void SetDXArray(const DeviceCoordinate *pDXArray)
Definition: sallayout.hxx:103
void AddRun(int nMinRunPos, int nEndRunPos, bool bRTL)
Definition: sallayout.cxx:257
virtual bool IsKashidaPosValid(int) const
Definition: vcllayout.hxx:88
virtual bool LayoutText(ImplLayoutArgs &, const SalLayoutGlyphs *)=0
void ResetPos()
Definition: sallayout.hxx:67
SalLayoutFlags mnFlags
Definition: sallayout.hxx:80
css::uno::Reference< css::i18n::XBreakIterator > mxBreak
Definition: sallayout.hxx:209
SalLayoutGlyphs m_GlyphItems
Definition: sallayout.hxx:211
ImplLayoutRuns maFallbackRuns
Definition: sallayout.hxx:95
ImplLayoutRuns maFallbackRuns[MAX_FALLBACK]
Definition: sallayout.hxx:154
virtual bool GetNextGlyph(const GlyphItem **pGlyph, Point &rPos, int &nStart, const PhysicalFontFace **pFallbackFont=nullptr) const =0
bool PosIsInAnyRun(int nCharPos) const
Definition: sallayout.cxx:302
DeviceCoordinate FillDXArray(DeviceCoordinate *pDXArray) const override
Definition: sallayout.cxx:1435
virtual const SalLayoutGlyphs * GetGlyphs() const
Definition: sallayout.cxx:1574
sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const override
Definition: sallayout.cxx:1394
const DeviceCoordinate * mpDXArray
Definition: sallayout.hxx:89
::std::vector< B2DPolyPolygon > B2DPolyPolygonVector