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_GLYPHCACHE_HXX
21 : #define _SV_GLYPHCACHE_HXX
22 :
23 : #include <vcl/dllapi.h>
24 :
25 : class GlyphCache;
26 : class GlyphMetric;
27 : class GlyphData;
28 : class ServerFont;
29 : class GlyphCachePeer;
30 : class ServerFontLayoutEngine;
31 : class ServerFontLayout;
32 : class ExtraKernInfo;
33 : struct ImplKernPairData;
34 : class ImplFontOptions;
35 :
36 : #include <tools/gen.hxx>
37 : #include <boost/unordered_map.hpp>
38 : #include <boost/unordered_set.hpp>
39 : #include <boost/shared_ptr.hpp>
40 : #include <com/sun/star/i18n/XBreakIterator.hpp>
41 :
42 : namespace basegfx { class B2DPolyPolygon; }
43 :
44 : class RawBitmap;
45 :
46 : #include <outfont.hxx>
47 : #include <impfont.hxx>
48 :
49 : class ServerFontLayout;
50 : #include <sallayout.hxx>
51 :
52 : #include <config_graphite.h>
53 : #if ENABLE_GRAPHITE
54 : class GraphiteFaceWrapper;
55 : #endif
56 :
57 : #include <ft2build.h>
58 : #include FT_FREETYPE_H
59 : #include FT_GLYPH_H
60 :
61 : namespace vcl
62 : {
63 : struct FontCapabilities;
64 : }
65 :
66 : // =======================================================================
67 :
68 : class VCL_DLLPUBLIC GlyphCache
69 : {
70 : public:
71 : explicit GlyphCache( GlyphCachePeer& );
72 : /*virtual*/ ~GlyphCache();
73 :
74 : static GlyphCache& GetInstance();
75 :
76 : void AddFontFile( const OString& rNormalizedName,
77 : int nFaceNum, sal_IntPtr nFontId, const ImplDevFontAttributes&,
78 : const ExtraKernInfo* = NULL );
79 : void AnnounceFonts( ImplDevFontList* ) const;
80 :
81 : ServerFont* CacheFont( const FontSelectPattern& );
82 : void UncacheFont( ServerFont& );
83 : void ClearFontCache();
84 : void InvalidateAllGlyphs();
85 :
86 : protected:
87 : GlyphCachePeer& mrPeer;
88 :
89 : private:
90 : friend class ServerFont;
91 : // used by ServerFont class only
92 : void AddedGlyph( ServerFont&, GlyphData& );
93 : void RemovingGlyph( ServerFont&, GlyphData&, int nGlyphIndex );
94 : void UsingGlyph( ServerFont&, GlyphData& );
95 : void GrowNotify();
96 :
97 : private:
98 : void GarbageCollect();
99 :
100 : // the GlyphCache's FontList matches a font request to a serverfont instance
101 : // the FontList key's mpFontData member is reinterpreted as integer font id
102 : struct IFSD_Equal{ bool operator()( const FontSelectPattern&, const FontSelectPattern& ) const; };
103 : struct IFSD_Hash{ size_t operator()( const FontSelectPattern& ) const; };
104 : typedef ::boost::unordered_map<FontSelectPattern,ServerFont*,IFSD_Hash,IFSD_Equal > FontList;
105 : FontList maFontList;
106 : sal_uLong mnMaxSize; // max overall cache size in bytes
107 : mutable sal_uLong mnBytesUsed;
108 : mutable long mnLruIndex;
109 : mutable int mnGlyphCount;
110 : ServerFont* mpCurrentGCFont;
111 :
112 : class FreetypeManager* mpFtManager;
113 : };
114 :
115 : // =======================================================================
116 :
117 25311 : class GlyphMetric
118 : {
119 : public:
120 188644 : Point GetOffset() const { return maOffset; }
121 : Point GetDelta() const { return maDelta; }
122 188644 : Size GetSize() const { return maSize; }
123 12058782 : long GetCharWidth() const { return mnAdvanceWidth; }
124 :
125 : protected:
126 : friend class GlyphData;
127 25311 : void SetOffset( int nX, int nY ) { maOffset = Point( nX, nY); }
128 25311 : void SetDelta( int nX, int nY ) { maDelta = Point( nX, nY); }
129 25311 : void SetSize( const Size& s ) { maSize = s; }
130 25311 : void SetCharWidth( long nW ) { mnAdvanceWidth = nW; }
131 :
132 : private:
133 : long mnAdvanceWidth;
134 : Point maDelta;
135 : Point maOffset;
136 : Size maSize;
137 : };
138 :
139 : // -----------------------------------------------------------------------
140 :
141 : // the glyph specific data needed by a GlyphCachePeer is usually trivial,
142 : // not attaching it to the corresponding GlyphData would be overkill
143 : struct ExtGlyphData
144 : {
145 : int meInfo;
146 : void* mpData;
147 :
148 25311 : ExtGlyphData() : meInfo(0), mpData(NULL) {}
149 : };
150 :
151 : // -----------------------------------------------------------------------
152 :
153 25311 : class GlyphData
154 : {
155 : public:
156 12247426 : const GlyphMetric& GetMetric() const { return maMetric; }
157 : Size GetSize() const { return maMetric.GetSize(); }
158 :
159 25311 : void SetSize( const Size& s) { maMetric.SetSize( s ); }
160 25311 : void SetOffset( int nX, int nY ) { maMetric.SetOffset( nX, nY ); }
161 25311 : void SetDelta( int nX, int nY ) { maMetric.SetDelta( nX, nY ); }
162 25311 : void SetCharWidth( long nW ) { maMetric.SetCharWidth( nW ); }
163 :
164 13151913 : void SetLruValue( int n ) const { mnLruValue = n; }
165 0 : long GetLruValue() const { return mnLruValue;}
166 :
167 2716119 : ExtGlyphData& ExtDataRef() { return maExtData; }
168 : const ExtGlyphData& ExtDataRef() const { return maExtData; }
169 :
170 : private:
171 : GlyphMetric maMetric;
172 : ExtGlyphData maExtData;
173 :
174 : // used by GlyphCache for cache LRU algorithm
175 : mutable long mnLruValue;
176 : };
177 :
178 : // =======================================================================
179 :
180 : class FtFontInfo;
181 :
182 : class VCL_DLLPUBLIC ServerFont
183 : {
184 : public:
185 : ServerFont( const FontSelectPattern&, FtFontInfo* );
186 : virtual ~ServerFont();
187 :
188 : const OString* GetFontFileName() const;
189 : bool TestFont() const;
190 : FT_Face GetFtFace() const;
191 0 : int GetLoadFlags() const { return (mnLoadFlags & ~FT_LOAD_IGNORE_TRANSFORM); }
192 : void SetFontOptions( boost::shared_ptr<ImplFontOptions> );
193 : boost::shared_ptr<ImplFontOptions> GetFontOptions() const;
194 0 : bool NeedsArtificialBold() const { return mbArtBold; }
195 0 : bool NeedsArtificialItalic() const { return mbArtItalic; }
196 :
197 12997124 : const FontSelectPattern& GetFontSelData() const { return maFontSelData; }
198 :
199 : void FetchFontMetric( ImplFontMetricData&, long& rFactor ) const;
200 : sal_uLong GetKernPairs( ImplKernPairData** ) const;
201 : const unsigned char* GetTable( const char* pName, sal_uLong* pLength );
202 : int GetEmUnits() const;
203 : const FT_Size_Metrics& GetMetricsFT() const { return maSizeFT->metrics; }
204 : const ImplFontCharMap* GetImplFontCharMap() const;
205 : bool GetFontCapabilities(vcl::FontCapabilities &) const;
206 :
207 : GlyphData& GetGlyphData( int nGlyphIndex );
208 12246540 : const GlyphMetric& GetGlyphMetric( int nGlyphIndex )
209 12246540 : { return GetGlyphData( nGlyphIndex ).GetMetric(); }
210 : #if ENABLE_GRAPHITE
211 : virtual GraphiteFaceWrapper* GetGraphiteFace() const;
212 : #endif
213 :
214 : int GetGlyphIndex( sal_UCS4 ) const;
215 : int GetRawGlyphIndex( sal_UCS4, sal_UCS4 = 0 ) const;
216 : int FixupGlyphIndex( int nGlyphIndex, sal_UCS4 ) const;
217 : bool GetGlyphOutline( int nGlyphIndex, ::basegfx::B2DPolyPolygon& ) const;
218 : bool GetAntialiasAdvice( void ) const;
219 : bool GetGlyphBitmap1( int nGlyphIndex, RawBitmap& ) const;
220 : bool GetGlyphBitmap8( int nGlyphIndex, RawBitmap& ) const;
221 :
222 : void SetExtended( int nInfo, void* ppVoid );
223 : int GetExtInfo() { return mnExtInfo; }
224 : void* GetExtPointer() { return mpExtData; }
225 :
226 : private:
227 : friend class GlyphCache;
228 : friend class ServerFontLayout;
229 : friend class ImplServerFontEntry;
230 : friend class X11SalGraphics;
231 :
232 183081 : void AddRef() const { ++mnRefCount; }
233 0 : long GetRefCount() const { return mnRefCount; }
234 : long Release() const;
235 2350 : sal_uLong GetByteCount() const { return mnBytesUsed; }
236 :
237 : void InitGlyphData( int nGlyphIndex, GlyphData& ) const;
238 : void GarbageCollect( long );
239 : void ReleaseFromGarbageCollect();
240 :
241 : int ApplyGlyphTransform( int nGlyphFlags, FT_GlyphRec_*, bool ) const;
242 : bool ApplyGSUB( const FontSelectPattern& );
243 :
244 : ServerFontLayoutEngine* GetLayoutEngine();
245 :
246 : typedef ::boost::unordered_map<int,GlyphData> GlyphList;
247 : mutable GlyphList maGlyphList;
248 :
249 : const FontSelectPattern maFontSelData;
250 :
251 : // info for GlyphcachePeer
252 : int mnExtInfo;
253 : void* mpExtData;
254 :
255 : // used by GlyphCache for cache LRU algorithm
256 : mutable long mnRefCount;
257 : mutable sal_uLong mnBytesUsed;
258 :
259 : ServerFont* mpPrevGCFont;
260 : ServerFont* mpNextGCFont;
261 :
262 : // 16.16 fixed point values used for a rotated font
263 : long mnCos;
264 : long mnSin;
265 :
266 : bool mbCollectedZW;
267 :
268 : int mnWidth;
269 : int mnPrioEmbedded;
270 : int mnPrioAntiAlias;
271 : int mnPrioAutoHint;
272 : FtFontInfo* mpFontInfo;
273 : FT_Int mnLoadFlags;
274 : double mfStretch;
275 : FT_FaceRec_* maFaceFT;
276 : FT_SizeRec_* maSizeFT;
277 :
278 : boost::shared_ptr<ImplFontOptions> mpFontOptions;
279 :
280 : bool mbFaceOk;
281 : bool mbArtItalic;
282 : bool mbArtBold;
283 : bool mbUseGamma;
284 :
285 : typedef ::boost::unordered_map<int,int> GlyphSubstitution;
286 : GlyphSubstitution maGlyphSubstitution;
287 : rtl_UnicodeToTextConverter maRecodeConverter;
288 :
289 : ServerFontLayoutEngine* mpLayoutEngine;
290 : };
291 :
292 : // =======================================================================
293 :
294 : // a class for cache entries for physical font instances that are based on serverfonts
295 : class VCL_DLLPUBLIC ImplServerFontEntry : public ImplFontEntry
296 : {
297 : private:
298 : ServerFont* mpServerFont;
299 : boost::shared_ptr<ImplFontOptions> mpFontOptions;
300 : bool mbGotFontOptions;
301 :
302 : public:
303 : ImplServerFontEntry( FontSelectPattern& );
304 : virtual ~ImplServerFontEntry();
305 : void SetServerFont(ServerFont* p);
306 : void HandleFontOptions();
307 : };
308 :
309 : // =======================================================================
310 :
311 1455311 : class VCL_DLLPUBLIC ServerFontLayout : public GenericSalLayout
312 : {
313 : private:
314 : ServerFont& mrServerFont;
315 : com::sun::star::uno::Reference<com::sun::star::i18n::XBreakIterator> mxBreak;
316 :
317 : // enforce proper copy semantic
318 : SAL_DLLPRIVATE ServerFontLayout( const ServerFontLayout& );
319 : SAL_DLLPRIVATE ServerFontLayout& operator=( const ServerFontLayout& );
320 :
321 : bool bUseHarfBuzz;
322 :
323 : public:
324 : ServerFontLayout( ServerFont& );
325 : virtual bool LayoutText( ImplLayoutArgs& );
326 : virtual void AdjustLayout( ImplLayoutArgs& );
327 : virtual void DrawText( SalGraphics& ) const;
328 : void setNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nIndex,
329 : bool bRightToLeft);
330 :
331 728181 : ServerFont& GetServerFont() const { return mrServerFont; }
332 : };
333 :
334 : // =======================================================================
335 :
336 1716 : class ServerFontLayoutEngine
337 : {
338 : public:
339 1716 : virtual ~ServerFontLayoutEngine() {}
340 : virtual bool layout(ServerFontLayout&, ImplLayoutArgs&) = 0;
341 : };
342 :
343 : // =======================================================================
344 :
345 : class GlyphCachePeer
346 : {
347 : protected:
348 125 : GlyphCachePeer() : mnBytesUsed(0) {}
349 125 : virtual ~GlyphCachePeer() {}
350 :
351 : public:
352 33326 : sal_Int32 GetByteCount() const { return mnBytesUsed; }
353 0 : virtual void RemovingFont( ServerFont& ) {}
354 0 : virtual void RemovingGlyph( ServerFont&, GlyphData&, int ) {}
355 :
356 : protected:
357 : sal_Int32 mnBytesUsed;
358 : };
359 :
360 : // =======================================================================
361 :
362 : class VCL_DLLPUBLIC RawBitmap
363 : {
364 : public:
365 : RawBitmap();
366 : ~RawBitmap();
367 : bool Rotate( int nAngle );
368 :
369 : public:
370 : unsigned char* mpBits;
371 : sal_uLong mnAllocated;
372 :
373 : sal_uLong mnWidth;
374 : sal_uLong mnHeight;
375 :
376 : sal_uLong mnScanlineSize;
377 : sal_uLong mnBitCount;
378 :
379 : int mnXOffset;
380 : int mnYOffset;
381 : };
382 :
383 : // =======================================================================
384 :
385 905370 : inline void ServerFont::SetExtended( int nInfo, void* pVoid )
386 : {
387 905370 : mnExtInfo = nInfo;
388 905370 : mpExtData = pVoid;
389 905370 : }
390 :
391 : // =======================================================================
392 :
393 : // ExtraKernInfo allows an on-demand query of extra kerning info #i29881#
394 : // The kerning values have to be scaled to match the font size before use
395 : class VCL_DLLPUBLIC ExtraKernInfo
396 : {
397 : public:
398 : ExtraKernInfo( sal_IntPtr nFontId );
399 5875 : virtual ~ExtraKernInfo() {}
400 :
401 : int GetUnscaledKernPairs( ImplKernPairData** ) const;
402 :
403 : protected:
404 : mutable bool mbInitialized;
405 : virtual void Initialize() const = 0;
406 :
407 : protected:
408 : sal_IntPtr mnFontId;
409 :
410 : // container to map a unicode pair to an unscaled kerning value
411 0 : struct PairEqual{ int operator()(const ImplKernPairData& rA, const ImplKernPairData& rB) const
412 0 : { return (rA.mnChar1 == rB.mnChar1) && (rA.mnChar2 == rB.mnChar2); } };
413 0 : struct PairHash{ int operator()(const ImplKernPairData& rA) const
414 0 : { return (rA.mnChar1) * 256 ^ rA.mnChar2; } };
415 : typedef boost::unordered_set< ImplKernPairData, PairHash, PairEqual > UnicodeKernPairs;
416 : mutable UnicodeKernPairs maUnicodeKernPairs;
417 : };
418 :
419 : // =======================================================================
420 :
421 : #endif // _SV_GLYPHCACHE_HXX
422 :
423 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|