1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef _SV_GLYPHCACHE_HXX
25 #define _SV_GLYPHCACHE_HXX
26
27 #include <vcl/dllapi.h>
28
29 class GlyphCache;
30 class GlyphMetric;
31 class GlyphData;
32 class ServerFont;
33 class GlyphCachePeer;
34 class ServerFontLayoutEngine;
35 class ServerFontLayout;
36 class ExtraKernInfo;
37 struct ImplKernPairData;
38 class ImplFontOptions;
39
40 #include <tools/gen.hxx>
41 #include <hash_map>
42 #include <hash_set>
43
44 namespace basegfx { class B2DPolyPolygon; }
45
46 class RawBitmap;
47
48 #include <outfont.hxx>
49 #include <impfont.hxx>
50
51 class ServerFontLayout;
52 #include <sallayout.hxx>
53
54 // =======================================================================
55
56 class VCL_PLUGIN_PUBLIC GlyphCache
57 {
58 public:
59 explicit GlyphCache( GlyphCachePeer& );
60 /*virtual*/ ~GlyphCache();
61
62 static GlyphCache& GetInstance();
63 void LoadFonts();
64
65 void ClearFontPath();
66 void AddFontPath( const String& rFontPath );
67 void AddFontFile( const rtl::OString& rNormalizedName,
68 int nFaceNum, sal_IntPtr nFontId, const ImplDevFontAttributes&,
69 const ExtraKernInfo* = NULL );
70 void AnnounceFonts( ImplDevFontList* ) const;
71
72 ServerFont* CacheFont( const ImplFontSelectData& );
73 void UncacheFont( ServerFont& );
74 void InvalidateAllGlyphs();
75
76 protected:
77 GlyphCachePeer& mrPeer;
78
79 private:
80 friend class ServerFont;
81 // used by ServerFont class only
82 void AddedGlyph( ServerFont&, GlyphData& );
83 void RemovingGlyph( ServerFont&, GlyphData&, sal_GlyphId );
84 void UsingGlyph( ServerFont&, GlyphData& );
85 void GrowNotify();
86
87 private:
88 sal_uLong CalcByteCount() const;
89 void GarbageCollect();
90
91 // the GlyphCache's FontList matches a font request to a serverfont instance
92 // the FontList key's mpFontData member is reinterpreted as integer font id
93 struct IFSD_Equal{ bool operator()( const ImplFontSelectData&, const ImplFontSelectData& ) const; };
94 struct IFSD_Hash{ size_t operator()( const ImplFontSelectData& ) const; };
95 typedef ::std::hash_map<ImplFontSelectData,ServerFont*,IFSD_Hash,IFSD_Equal > FontList;
96 FontList maFontList;
97 sal_uLong mnMaxSize; // max overall cache size in bytes
98 mutable sal_uLong mnBytesUsed;
99 mutable long mnLruIndex;
100 mutable int mnGlyphCount;
101 ServerFont* mpCurrentGCFont;
102
103 class FreetypeManager* mpFtManager;
104 };
105
106 // =======================================================================
107
108 class GlyphMetric
109 {
110 public:
GetOffset() const111 Point GetOffset() const { return maOffset; }
GetDelta() const112 Point GetDelta() const { return maDelta; }
GetSize() const113 Size GetSize() const { return maSize; }
GetCharWidth() const114 long GetCharWidth() const { return mnAdvanceWidth; }
115
116 protected:
117 friend class GlyphData;
SetOffset(int nX,int nY)118 void SetOffset( int nX, int nY ) { maOffset = Point( nX, nY); }
SetDelta(int nX,int nY)119 void SetDelta( int nX, int nY ) { maDelta = Point( nX, nY); }
SetSize(const Size & s)120 void SetSize( const Size& s ) { maSize = s; }
SetCharWidth(long nW)121 void SetCharWidth( long nW ) { mnAdvanceWidth = nW; }
122
123 private:
124 long mnAdvanceWidth;
125 Point maDelta;
126 Point maOffset;
127 Size maSize;
128 };
129
130 // -----------------------------------------------------------------------
131
132 // the glyph specific data needed by a GlyphCachePeer is usually trivial,
133 // not attaching it to the corresponding GlyphData would be overkill
134 struct ExtGlyphData
135 {
136 int meInfo;
137 void* mpData;
138
ExtGlyphDataExtGlyphData139 ExtGlyphData() : meInfo(0), mpData(NULL) {}
140 };
141
142 // -----------------------------------------------------------------------
143
144 class GlyphData
145 {
146 public:
GetMetric() const147 const GlyphMetric& GetMetric() const { return maMetric; }
GetSize() const148 Size GetSize() const { return maMetric.GetSize(); }
149
SetSize(const Size & s)150 void SetSize( const Size& s) { maMetric.SetSize( s ); }
SetOffset(int nX,int nY)151 void SetOffset( int nX, int nY ) { maMetric.SetOffset( nX, nY ); }
SetDelta(int nX,int nY)152 void SetDelta( int nX, int nY ) { maMetric.SetDelta( nX, nY ); }
SetCharWidth(long nW)153 void SetCharWidth( long nW ) { maMetric.SetCharWidth( nW ); }
154
SetLruValue(int n) const155 void SetLruValue( int n ) const { mnLruValue = n; }
GetLruValue() const156 long GetLruValue() const { return mnLruValue;}
157
ExtDataRef()158 ExtGlyphData& ExtDataRef() { return maExtData; }
ExtDataRef() const159 const ExtGlyphData& ExtDataRef() const { return maExtData; }
160
161 private:
162 GlyphMetric maMetric;
163 ExtGlyphData maExtData;
164
165 // used by GlyphCache for cache LRU algorithm
166 mutable long mnLruValue;
167 };
168
169 // =======================================================================
170
171 class VCL_PLUGIN_PUBLIC ServerFont
172 {
173 public:
GetFontFileName() const174 virtual const ::rtl::OString* GetFontFileName() const { return NULL; }
GetFontFaceNumber() const175 virtual int GetFontFaceNumber() const { return 0; }
TestFont() const176 virtual bool TestFont() const { return true; }
GetFtFace() const177 virtual void* GetFtFace() const { return 0; }
GetLoadFlags() const178 virtual int GetLoadFlags() const { return 0; }
SetFontOptions(const ImplFontOptions &)179 virtual void SetFontOptions( const ImplFontOptions&) {}
NeedsArtificialBold() const180 virtual bool NeedsArtificialBold() const { return false; }
NeedsArtificialItalic() const181 virtual bool NeedsArtificialItalic() const { return false; }
182
GetFontSelData() const183 const ImplFontSelectData& GetFontSelData() const { return maFontSelData; }
184
185 virtual void FetchFontMetric( ImplFontMetricData&, long& rFactor ) const = 0;
GetKernPairs(ImplKernPairData **) const186 virtual sal_uLong GetKernPairs( ImplKernPairData** ) const { return 0; }
GetGlyphKernValue(int,int) const187 virtual int GetGlyphKernValue( int, int ) const { return 0; }
188 virtual const ImplFontCharMap* GetImplFontCharMap() const = 0;
189 Point TransformPoint( const Point& ) const;
190
191 GlyphData& GetGlyphData( sal_GlyphId );
GetGlyphMetric(sal_GlyphId aGlyphId)192 const GlyphMetric& GetGlyphMetric( sal_GlyphId aGlyphId )
193 { return GetGlyphData( aGlyphId ).GetMetric(); }
194
195 virtual sal_GlyphId GetGlyphIndex( sal_UCS4 ) const = 0;
196 virtual bool GetGlyphOutline( sal_GlyphId, ::basegfx::B2DPolyPolygon& ) const = 0;
197 virtual bool GetAntialiasAdvice( void ) const = 0;
198 bool IsGlyphInvisible( sal_GlyphId );
199 virtual bool GetGlyphBitmap1( sal_GlyphId, RawBitmap& ) const = 0;
200 virtual bool GetGlyphBitmap8( sal_GlyphId, RawBitmap& ) const = 0;
201
202 void SetExtended( int nInfo, void* ppVoid );
GetExtInfo()203 int GetExtInfo() { return mnExtInfo; }
GetExtPointer()204 void* GetExtPointer() { return mpExtData; }
205
206 protected:
207 friend class GlyphCache;
208 friend class ServerFontLayout;
209 explicit ServerFont( const ImplFontSelectData& );
210 virtual ~ServerFont();
211
AddRef() const212 void AddRef() const { ++mnRefCount; }
GetRefCount() const213 long GetRefCount() const { return mnRefCount; }
214 long Release() const;
GetByteCount() const215 sal_uLong GetByteCount() const { return mnBytesUsed; }
216
217 virtual void InitGlyphData( sal_GlyphId, GlyphData& ) const = 0;
218 virtual void GarbageCollect( long );
219 void ReleaseFromGarbageCollect();
220
GetLayoutEngine()221 virtual ServerFontLayoutEngine* GetLayoutEngine() { return NULL; }
222
223 private:
224 typedef ::std::hash_map<sal_GlyphId,GlyphData> GlyphList;
225 mutable GlyphList maGlyphList;
226
227 const ImplFontSelectData maFontSelData;
228
229 // info for GlyphcachePeer
230 int mnExtInfo;
231 void* mpExtData;
232
233 // used by GlyphCache for cache LRU algorithm
234 mutable long mnRefCount;
235 mutable sal_uLong mnBytesUsed;
236
237 ServerFont* mpPrevGCFont;
238 ServerFont* mpNextGCFont;
239
240 protected:
241 // 16.16 fixed point values used for a rotated font
242 long mnCos;
243 long mnSin;
244 private:
245 int mnZWJ;
246 int mnZWNJ;
247 bool mbCollectedZW;
248 };
249
250 // =======================================================================
251
252 // a class for cache entries for physical font instances that are based on serverfonts
253 class VCL_PLUGIN_PUBLIC ImplServerFontEntry : public ImplFontEntry
254 {
255 private:
256 ServerFont* mpServerFont;
257 ImplFontOptions maFontOptions;
258 bool mbGotFontOptions;
259 bool mbValidFontOptions;
260
261 public:
262 ImplServerFontEntry( ImplFontSelectData& );
263 virtual ~ImplServerFontEntry();
SetServerFont(ServerFont * p)264 void SetServerFont( ServerFont* p) { mpServerFont = p; }
265 void HandleFontOptions();
266 };
267
268 // =======================================================================
269
270 class VCL_PLUGIN_PUBLIC ServerFontLayout : public GenericSalLayout
271 {
272 private:
273 ServerFont& mrServerFont;
274
275 // enforce proper copy semantic
276 SAL_DLLPRIVATE ServerFontLayout( const ServerFontLayout& );
277 SAL_DLLPRIVATE ServerFontLayout& operator=( const ServerFontLayout& );
278
279 public:
280 ServerFontLayout( ServerFont& );
281 virtual bool LayoutText( ImplLayoutArgs& );
282 virtual void AdjustLayout( ImplLayoutArgs& );
283 virtual void DrawText( SalGraphics& ) const;
GetServerFont() const284 ServerFont& GetServerFont() const { return mrServerFont; }
285 };
286
287 // =======================================================================
288
289 class ServerFontLayoutEngine
290 {
291 public:
~ServerFontLayoutEngine()292 virtual ~ServerFontLayoutEngine() {}
293 virtual bool operator()( ServerFontLayout&, ImplLayoutArgs& );
294 };
295
296 // =======================================================================
297
298 class GlyphCachePeer
299 {
300 protected:
GlyphCachePeer()301 GlyphCachePeer() : mnBytesUsed(0) {}
~GlyphCachePeer()302 virtual ~GlyphCachePeer() {}
303
304 public:
GetByteCount() const305 sal_Int32 GetByteCount() const { return mnBytesUsed; }
RemovingFont(ServerFont &)306 virtual void RemovingFont( ServerFont& ) {}
RemovingGlyph(ServerFont &,GlyphData &,sal_GlyphId)307 virtual void RemovingGlyph( ServerFont&, GlyphData&, sal_GlyphId ) {}
308
309 protected:
310 sal_Int32 mnBytesUsed;
311 };
312
313 // =======================================================================
314
315 class VCL_PLUGIN_PUBLIC RawBitmap
316 {
317 public:
318 RawBitmap();
319 ~RawBitmap();
320 bool Rotate( int nAngle );
321
322 public:
323 unsigned char* mpBits;
324 sal_uLong mnAllocated;
325
326 sal_uLong mnWidth;
327 sal_uLong mnHeight;
328
329 sal_uLong mnScanlineSize;
330 sal_uLong mnBitCount;
331
332 int mnXOffset;
333 int mnYOffset;
334 };
335
336 // =======================================================================
337
SetExtended(int nInfo,void * pVoid)338 inline void ServerFont::SetExtended( int nInfo, void* pVoid )
339 {
340 mnExtInfo = nInfo;
341 mpExtData = pVoid;
342 }
343
344 // =======================================================================
345
346 // ExtraKernInfo allows an on-demand query of extra kerning info #i29881#
347 // The kerning values have to be scaled to match the font size before use
348 class VCL_PLUGIN_PUBLIC ExtraKernInfo
349 {
350 public:
351 ExtraKernInfo( sal_IntPtr nFontId );
~ExtraKernInfo()352 virtual ~ExtraKernInfo() {}
353
354 bool HasKernPairs() const;
355 int GetUnscaledKernPairs( ImplKernPairData** ) const;
356 int GetUnscaledKernValue( sal_Unicode cLeft, sal_Unicode cRight ) const;
357
358 protected:
359 mutable bool mbInitialized;
360 virtual void Initialize() const = 0;
361
362 protected:
363 sal_IntPtr mnFontId;
364
365 // container to map a unicode pair to an unscaled kerning value
operator ()ExtraKernInfo::PairEqual366 struct PairEqual{ int operator()(const ImplKernPairData& rA, const ImplKernPairData& rB) const
367 { return (rA.mnChar1 == rB.mnChar1) && (rA.mnChar2 == rB.mnChar2); } };
operator ()ExtraKernInfo::PairHash368 struct PairHash{ int operator()(const ImplKernPairData& rA) const
369 { return (rA.mnChar1) * 256 ^ rA.mnChar2; } };
370 typedef std::hash_set< ImplKernPairData, PairHash, PairEqual > UnicodeKernPairs;
371 mutable UnicodeKernPairs maUnicodeKernPairs;
372 };
373
374 // =======================================================================
375
376 #endif // _SV_GLYPHCACHE_HXX
377