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