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 INCLUDED_VCL_INC_SALLAYOUT_HXX
21 : #define INCLUDED_VCL_INC_SALLAYOUT_HXX
22 :
23 : #include <iostream>
24 : #include <list>
25 : #include <vector>
26 :
27 : #include <basegfx/polygon/b2dpolypolygon.hxx>
28 : #include <i18nlangtag/languagetag.hxx>
29 : #include <tools/gen.hxx>
30 : #include <vcl/dllapi.h>
31 : #include <vcl/vclenum.hxx> // for typedef sal_UCS4
32 :
33 : #ifndef _TOOLS_LANG_HXX
34 : typedef unsigned short LanguageType;
35 : #endif
36 :
37 : #include "magic.h"
38 : #include "salglyphid.hxx"
39 :
40 : class SalGraphics;
41 : class PhysicalFontFace;
42 :
43 : // Layout options
44 : #define SAL_LAYOUT_BIDI_RTL 0x0001
45 : #define SAL_LAYOUT_BIDI_STRONG 0x0002
46 : #define SAL_LAYOUT_RIGHT_ALIGN 0x0004
47 : #define SAL_LAYOUT_KERNING_PAIRS 0x0010
48 : #define SAL_LAYOUT_KERNING_ASIAN 0x0020
49 : #define SAL_LAYOUT_VERTICAL 0x0040
50 : #define SAL_LAYOUT_COMPLEX_DISABLED 0x0100
51 : #define SAL_LAYOUT_ENABLE_LIGATURES 0x0200
52 : #define SAL_LAYOUT_SUBSTITUTE_DIGITS 0x0400
53 : #define SAL_LAYOUT_KASHIDA_JUSTIFICATON 0x0800
54 : #define SAL_LAYOUT_DISABLE_GLYPH_PROCESSING 0x1000
55 : #define SAL_LAYOUT_FOR_FALLBACK 0x2000
56 :
57 : // used for managing runs e.g. for BiDi, glyph and script fallback
58 0 : class VCL_PLUGIN_PUBLIC ImplLayoutRuns
59 : {
60 : private:
61 : int mnRunIndex;
62 : std::vector<int> maRuns;
63 :
64 : public:
65 0 : ImplLayoutRuns() { mnRunIndex = 0; maRuns.reserve(8); }
66 :
67 0 : void Clear() { maRuns.clear(); }
68 : bool AddPos( int nCharPos, bool bRTL );
69 : bool AddRun( int nMinRunPos, int nEndRunPos, bool bRTL );
70 :
71 0 : bool IsEmpty() const { return maRuns.empty(); }
72 0 : void ResetPos() { mnRunIndex = 0; }
73 0 : void NextRun() { mnRunIndex += 2; }
74 : bool GetRun( int* nMinRunPos, int* nEndRunPos, bool* bRTL ) const;
75 : bool GetNextPos( int* nCharPos, bool* bRTL );
76 : bool PosIsInRun( int nCharPos ) const;
77 : bool PosIsInAnyRun( int nCharPos ) const;
78 : };
79 :
80 0 : class ImplLayoutArgs
81 : {
82 : public:
83 : // string related inputs
84 : LanguageTag maLanguageTag;
85 : int mnFlags;
86 : int mnLength;
87 : int mnMinCharPos;
88 : int mnEndCharPos;
89 : const sal_Unicode* mpStr;
90 :
91 : // positioning related inputs
92 : const sal_Int32* mpDXArray; // in pixel units
93 : long mnLayoutWidth; // in pixel units
94 : int mnOrientation; // in 0-3600 system
95 :
96 : // data for bidi and glyph+script fallback
97 : ImplLayoutRuns maRuns;
98 : ImplLayoutRuns maFallbackRuns;
99 :
100 : public:
101 : ImplLayoutArgs( const sal_Unicode* pStr, int nLength,
102 : int nMinCharPos, int nEndCharPos, int nFlags, const LanguageTag& rLanguageTag );
103 :
104 0 : void SetLayoutWidth( long nWidth ) { mnLayoutWidth = nWidth; }
105 0 : void SetDXArray( const sal_Int32* pDXArray ) { mpDXArray = pDXArray; }
106 0 : void SetOrientation( int nOrientation ) { mnOrientation = nOrientation; }
107 :
108 0 : void ResetPos()
109 0 : { maRuns.ResetPos(); }
110 0 : bool GetNextPos( int* nCharPos, bool* bRTL )
111 0 : { return maRuns.GetNextPos( nCharPos, bRTL ); }
112 : bool GetNextRun( int* nMinRunPos, int* nEndRunPos, bool* bRTL );
113 0 : bool NeedFallback( int nCharPos, bool bRTL )
114 0 : { return maFallbackRuns.AddPos( nCharPos, bRTL ); }
115 0 : bool NeedFallback( int nMinRunPos, int nEndRunPos, bool bRTL )
116 0 : { return maFallbackRuns.AddRun( nMinRunPos, nEndRunPos, bRTL ); }
117 : // methods used by BiDi and glyph fallback
118 0 : bool NeedFallback() const
119 0 : { return !maFallbackRuns.IsEmpty(); }
120 : bool PrepareFallback();
121 :
122 : protected:
123 : void AddRun( int nMinCharPos, int nEndCharPos, bool bRTL );
124 : };
125 :
126 : // For nice SAL_INFO logging of ImplLayoutArgs values
127 : std::ostream &operator <<(std::ostream& s, ImplLayoutArgs &rArgs);
128 :
129 : // helper functions often used with ImplLayoutArgs
130 : bool IsDiacritic( sal_UCS4 );
131 : int GetVerticalFlags( sal_UCS4 );
132 : sal_UCS4 GetVerticalChar( sal_UCS4 );
133 :
134 : // all positions/widths are in font units
135 : // one exception: drawposition is in pixel units
136 :
137 : // Unfortunately there is little documentation to help implementors of
138 : // new classes derived from SalLayout ("layout engines"), and the code
139 : // and data structures are far from obvious.
140 :
141 : // For instance, I *think* the important virtual functions in the
142 : // layout engines are called in this order:
143 :
144 : // * InitFont()
145 : // * LayoutText()
146 : // * AdjustLayout(), any number of times (but presumably
147 : // usually not at all or just once)
148 : // * Optionally, DrawText()
149 :
150 : // Functions that just return information like GetTexWidth() and
151 : // FillDXArray() are called after LayoutText() and before DrawText().
152 :
153 : // Another important questions is which parts of an ImplLayoutArgs can
154 : // be changed by callers between LayoutText() and AdjustLayout()
155 : // calls. It probably makes sense only if one assumes that the "string
156 : // related inputs" part are not changed after LayoutText().
157 :
158 : // But why use the same ImplLayoutArgs structure as parameter for both
159 : // LayoutText() and AdjustLayout() in the first place? And why
160 : // duplicate some of the fields in both SalLayout and ImplLayoutArgs
161 : // (mnMinCharPos, mnEndCharPos, mnLayoutFlags==mnFlags,
162 : // mnOrientation)? Lost in history...
163 :
164 : class VCL_PLUGIN_PUBLIC SalLayout
165 : {
166 : public:
167 : // used by upper layers
168 0 : Point& DrawBase() { return maDrawBase; }
169 0 : const Point& DrawBase() const { return maDrawBase; }
170 0 : Point& DrawOffset() { return maDrawOffset; }
171 : const Point& DrawOffset() const { return maDrawOffset; }
172 : Point GetDrawPosition( const Point& rRelative = Point(0,0) ) const;
173 :
174 : virtual bool LayoutText( ImplLayoutArgs& ) = 0; // first step of layouting
175 : virtual void AdjustLayout( ImplLayoutArgs& ); // adjusting after fallback etc.
176 0 : virtual void InitFont() const {}
177 : virtual void DrawText( SalGraphics& ) const = 0;
178 0 : virtual bool DrawTextSpecial( SalGraphics& /* rGraphics */, sal_uInt32 /* flags */ ) const { return false; }
179 : #define DRAWTEXT_F_OUTLINE ((sal_uInt32)(1<<0))
180 :
181 0 : int GetUnitsPerPixel() const { return mnUnitsPerPixel; }
182 0 : int GetOrientation() const { return mnOrientation; }
183 :
184 : // methods using string indexing
185 : virtual sal_Int32 GetTextBreak(long nMaxWidth, long nCharExtra=0, int nFactor=1) const = 0;
186 : virtual long FillDXArray( sal_Int32* pDXArray ) const = 0;
187 0 : virtual long GetTextWidth() const { return FillDXArray( NULL ); }
188 : virtual void GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray ) const = 0;
189 0 : virtual bool IsKashidaPosValid ( int /*nCharPos*/ ) const { return true; } // i60594
190 :
191 : // methods using glyph indexing
192 : virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdAry, Point& rPos, int&,
193 : sal_Int32* pGlyphAdvAry = NULL, int* pCharPosAry = NULL,
194 : const PhysicalFontFace** pFallbackFonts = NULL ) const = 0;
195 : virtual bool GetOutline( SalGraphics&, ::basegfx::B2DPolyPolygonVector& ) const;
196 : virtual bool GetBoundRect( SalGraphics&, Rectangle& ) const;
197 :
198 : virtual bool IsSpacingGlyph( sal_GlyphId ) const;
199 :
200 : // reference counting
201 : void Release() const;
202 :
203 : // used by glyph+font+script fallback
204 : virtual void MoveGlyph( int nStart, long nNewXPos ) = 0;
205 : virtual void DropGlyph( int nStart ) = 0;
206 : virtual void Simplify( bool bIsBase ) = 0;
207 0 : virtual void DisableGlyphInjection( bool /*bDisable*/ ) {}
208 :
209 : protected:
210 : // used by layout engines
211 : SalLayout();
212 : virtual ~SalLayout();
213 :
214 : // used by layout layers
215 0 : void SetUnitsPerPixel( int n ) { mnUnitsPerPixel = n; }
216 0 : void SetOrientation( int nOrientation ) // in 0-3600 system
217 0 : { mnOrientation = nOrientation; }
218 :
219 : static int CalcAsianKerning( sal_UCS4, bool bLeft, bool bVertical );
220 :
221 : private:
222 : // enforce proper copy semantic
223 : SAL_DLLPRIVATE SalLayout( const SalLayout& );
224 : SAL_DLLPRIVATE SalLayout& operator=( const SalLayout& );
225 :
226 : protected:
227 : int mnMinCharPos;
228 : int mnEndCharPos;
229 : int mnLayoutFlags;
230 :
231 : int mnUnitsPerPixel;
232 : int mnOrientation;
233 :
234 : mutable int mnRefCount;
235 : mutable Point maDrawOffset;
236 : Point maDrawBase;
237 : };
238 :
239 : class VCL_PLUGIN_PUBLIC MultiSalLayout : public SalLayout
240 : {
241 : public:
242 : virtual void DrawText( SalGraphics& ) const SAL_OVERRIDE;
243 : virtual sal_Int32 GetTextBreak(long nMaxWidth, long nCharExtra, int nFactor) const SAL_OVERRIDE;
244 : virtual long FillDXArray( sal_Int32* pDXArray ) const SAL_OVERRIDE;
245 : virtual void GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray ) const SAL_OVERRIDE;
246 : virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos,
247 : int&, sal_Int32* pGlyphAdvAry, int* pCharPosAry,
248 : const PhysicalFontFace** pFallbackFonts ) const SAL_OVERRIDE;
249 : virtual bool GetOutline( SalGraphics&, ::basegfx::B2DPolyPolygonVector& ) const SAL_OVERRIDE;
250 :
251 : // used only by OutputDevice::ImplLayout, TODO: make friend
252 : explicit MultiSalLayout( SalLayout& rBaseLayout,
253 : const PhysicalFontFace* pBaseFont = NULL );
254 : virtual bool AddFallback( SalLayout& rFallbackLayout,
255 : ImplLayoutRuns&, const PhysicalFontFace* pFallbackFont );
256 : virtual bool LayoutText( ImplLayoutArgs& ) SAL_OVERRIDE;
257 : virtual void AdjustLayout( ImplLayoutArgs& ) SAL_OVERRIDE;
258 : virtual void InitFont() const SAL_OVERRIDE;
259 :
260 : void SetInComplete(bool bInComplete = true);
261 :
262 : protected:
263 : virtual ~MultiSalLayout();
264 :
265 : private:
266 : // dummy implementations
267 0 : virtual void MoveGlyph( int, long ) SAL_OVERRIDE {}
268 0 : virtual void DropGlyph( int ) SAL_OVERRIDE {}
269 0 : virtual void Simplify( bool ) SAL_OVERRIDE {}
270 :
271 : // enforce proper copy semantic
272 : SAL_DLLPRIVATE MultiSalLayout( const MultiSalLayout& );
273 : SAL_DLLPRIVATE MultiSalLayout& operator=( const MultiSalLayout& );
274 :
275 : private:
276 : SalLayout* mpLayouts[ MAX_FALLBACK ];
277 : const PhysicalFontFace* mpFallbackFonts[ MAX_FALLBACK ];
278 : ImplLayoutRuns maFallbackRuns[ MAX_FALLBACK ];
279 : int mnLevel;
280 : bool mbInComplete;
281 : };
282 :
283 : struct GlyphItem
284 : {
285 : int mnFlags;
286 : int mnCharPos; // index in string
287 : int mnOrigWidth; // original glyph width
288 : int mnNewWidth; // width after adjustments
289 : int mnXOffset;
290 : sal_GlyphId maGlyphId;
291 : Point maLinearPos; // absolute position of non rotated string
292 :
293 : public:
294 0 : GlyphItem() {}
295 :
296 0 : GlyphItem( int nCharPos, sal_GlyphId aGlyphId, const Point& rLinearPos,
297 : long nFlags, int nOrigWidth )
298 : : mnFlags(nFlags), mnCharPos(nCharPos),
299 : mnOrigWidth(nOrigWidth), mnNewWidth(nOrigWidth),
300 : mnXOffset(0),
301 0 : maGlyphId(aGlyphId), maLinearPos(rLinearPos)
302 0 : {}
303 :
304 0 : GlyphItem( int nCharPos, sal_GlyphId aGlyphId, const Point& rLinearPos,
305 : long nFlags, int nOrigWidth, int nXOffset )
306 : : mnFlags(nFlags), mnCharPos(nCharPos),
307 : mnOrigWidth(nOrigWidth), mnNewWidth(nOrigWidth),
308 : mnXOffset(nXOffset),
309 0 : maGlyphId(aGlyphId), maLinearPos(rLinearPos)
310 0 : {}
311 :
312 : enum{ FALLBACK_MASK=0xFF, IS_IN_CLUSTER=0x100, IS_RTL_GLYPH=0x200, IS_DIACRITIC=0x400 };
313 :
314 0 : bool IsClusterStart() const { return ((mnFlags & IS_IN_CLUSTER) == 0); }
315 0 : bool IsRTLGlyph() const { return ((mnFlags & IS_RTL_GLYPH) != 0); }
316 0 : bool IsDiacritic() const { return ((mnFlags & IS_DIACRITIC) != 0); }
317 : };
318 :
319 : typedef std::list<GlyphItem> GlyphList;
320 : typedef std::vector<GlyphItem> GlyphVector;
321 :
322 : class VCL_PLUGIN_PUBLIC GenericSalLayout : public SalLayout
323 : {
324 : public:
325 : // used by layout engines
326 : void AppendGlyph( const GlyphItem& );
327 0 : void Reserve(int size) { m_GlyphItems.reserve(size + 1); }
328 : virtual void AdjustLayout( ImplLayoutArgs& ) SAL_OVERRIDE;
329 : virtual void ApplyDXArray( ImplLayoutArgs& );
330 : virtual void Justify( long nNewWidth );
331 : void KashidaJustify( long nIndex, int nWidth );
332 : void ApplyAsianKerning( const sal_Unicode*, int nLength );
333 : void SortGlyphItems();
334 :
335 : // used by upper layers
336 : virtual long GetTextWidth() const SAL_OVERRIDE;
337 : virtual long FillDXArray( sal_Int32* pDXArray ) const SAL_OVERRIDE;
338 : virtual sal_Int32 GetTextBreak(long nMaxWidth, long nCharExtra, int nFactor) const SAL_OVERRIDE;
339 : virtual void GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray ) const SAL_OVERRIDE;
340 :
341 : // used by display layers
342 : virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos, int&,
343 : sal_Int32* pGlyphAdvAry = NULL, int* pCharPosAry = NULL,
344 : const PhysicalFontFace** pFallbackFonts = NULL ) const SAL_OVERRIDE;
345 :
346 : protected:
347 : GenericSalLayout();
348 : virtual ~GenericSalLayout();
349 :
350 : // for glyph+font+script fallback
351 : virtual void MoveGlyph( int nStart, long nNewXPos ) SAL_OVERRIDE;
352 : virtual void DropGlyph( int nStart ) SAL_OVERRIDE;
353 : virtual void Simplify( bool bIsBase ) SAL_OVERRIDE;
354 :
355 : bool GetCharWidths( sal_Int32* pCharWidths ) const;
356 :
357 : GlyphVector m_GlyphItems;
358 :
359 : private:
360 : mutable Point maBasePoint;
361 :
362 : // enforce proper copy semantic
363 : SAL_DLLPRIVATE GenericSalLayout( const GenericSalLayout& );
364 : SAL_DLLPRIVATE GenericSalLayout& operator=( const GenericSalLayout& );
365 : };
366 :
367 : #undef SalGraphics
368 :
369 : #endif // INCLUDED_VCL_INC_SALLAYOUT_HXX
370 :
371 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|