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