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