[Libreoffice-commits] .: 4 commits - vcl/inc vcl/Library_vcl.mk vcl/Library_vclplug_svp.mk vcl/source vcl/unx
Caolán McNamara
caolan at kemper.freedesktop.org
Thu Aug 18 08:56:27 PDT 2011
vcl/Library_vcl.mk | 10
vcl/Library_vclplug_svp.mk | 4
vcl/inc/glyphcache.hxx | 386 ---
vcl/inc/graphite_serverfont.hxx | 2
vcl/inc/unx/glyphcache.hxx | 402 +++
vcl/source/gdi/outdev3.cxx | 8
vcl/source/glyphs/gcach_ftyp.cxx | 2585 -------------------------
vcl/source/glyphs/gcach_ftyp.hxx | 279 --
vcl/source/glyphs/gcach_layout.cxx | 669 ------
vcl/source/glyphs/gcach_rbmp.cxx | 277 --
vcl/source/glyphs/glyphcache.cxx | 554 -----
vcl/source/glyphs/graphite_serverfont.cxx | 164 -
vcl/unx/generic/gdi/gcach_xpeer.hxx | 2
vcl/unx/generic/gdi/pspgraphics.cxx | 4
vcl/unx/generic/gdi/salgdi3.cxx | 2
vcl/unx/generic/glyphs/gcach_ftyp.cxx | 2585 +++++++++++++++++++++++++
vcl/unx/generic/glyphs/gcach_ftyp.hxx | 275 ++
vcl/unx/generic/glyphs/gcach_layout.cxx | 669 ++++++
vcl/unx/generic/glyphs/gcach_rbmp.cxx | 277 ++
vcl/unx/generic/glyphs/glyphcache.cxx | 554 +++++
vcl/unx/generic/glyphs/graphite_serverfont.cxx | 154 +
vcl/unx/headless/svppspgraphics.cxx | 2
vcl/unx/headless/svptext.cxx | 2
23 files changed, 4932 insertions(+), 4934 deletions(-)
New commits:
commit 6e566bc451f3db8a0507fe42946706fcb5616918
Author: Caolán McNamara <caolanm at redhat.com>
Date: Thu Aug 18 14:43:32 2011 +0100
and so glyphcache.hxx is revealed to be unx only
diff --git a/vcl/inc/glyphcache.hxx b/vcl/inc/glyphcache.hxx
deleted file mode 100644
index a94ccd2..0000000
--- a/vcl/inc/glyphcache.hxx
+++ /dev/null
@@ -1,401 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef _SV_GLYPHCACHE_HXX
-#define _SV_GLYPHCACHE_HXX
-
-#include <vcl/dllapi.h>
-
-class GlyphCache;
-class GlyphMetric;
-class GlyphData;
-class ServerFont;
-class GlyphCachePeer;
-class ServerFontLayoutEngine;
-class ServerFontLayout;
-class ExtraKernInfo;
-struct ImplKernPairData;
-class ImplFontOptions;
-
-#include <tools/gen.hxx>
-#include <boost/unordered_map.hpp>
-#include <boost/unordered_set.hpp>
-#include <boost/shared_ptr.hpp>
-
-namespace basegfx { class B2DPolyPolygon; }
-
-class RawBitmap;
-
-#include <outfont.hxx>
-#include <impfont.hxx>
-
-class ServerFontLayout;
-#include <sallayout.hxx>
-
-#ifdef ENABLE_GRAPHITE
-class GraphiteFaceWrapper;
-#endif
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-namespace vcl
-{
- struct FontCapabilities;
-}
-
-// =======================================================================
-
-class VCL_PLUGIN_PUBLIC GlyphCache
-{
-public:
- explicit GlyphCache( GlyphCachePeer& );
- /*virtual*/ ~GlyphCache();
-
- static GlyphCache& GetInstance();
-
- void AddFontFile( const rtl::OString& rNormalizedName,
- int nFaceNum, sal_IntPtr nFontId, const ImplDevFontAttributes&,
- const ExtraKernInfo* = NULL );
- void AnnounceFonts( ImplDevFontList* ) const;
-
- ServerFont* CacheFont( const ImplFontSelectData& );
- void UncacheFont( ServerFont& );
- void InvalidateAllGlyphs();
-
-protected:
- GlyphCachePeer& mrPeer;
-
-private:
- friend class ServerFont;
- // used by ServerFont class only
- void AddedGlyph( ServerFont&, GlyphData& );
- void RemovingGlyph( ServerFont&, GlyphData&, int nGlyphIndex );
- void UsingGlyph( ServerFont&, GlyphData& );
- void GrowNotify();
-
-private:
- void GarbageCollect();
-
- // the GlyphCache's FontList matches a font request to a serverfont instance
- // the FontList key's mpFontData member is reinterpreted as integer font id
- struct IFSD_Equal{ bool operator()( const ImplFontSelectData&, const ImplFontSelectData& ) const; };
- struct IFSD_Hash{ size_t operator()( const ImplFontSelectData& ) const; };
- typedef ::boost::unordered_map<ImplFontSelectData,ServerFont*,IFSD_Hash,IFSD_Equal > FontList;
- FontList maFontList;
- sal_uLong mnMaxSize; // max overall cache size in bytes
- mutable sal_uLong mnBytesUsed;
- mutable long mnLruIndex;
- mutable int mnGlyphCount;
- ServerFont* mpCurrentGCFont;
-
- class FreetypeManager* mpFtManager;
-};
-
-// =======================================================================
-
-class GlyphMetric
-{
-public:
- Point GetOffset() const { return maOffset; }
- Point GetDelta() const { return maDelta; }
- Size GetSize() const { return maSize; }
- long GetCharWidth() const { return mnAdvanceWidth; }
-
-protected:
- friend class GlyphData;
- void SetOffset( int nX, int nY ) { maOffset = Point( nX, nY); }
- void SetDelta( int nX, int nY ) { maDelta = Point( nX, nY); }
- void SetSize( const Size& s ) { maSize = s; }
- void SetCharWidth( long nW ) { mnAdvanceWidth = nW; }
-
-private:
- long mnAdvanceWidth;
- Point maDelta;
- Point maOffset;
- Size maSize;
-};
-
-// -----------------------------------------------------------------------
-
-// the glyph specific data needed by a GlyphCachePeer is usually trivial,
-// not attaching it to the corresponding GlyphData would be overkill
-struct ExtGlyphData
-{
- int meInfo;
- void* mpData;
-
- ExtGlyphData() : meInfo(0), mpData(NULL) {}
-};
-
-// -----------------------------------------------------------------------
-
-class GlyphData
-{
-public:
- const GlyphMetric& GetMetric() const { return maMetric; }
- Size GetSize() const { return maMetric.GetSize(); }
-
- void SetSize( const Size& s) { maMetric.SetSize( s ); }
- void SetOffset( int nX, int nY ) { maMetric.SetOffset( nX, nY ); }
- void SetDelta( int nX, int nY ) { maMetric.SetDelta( nX, nY ); }
- void SetCharWidth( long nW ) { maMetric.SetCharWidth( nW ); }
-
- void SetLruValue( int n ) const { mnLruValue = n; }
- long GetLruValue() const { return mnLruValue;}
-
- ExtGlyphData& ExtDataRef() { return maExtData; }
- const ExtGlyphData& ExtDataRef() const { return maExtData; }
-
-private:
- GlyphMetric maMetric;
- ExtGlyphData maExtData;
-
- // used by GlyphCache for cache LRU algorithm
- mutable long mnLruValue;
-};
-
-// =======================================================================
-
-class VCL_PLUGIN_PUBLIC ServerFont
-{
-public:
- virtual const ::rtl::OString* GetFontFileName() const = 0;
- virtual int GetFontFaceNumber() const = 0;
- virtual bool TestFont() const = 0;
- virtual void* GetFtFace() const = 0;
- virtual int GetLoadFlags() const = 0;
- virtual void SetFontOptions( boost::shared_ptr<ImplFontOptions> ) = 0;
- virtual boost::shared_ptr<ImplFontOptions> GetFontOptions() const = 0;
- virtual bool NeedsArtificialBold() const = 0;
- virtual bool NeedsArtificialItalic() const = 0;
-
- const ImplFontSelectData& GetFontSelData() const { return maFontSelData; }
-
- virtual void FetchFontMetric( ImplFontMetricData&, long& rFactor ) const = 0;
- virtual sal_uLong GetKernPairs( ImplKernPairData** ) const = 0;
- virtual const unsigned char* GetTable( const char* pName, sal_uLong* pLength ) = 0;
- virtual int GetEmUnits() const = 0;
- virtual const FT_Size_Metrics& GetMetricsFT() const = 0;
- virtual int GetGlyphKernValue( int, int ) const = 0;
- virtual const ImplFontCharMap* GetImplFontCharMap() const = 0;
- virtual bool GetFontCapabilities(vcl::FontCapabilities &) const = 0;
- Point TransformPoint( const Point& ) const;
-
- GlyphData& GetGlyphData( int nGlyphIndex );
- const GlyphMetric& GetGlyphMetric( int nGlyphIndex )
- { return GetGlyphData( nGlyphIndex ).GetMetric(); }
-#ifdef ENABLE_GRAPHITE
- virtual GraphiteFaceWrapper* GetGraphiteFace() const = 0;
-#endif
-
- virtual int GetGlyphIndex( sal_UCS4 ) const = 0;
- virtual int GetRawGlyphIndex( sal_UCS4 ) const = 0;
- virtual int FixupGlyphIndex( int nGlyphIndex, sal_UCS4 ) const = 0;
- virtual bool GetGlyphOutline( int nGlyphIndex, ::basegfx::B2DPolyPolygon& ) const = 0;
- virtual bool GetAntialiasAdvice( void ) const = 0;
- bool IsGlyphInvisible( int nGlyphIndex );
- virtual bool GetGlyphBitmap1( int nGlyphIndex, RawBitmap& ) const = 0;
- virtual bool GetGlyphBitmap8( int nGlyphIndex, RawBitmap& ) const = 0;
-
- void SetExtended( int nInfo, void* ppVoid );
- int GetExtInfo() { return mnExtInfo; }
- void* GetExtPointer() { return mpExtData; }
-
-protected:
- friend class GlyphCache;
- friend class ServerFontLayout;
- explicit ServerFont( const ImplFontSelectData& );
- virtual ~ServerFont();
-
- void AddRef() const { ++mnRefCount; }
- long GetRefCount() const { return mnRefCount; }
- long Release() const;
- sal_uLong GetByteCount() const { return mnBytesUsed; }
-
- virtual void InitGlyphData( int nGlyphIndex, GlyphData& ) const = 0;
- virtual void GarbageCollect( long );
- void ReleaseFromGarbageCollect();
-
- virtual ServerFontLayoutEngine* GetLayoutEngine() = 0;
-
-private:
- typedef ::boost::unordered_map<int,GlyphData> GlyphList;
- mutable GlyphList maGlyphList;
-
- const ImplFontSelectData maFontSelData;
-
- // info for GlyphcachePeer
- int mnExtInfo;
- void* mpExtData;
-
- // used by GlyphCache for cache LRU algorithm
- mutable long mnRefCount;
- mutable sal_uLong mnBytesUsed;
-
- ServerFont* mpPrevGCFont;
- ServerFont* mpNextGCFont;
-
-protected:
- // 16.16 fixed point values used for a rotated font
- long mnCos;
- long mnSin;
-private:
- int mnZWJ;
- int mnZWNJ;
- bool mbCollectedZW;
-};
-
-// =======================================================================
-
-// a class for cache entries for physical font instances that are based on serverfonts
-class VCL_PLUGIN_PUBLIC ImplServerFontEntry : public ImplFontEntry
-{
-private:
- ServerFont* mpServerFont;
- boost::shared_ptr<ImplFontOptions> mpFontOptions;
- bool mbGotFontOptions;
-
-public:
- ImplServerFontEntry( ImplFontSelectData& );
- virtual ~ImplServerFontEntry();
- void SetServerFont( ServerFont* p) { mpServerFont = p; }
- void HandleFontOptions();
-};
-
-// =======================================================================
-
-class VCL_PLUGIN_PUBLIC ServerFontLayout : public GenericSalLayout
-{
-private:
- ServerFont& mrServerFont;
-
- // enforce proper copy semantic
- SAL_DLLPRIVATE ServerFontLayout( const ServerFontLayout& );
- SAL_DLLPRIVATE ServerFontLayout& operator=( const ServerFontLayout& );
-
-public:
- ServerFontLayout( ServerFont& );
- virtual bool LayoutText( ImplLayoutArgs& );
- virtual void AdjustLayout( ImplLayoutArgs& );
- virtual void DrawText( SalGraphics& ) const;
- ServerFont& GetServerFont() const { return mrServerFont; }
-};
-
-// =======================================================================
-
-class ServerFontLayoutEngine
-{
-public:
- virtual ~ServerFontLayoutEngine() {}
- virtual bool operator()( ServerFontLayout&, ImplLayoutArgs& );
-};
-
-// =======================================================================
-
-class GlyphCachePeer
-{
-protected:
- GlyphCachePeer() : mnBytesUsed(0) {}
- virtual ~GlyphCachePeer() {}
-
-public:
- sal_Int32 GetByteCount() const { return mnBytesUsed; }
- virtual void RemovingFont( ServerFont& ) {}
- virtual void RemovingGlyph( ServerFont&, GlyphData&, int ) {}
-
-protected:
- sal_Int32 mnBytesUsed;
-};
-
-// =======================================================================
-
-class VCL_PLUGIN_PUBLIC RawBitmap
-{
-public:
- RawBitmap();
- ~RawBitmap();
- bool Rotate( int nAngle );
-
-public:
- unsigned char* mpBits;
- sal_uLong mnAllocated;
-
- sal_uLong mnWidth;
- sal_uLong mnHeight;
-
- sal_uLong mnScanlineSize;
- sal_uLong mnBitCount;
-
- int mnXOffset;
- int mnYOffset;
-};
-
-// =======================================================================
-
-inline void ServerFont::SetExtended( int nInfo, void* pVoid )
-{
- mnExtInfo = nInfo;
- mpExtData = pVoid;
-}
-
-// =======================================================================
-
-// ExtraKernInfo allows an on-demand query of extra kerning info #i29881#
-// The kerning values have to be scaled to match the font size before use
-class VCL_PLUGIN_PUBLIC ExtraKernInfo
-{
-public:
- ExtraKernInfo( sal_IntPtr nFontId );
- virtual ~ExtraKernInfo() {}
-
- bool HasKernPairs() const;
- int GetUnscaledKernPairs( ImplKernPairData** ) const;
- int GetUnscaledKernValue( sal_Unicode cLeft, sal_Unicode cRight ) const;
-
-protected:
- mutable bool mbInitialized;
- virtual void Initialize() const = 0;
-
-protected:
- sal_IntPtr mnFontId;
-
- // container to map a unicode pair to an unscaled kerning value
- struct PairEqual{ int operator()(const ImplKernPairData& rA, const ImplKernPairData& rB) const
- { return (rA.mnChar1 == rB.mnChar1) && (rA.mnChar2 == rB.mnChar2); } };
- struct PairHash{ int operator()(const ImplKernPairData& rA) const
- { return (rA.mnChar1) * 256 ^ rA.mnChar2; } };
- typedef boost::unordered_set< ImplKernPairData, PairHash, PairEqual > UnicodeKernPairs;
- mutable UnicodeKernPairs maUnicodeKernPairs;
-};
-
-// =======================================================================
-
-#endif // _SV_GLYPHCACHE_HXX
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
new file mode 100644
index 0000000..40c3eb5
--- /dev/null
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -0,0 +1,402 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SV_GLYPHCACHE_HXX
+#define _SV_GLYPHCACHE_HXX
+
+#include <vcl/dllapi.h>
+
+class GlyphCache;
+class GlyphMetric;
+class GlyphData;
+class ServerFont;
+class GlyphCachePeer;
+class ServerFontLayoutEngine;
+class ServerFontLayout;
+class ExtraKernInfo;
+struct ImplKernPairData;
+class ImplFontOptions;
+
+#include <tools/gen.hxx>
+#include <boost/unordered_map.hpp>
+#include <boost/unordered_set.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace basegfx { class B2DPolyPolygon; }
+
+class RawBitmap;
+
+#include <outfont.hxx>
+#include <impfont.hxx>
+
+class ServerFontLayout;
+#include <sallayout.hxx>
+
+#ifdef ENABLE_GRAPHITE
+class GraphiteFaceWrapper;
+#endif
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+namespace vcl
+{
+ struct FontCapabilities;
+}
+
+// =======================================================================
+
+class VCL_PLUGIN_PUBLIC GlyphCache
+{
+public:
+ explicit GlyphCache( GlyphCachePeer& );
+ /*virtual*/ ~GlyphCache();
+
+ static GlyphCache& GetInstance();
+
+ void AddFontFile( const rtl::OString& rNormalizedName,
+ int nFaceNum, sal_IntPtr nFontId, const ImplDevFontAttributes&,
+ const ExtraKernInfo* = NULL );
+ void AnnounceFonts( ImplDevFontList* ) const;
+
+ ServerFont* CacheFont( const ImplFontSelectData& );
+ void UncacheFont( ServerFont& );
+ void InvalidateAllGlyphs();
+
+protected:
+ GlyphCachePeer& mrPeer;
+
+private:
+ friend class ServerFont;
+ // used by ServerFont class only
+ void AddedGlyph( ServerFont&, GlyphData& );
+ void RemovingGlyph( ServerFont&, GlyphData&, int nGlyphIndex );
+ void UsingGlyph( ServerFont&, GlyphData& );
+ void GrowNotify();
+
+private:
+ void GarbageCollect();
+
+ // the GlyphCache's FontList matches a font request to a serverfont instance
+ // the FontList key's mpFontData member is reinterpreted as integer font id
+ struct IFSD_Equal{ bool operator()( const ImplFontSelectData&, const ImplFontSelectData& ) const; };
+ struct IFSD_Hash{ size_t operator()( const ImplFontSelectData& ) const; };
+ typedef ::boost::unordered_map<ImplFontSelectData,ServerFont*,IFSD_Hash,IFSD_Equal > FontList;
+ FontList maFontList;
+ sal_uLong mnMaxSize; // max overall cache size in bytes
+ mutable sal_uLong mnBytesUsed;
+ mutable long mnLruIndex;
+ mutable int mnGlyphCount;
+ ServerFont* mpCurrentGCFont;
+
+ class FreetypeManager* mpFtManager;
+};
+
+// =======================================================================
+
+class GlyphMetric
+{
+public:
+ Point GetOffset() const { return maOffset; }
+ Point GetDelta() const { return maDelta; }
+ Size GetSize() const { return maSize; }
+ long GetCharWidth() const { return mnAdvanceWidth; }
+
+protected:
+ friend class GlyphData;
+ void SetOffset( int nX, int nY ) { maOffset = Point( nX, nY); }
+ void SetDelta( int nX, int nY ) { maDelta = Point( nX, nY); }
+ void SetSize( const Size& s ) { maSize = s; }
+ void SetCharWidth( long nW ) { mnAdvanceWidth = nW; }
+
+private:
+ long mnAdvanceWidth;
+ Point maDelta;
+ Point maOffset;
+ Size maSize;
+};
+
+// -----------------------------------------------------------------------
+
+// the glyph specific data needed by a GlyphCachePeer is usually trivial,
+// not attaching it to the corresponding GlyphData would be overkill
+struct ExtGlyphData
+{
+ int meInfo;
+ void* mpData;
+
+ ExtGlyphData() : meInfo(0), mpData(NULL) {}
+};
+
+// -----------------------------------------------------------------------
+
+class GlyphData
+{
+public:
+ const GlyphMetric& GetMetric() const { return maMetric; }
+ Size GetSize() const { return maMetric.GetSize(); }
+
+ void SetSize( const Size& s) { maMetric.SetSize( s ); }
+ void SetOffset( int nX, int nY ) { maMetric.SetOffset( nX, nY ); }
+ void SetDelta( int nX, int nY ) { maMetric.SetDelta( nX, nY ); }
+ void SetCharWidth( long nW ) { maMetric.SetCharWidth( nW ); }
+
+ void SetLruValue( int n ) const { mnLruValue = n; }
+ long GetLruValue() const { return mnLruValue;}
+
+ ExtGlyphData& ExtDataRef() { return maExtData; }
+ const ExtGlyphData& ExtDataRef() const { return maExtData; }
+
+private:
+ GlyphMetric maMetric;
+ ExtGlyphData maExtData;
+
+ // used by GlyphCache for cache LRU algorithm
+ mutable long mnLruValue;
+};
+
+// =======================================================================
+
+class VCL_PLUGIN_PUBLIC ServerFont
+{
+public:
+ virtual const ::rtl::OString* GetFontFileName() const = 0;
+ virtual int GetFontFaceNumber() const = 0;
+ virtual bool TestFont() const = 0;
+ virtual void* GetFtFace() const = 0;
+ virtual int GetLoadFlags() const = 0;
+ virtual void SetFontOptions( boost::shared_ptr<ImplFontOptions> ) = 0;
+ virtual boost::shared_ptr<ImplFontOptions> GetFontOptions() const = 0;
+ virtual bool NeedsArtificialBold() const = 0;
+ virtual bool NeedsArtificialItalic() const = 0;
+
+ const ImplFontSelectData& GetFontSelData() const { return maFontSelData; }
+
+ virtual void FetchFontMetric( ImplFontMetricData&, long& rFactor ) const = 0;
+ virtual sal_uLong GetKernPairs( ImplKernPairData** ) const = 0;
+ virtual const unsigned char* GetTable( const char* pName, sal_uLong* pLength ) = 0;
+ virtual int GetEmUnits() const = 0;
+ virtual const FT_Size_Metrics& GetMetricsFT() const = 0;
+ virtual int GetGlyphKernValue( int, int ) const = 0;
+ virtual const ImplFontCharMap* GetImplFontCharMap() const = 0;
+ virtual bool GetFontCapabilities(vcl::FontCapabilities &) const = 0;
+ Point TransformPoint( const Point& ) const;
+
+ GlyphData& GetGlyphData( int nGlyphIndex );
+ const GlyphMetric& GetGlyphMetric( int nGlyphIndex )
+ { return GetGlyphData( nGlyphIndex ).GetMetric(); }
+#ifdef ENABLE_GRAPHITE
+ virtual GraphiteFaceWrapper* GetGraphiteFace() const = 0;
+#endif
+
+ virtual int GetGlyphIndex( sal_UCS4 ) const = 0;
+ virtual int GetRawGlyphIndex( sal_UCS4 ) const = 0;
+ virtual int FixupGlyphIndex( int nGlyphIndex, sal_UCS4 ) const = 0;
+ virtual bool GetGlyphOutline( int nGlyphIndex, ::basegfx::B2DPolyPolygon& ) const = 0;
+ virtual bool GetAntialiasAdvice( void ) const = 0;
+ bool IsGlyphInvisible( int nGlyphIndex );
+ virtual bool GetGlyphBitmap1( int nGlyphIndex, RawBitmap& ) const = 0;
+ virtual bool GetGlyphBitmap8( int nGlyphIndex, RawBitmap& ) const = 0;
+
+ void SetExtended( int nInfo, void* ppVoid );
+ int GetExtInfo() { return mnExtInfo; }
+ void* GetExtPointer() { return mpExtData; }
+
+protected:
+ friend class GlyphCache;
+ friend class ServerFontLayout;
+ explicit ServerFont( const ImplFontSelectData& );
+ virtual ~ServerFont();
+
+ void AddRef() const { ++mnRefCount; }
+ long GetRefCount() const { return mnRefCount; }
+ long Release() const;
+ sal_uLong GetByteCount() const { return mnBytesUsed; }
+
+ virtual void InitGlyphData( int nGlyphIndex, GlyphData& ) const = 0;
+ virtual void GarbageCollect( long );
+ void ReleaseFromGarbageCollect();
+
+ virtual ServerFontLayoutEngine* GetLayoutEngine() = 0;
+
+private:
+ typedef ::boost::unordered_map<int,GlyphData> GlyphList;
+ mutable GlyphList maGlyphList;
+
+ const ImplFontSelectData maFontSelData;
+
+ // info for GlyphcachePeer
+ int mnExtInfo;
+ void* mpExtData;
+
+ // used by GlyphCache for cache LRU algorithm
+ mutable long mnRefCount;
+ mutable sal_uLong mnBytesUsed;
+
+ ServerFont* mpPrevGCFont;
+ ServerFont* mpNextGCFont;
+
+protected:
+ // 16.16 fixed point values used for a rotated font
+ long mnCos;
+ long mnSin;
+private:
+ int mnZWJ;
+ int mnZWNJ;
+ bool mbCollectedZW;
+};
+
+// =======================================================================
+
+// a class for cache entries for physical font instances that are based on serverfonts
+class VCL_PLUGIN_PUBLIC ImplServerFontEntry : public ImplFontEntry
+{
+private:
+ ServerFont* mpServerFont;
+ boost::shared_ptr<ImplFontOptions> mpFontOptions;
+ bool mbGotFontOptions;
+
+public:
+ ImplServerFontEntry( ImplFontSelectData& );
+ virtual ~ImplServerFontEntry();
+ void SetServerFont( ServerFont* p) { mpServerFont = p; }
+ void HandleFontOptions();
+};
+
+// =======================================================================
+
+class VCL_PLUGIN_PUBLIC ServerFontLayout : public GenericSalLayout
+{
+private:
+ ServerFont& mrServerFont;
+
+ // enforce proper copy semantic
+ SAL_DLLPRIVATE ServerFontLayout( const ServerFontLayout& );
+ SAL_DLLPRIVATE ServerFontLayout& operator=( const ServerFontLayout& );
+
+public:
+ ServerFontLayout( ServerFont& );
+ virtual bool LayoutText( ImplLayoutArgs& );
+ virtual void AdjustLayout( ImplLayoutArgs& );
+ virtual void DrawText( SalGraphics& ) const;
+ ServerFont& GetServerFont() const { return mrServerFont; }
+};
+
+// =======================================================================
+
+class ServerFontLayoutEngine
+{
+public:
+ virtual ~ServerFontLayoutEngine() {}
+ virtual bool operator()( ServerFontLayout&, ImplLayoutArgs& );
+};
+
+// =======================================================================
+
+class GlyphCachePeer
+{
+protected:
+ GlyphCachePeer() : mnBytesUsed(0) {}
+ virtual ~GlyphCachePeer() {}
+
+public:
+ sal_Int32 GetByteCount() const { return mnBytesUsed; }
+ virtual void RemovingFont( ServerFont& ) {}
+ virtual void RemovingGlyph( ServerFont&, GlyphData&, int ) {}
+
+protected:
+ sal_Int32 mnBytesUsed;
+};
+
+// =======================================================================
+
+class VCL_PLUGIN_PUBLIC RawBitmap
+{
+public:
+ RawBitmap();
+ ~RawBitmap();
+ bool Rotate( int nAngle );
+
+public:
+ unsigned char* mpBits;
+ sal_uLong mnAllocated;
+
+ sal_uLong mnWidth;
+ sal_uLong mnHeight;
+
+ sal_uLong mnScanlineSize;
+ sal_uLong mnBitCount;
+
+ int mnXOffset;
+ int mnYOffset;
+};
+
+// =======================================================================
+
+inline void ServerFont::SetExtended( int nInfo, void* pVoid )
+{
+ mnExtInfo = nInfo;
+ mpExtData = pVoid;
+}
+
+// =======================================================================
+
+// ExtraKernInfo allows an on-demand query of extra kerning info #i29881#
+// The kerning values have to be scaled to match the font size before use
+class VCL_PLUGIN_PUBLIC ExtraKernInfo
+{
+public:
+ ExtraKernInfo( sal_IntPtr nFontId );
+ virtual ~ExtraKernInfo() {}
+
+ bool HasKernPairs() const;
+ int GetUnscaledKernPairs( ImplKernPairData** ) const;
+ int GetUnscaledKernValue( sal_Unicode cLeft, sal_Unicode cRight ) const;
+
+protected:
+ mutable bool mbInitialized;
+ virtual void Initialize() const = 0;
+
+protected:
+ sal_IntPtr mnFontId;
+
+ // container to map a unicode pair to an unscaled kerning value
+ struct PairEqual{ int operator()(const ImplKernPairData& rA, const ImplKernPairData& rB) const
+ { return (rA.mnChar1 == rB.mnChar1) && (rA.mnChar2 == rB.mnChar2); } };
+ struct PairHash{ int operator()(const ImplKernPairData& rA) const
+ { return (rA.mnChar1) * 256 ^ rA.mnChar2; } };
+ typedef boost::unordered_set< ImplKernPairData, PairHash, PairEqual > UnicodeKernPairs;
+ mutable UnicodeKernPairs maUnicodeKernPairs;
+};
+
+// =======================================================================
+
+#endif // _SV_GLYPHCACHE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/gcach_xpeer.hxx b/vcl/unx/generic/gdi/gcach_xpeer.hxx
index d2b4ec2..990cba3 100644
--- a/vcl/unx/generic/gdi/gcach_xpeer.hxx
+++ b/vcl/unx/generic/gdi/gcach_xpeer.hxx
@@ -33,7 +33,7 @@
#include <X11/extensions/Xrender.h>
#include <tools/postx.h>
-#include <glyphcache.hxx>
+#include "unx/glyphcache.hxx"
class SalDisplay;
struct MultiScreenGlyph;
diff --git a/vcl/unx/generic/gdi/pspgraphics.cxx b/vcl/unx/generic/gdi/pspgraphics.cxx
index a75ec2e..a3cae92 100644
--- a/vcl/unx/generic/gdi/pspgraphics.cxx
+++ b/vcl/unx/generic/gdi/pspgraphics.cxx
@@ -37,6 +37,7 @@
#include <sys/types.h>
#include "unx/pspgraphics.h"
+#include "unx/glyphcache.hxx"
#include "vcl/jobdata.hxx"
#include "vcl/printerinfomanager.hxx"
@@ -46,7 +47,6 @@
#include "printergfx.hxx"
#include "salbmp.hxx"
-#include "glyphcache.hxx"
#include "impfont.hxx"
#include "outfont.hxx"
#include "fontsubset.hxx"
diff --git a/vcl/unx/generic/glyphs/gcach_ftyp.hxx b/vcl/unx/generic/glyphs/gcach_ftyp.hxx
index e70b29d..808f386 100644
--- a/vcl/unx/generic/glyphs/gcach_ftyp.hxx
+++ b/vcl/unx/generic/glyphs/gcach_ftyp.hxx
@@ -29,19 +29,15 @@
#ifndef _SV_GCACHFTYP_HXX
#define _SV_GCACHFTYP_HXX
-#include <glyphcache.hxx>
-#include <rtl/textcvt.h>
+#include "unx/glyphcache.hxx"
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <rtl/textcvt.h>
class FreetypeServerFont;
#ifdef ENABLE_GRAPHITE
class GraphiteFaceWrapper;
#endif
-struct FT_GlyphRec_;
-
// -----------------------------------------------------------------------
// FtFontFile has the responsibility that a font file is only mapped once.
diff --git a/vcl/unx/generic/glyphs/gcach_rbmp.cxx b/vcl/unx/generic/glyphs/gcach_rbmp.cxx
index 71784f5..47321a3 100644
--- a/vcl/unx/generic/glyphs/gcach_rbmp.cxx
+++ b/vcl/unx/generic/glyphs/gcach_rbmp.cxx
@@ -29,7 +29,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
-#include <glyphcache.hxx>
+#include "unx/glyphcache.hxx"
#include <string.h>
//------------------------------------------------------------------------
diff --git a/vcl/unx/generic/glyphs/graphite_serverfont.cxx b/vcl/unx/generic/glyphs/graphite_serverfont.cxx
index a062b0f..d7928ea 100644
--- a/vcl/unx/generic/glyphs/graphite_serverfont.cxx
+++ b/vcl/unx/generic/glyphs/graphite_serverfont.cxx
@@ -40,13 +40,10 @@
#include <sallayout.hxx>
// Module
#include "gcach_ftyp.hxx"
-#include <glyphcache.hxx>
+#include "unx/glyphcache.hxx"
#include <graphite_features.hxx>
-//#include "graphite_textsrc.hxx"
#include <graphite_serverfont.hxx>
-#ifndef WNT
-
float freetypeServerFontAdvance(const void* appFontHandle, gr_uint16 glyphId)
{
ServerFont * pServerFont =
@@ -154,6 +151,4 @@ sal_GlyphId GraphiteLayoutImpl::getKashidaGlyph(int & width)
return nKashidaIndex;
}
-#endif
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/headless/svppspgraphics.cxx b/vcl/unx/headless/svppspgraphics.cxx
index 7b463a3..0e6832e 100644
--- a/vcl/unx/headless/svppspgraphics.cxx
+++ b/vcl/unx/headless/svppspgraphics.cxx
@@ -49,13 +49,13 @@
#include "salprn.hxx"
#include "salbmp.hxx"
-#include "glyphcache.hxx"
#include "impfont.hxx"
#include "outfont.hxx"
#include "fontsubset.hxx"
#include "printergfx.hxx"
#include "unx/headless/svppspgraphics.hxx"
#include "unx/headless/svpbmp.hxx"
+#include "unx/glyphcache.hxx"
#include "region.h"
using namespace psp;
diff --git a/vcl/unx/headless/svptext.cxx b/vcl/unx/headless/svptext.cxx
index 4d34246..41908cb 100644
--- a/vcl/unx/headless/svptext.cxx
+++ b/vcl/unx/headless/svptext.cxx
@@ -39,10 +39,10 @@
#endif
#include <outfont.hxx>
-#include <glyphcache.hxx>
#include <impfont.hxx>
#include <rtl/instance.hxx>
+#include "unx/glyphcache.hxx"
#include "unx/headless/svpgdi.hxx"
#include "unx/headless/svpbmp.hxx"
#include "unx/headless/svppspgraphics.hxx"
commit 670245be8d872e7d8bab60cef5348bf86c80b845
Author: Caolán McNamara <caolanm at redhat.com>
Date: Thu Aug 18 14:35:02 2011 +0100
move unix only stuff to unx
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 66d003c..ec44923 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -283,7 +283,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
# handle X11 platforms, which have additional files and possibly system graphite
ifeq ($(GUIBASE),unx)
$(eval $(call gb_Library_add_exception_objects,vcl,\
- vcl/source/glyphs/graphite_serverfont \
+ vcl/unx/generic/glyphs/graphite_serverfont \
))
else
$(eval $(call gb_Library_add_linked_libs,vcl,\
@@ -402,10 +402,10 @@ $(eval $(call gb_Library_add_defs,vcl,\
$(if $(ENABLE_CUPS),-DENABLE_CUPS) \
))
$(eval $(call gb_Library_add_exception_objects,vcl,\
- vcl/source/glyphs/gcach_ftyp \
- vcl/source/glyphs/gcach_layout \
- vcl/source/glyphs/gcach_rbmp \
- vcl/source/glyphs/glyphcache \
+ vcl/unx/generic/glyphs/gcach_ftyp \
+ vcl/unx/generic/glyphs/gcach_layout \
+ vcl/unx/generic/glyphs/gcach_rbmp \
+ vcl/unx/generic/glyphs/glyphcache \
vcl/unx/generic/fontmanager/fontcache \
vcl/unx/generic/fontmanager/fontconfig \
vcl/unx/generic/fontmanager/fontmanager \
diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx
deleted file mode 100644
index c38bc37..0000000
--- a/vcl/source/glyphs/gcach_ftyp.cxx
+++ /dev/null
@@ -1,2585 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_vcl.hxx"
-
-#ifdef WNT
-#include <svsys.h>
-#undef CreateFont
-#endif
-
-#include "gcach_ftyp.hxx"
-
-#include "vcl/svapp.hxx"
-#include <outfont.hxx>
-#include <impfont.hxx>
-#ifdef ENABLE_GRAPHITE
-#include <graphite2/Font.h>
-#include <graphite_layout.hxx>
-#endif
-
-#include "tools/poly.hxx"
-#include "basegfx/matrix/b2dhommatrix.hxx"
-#include <basegfx/matrix/b2dhommatrixtools.hxx>
-#include "basegfx/polygon/b2dpolypolygon.hxx"
-
-#include "osl/file.hxx"
-#include "osl/thread.hxx"
-
-#include "sft.hxx"
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-#include FT_OUTLINE_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_TRUETYPE_TAGS_H
-#include FT_TRUETYPE_IDS_H
-
-#ifndef FT_RENDER_MODE_MONO // happens in the MACOSX build
- #define FT_RENDER_MODE_MONO ft_render_mode_mono
-#endif
-#include "rtl/instance.hxx"
-
-#ifndef FREETYPE_PATCH
- // VERSION_MINOR in freetype.h is too coarse
- // if patch-level is not available we need to fine-tune the version ourselves
- #define FTVERSION 2005
-#else
- #define FTVERSION (1000*FREETYPE_MAJOR + 100*FREETYPE_MINOR + FREETYPE_PATCH)
-#endif
-#if FTVERSION >= 2200
-typedef const FT_Vector* FT_Vector_CPtr;
-#else // FTVERSION < 2200
-typedef FT_Vector* FT_Vector_CPtr;
-#endif
-
-#include <vector>
-
-// TODO: move file mapping stuff to OSL
-#if defined(UNX)
- // PORTERS: dlfcn is used for getting symbols from FT versions newer than baseline
- #include <dlfcn.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include "vcl/fontmanager.hxx"
-#elif defined(WNT)
- #include <io.h>
- #define strncasecmp strnicmp
-#endif
-
-typedef const unsigned char* CPU8;
-inline sal_uInt16 NEXT_U16( CPU8& p ) { p+=2; return (p[-2]<<8)|p[-1]; }
-inline sal_Int16 NEXT_S16( CPU8& p ) { return (sal_Int16)NEXT_U16(p); }
-inline sal_uInt32 NEXT_U32( CPU8& p ) { p+=4; return (p[-4]<<24)|(p[-3]<<16)|(p[-2]<<8)|p[-1]; }
-//inline sal_Int32 NEXT_S32( U8*& p ) { return (sal_Int32)NEXT_U32(p); }
-
-// -----------------------------------------------------------------------
-
-// the gamma table makes artificial bold look better for CJK glyphs
-static unsigned char aGammaTable[257];
-
-static void InitGammaTable()
-{
- static const int M_MAX = 255;
- static const int M_X = 128;
- static const int M_Y = 208;
-
- int x, a;
- for( x = 0; x < 256; x++)
- {
- if ( x <= M_X )
- a = ( x * M_Y + M_X / 2) / M_X;
- else
- a = M_Y + ( ( x - M_X ) * ( M_MAX - M_Y ) +
- ( M_MAX - M_X ) / 2 ) / ( M_MAX - M_X );
-
- aGammaTable[x] = (unsigned char)a;
- }
-}
-
-// -----------------------------------------------------------------------
-
-static FT_Library aLibFT = 0;
-
-// #110607# enable linking with old FT versions
-static int nFTVERSION = 0;
-static FT_Error (*pFTNewSize)(FT_Face,FT_Size*);
-static FT_Error (*pFTActivateSize)(FT_Size);
-static FT_Error (*pFTDoneSize)(FT_Size);
-FT_Error (*pFTEmbolden)(FT_GlyphSlot);
-FT_Error (*pFTOblique)(FT_GlyphSlot);
-static bool bEnableSizeFT = false;
-
-struct EqStr{ bool operator()(const char* a, const char* b) const { return !strcmp(a,b); } };
-struct HashStr { size_t operator()( const char* s ) const { return rtl_str_hashCode(s); } };
-typedef ::boost::unordered_map<const char*,boost::shared_ptr<FtFontFile>,HashStr, EqStr> FontFileList;
-namespace { struct vclFontFileList : public rtl::Static< FontFileList, vclFontFileList > {}; }
-
-// -----------------------------------------------------------------------
-
-// TODO: remove when the priorities are selected by UI
-// if (AH==0) => disable autohinting
-// if (AA==0) => disable antialiasing
-// if (EB==0) => disable embedded bitmaps
-// if (AA prio <= AH prio) => antialias + autohint
-// if (AH<AA) => do not autohint when antialiasing
-// if (EB<AH) => do not autohint for monochrome
-static int nDefaultPrioEmbedded = 2;
-static int nDefaultPrioAutoHint = 1;
-static int nDefaultPrioAntiAlias = 1;
-
-// =======================================================================
-// FreetypeManager
-// =======================================================================
-
-FtFontFile::FtFontFile( const ::rtl::OString& rNativeFileName )
-: maNativeFileName( rNativeFileName ),
- mpFileMap( NULL ),
- mnFileSize( 0 ),
- mnRefCount( 0 ),
- mnLangBoost( 0 )
-{
- // boost font preference if UI language is mentioned in filename
- int nPos = maNativeFileName.lastIndexOf( '_' );
- if( nPos == -1 || maNativeFileName[nPos+1] == '.' )
- mnLangBoost += 0x1000; // no langinfo => good
- else
- {
- static const char* pLangBoost = NULL;
- static bool bOnce = true;
- if( bOnce )
- {
- bOnce = false;
- LanguageType aLang = Application::GetSettings().GetUILanguage();
- switch( aLang )
- {
- case LANGUAGE_JAPANESE:
- pLangBoost = "jan";
- break;
- case LANGUAGE_CHINESE:
- case LANGUAGE_CHINESE_SIMPLIFIED:
- case LANGUAGE_CHINESE_SINGAPORE:
- pLangBoost = "zhs";
- break;
- case LANGUAGE_CHINESE_TRADITIONAL:
- case LANGUAGE_CHINESE_HONGKONG:
- case LANGUAGE_CHINESE_MACAU:
- pLangBoost = "zht";
- break;
- case LANGUAGE_KOREAN:
- case LANGUAGE_KOREAN_JOHAB:
- pLangBoost = "kor";
- break;
- }
- }
-
- if( pLangBoost && !strncasecmp( pLangBoost, &maNativeFileName.getStr()[nPos+1], 3 ) )
- mnLangBoost += 0x2000; // matching langinfo => better
- }
-}
-
-// -----------------------------------------------------------------------
-
-FtFontFile* FtFontFile::FindFontFile( const ::rtl::OString& rNativeFileName )
-{
- // font file already known? (e.g. for ttc, synthetic, aliased fonts)
- const char* pFileName = rNativeFileName.getStr();
- FontFileList &rFontFileList = vclFontFileList::get();
- FontFileList::const_iterator it = rFontFileList.find( pFileName );
- if( it != rFontFileList.end() )
- return it->second.get();
-
- // no => create new one
- FtFontFile* pFontFile = new FtFontFile( rNativeFileName );
- pFileName = pFontFile->maNativeFileName.getStr();
- rFontFileList[pFileName].reset(pFontFile);
- return pFontFile;
-}
-
-// -----------------------------------------------------------------------
-
-bool FtFontFile::Map()
-{
- if( mnRefCount++ <= 0 )
- {
- const char* pFileName = maNativeFileName.getStr();
-#if defined(UNX)
- int nFile = open( pFileName, O_RDONLY );
- if( nFile < 0 )
- return false;
-
- struct stat aStat;
- fstat( nFile, &aStat );
- mnFileSize = aStat.st_size;
- mpFileMap = (const unsigned char*)
- mmap( NULL, mnFileSize, PROT_READ, MAP_SHARED, nFile, 0 );
- if( mpFileMap == MAP_FAILED )
- mpFileMap = NULL;
- close( nFile );
-#elif defined(WNT)
- void* pFileDesc = ::CreateFile( pFileName, GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
- if( pFileDesc == INVALID_HANDLE_VALUE)
- return false;
-
- mnFileSize = ::GetFileSize( pFileDesc, NULL );
- HANDLE aHandle = ::CreateFileMapping( pFileDesc, NULL, PAGE_READONLY, 0, mnFileSize, "TTF" );
- mpFileMap = (const unsigned char*)::MapViewOfFile( aHandle, FILE_MAP_READ, 0, 0, mnFileSize );
- ::CloseHandle( pFileDesc );
-#else
- FILE* pFile = fopen( pFileName, "rb" );
- if( !pFile )
- return false;
-
- struct stat aStat;
- stat( pFileName, &aStat );
- mnFileSize = aStat.st_size;
- mpFileMap = new unsigned char[ mnFileSize ];
- if( mnFileSize != fread( mpFileMap, 1, mnFileSize, pFile ) )
- {
- delete[] mpFileMap;
- mpFileMap = NULL;
- }
- fclose( pFile );
-#endif
- }
-
- return (mpFileMap != NULL);
-}
-
-// -----------------------------------------------------------------------
-
-void FtFontFile::Unmap()
-{
- if( (--mnRefCount > 0) || (mpFileMap == NULL) )
- return;
-
-#if defined(UNX)
- munmap( (char*)mpFileMap, mnFileSize );
-#elif defined(WNT)
- UnmapViewOfFile( (LPCVOID)mpFileMap );
-#else
- delete[] mpFileMap;
-#endif
-
- mpFileMap = NULL;
-}
-
-#ifdef ENABLE_GRAPHITE
-// wrap FtFontInfo's table function
-const void * graphiteFontTable(const void* appFaceHandle, unsigned int name, size_t *len)
-{
- const FtFontInfo * pFontInfo = reinterpret_cast<const FtFontInfo*>(appFaceHandle);
- typedef union {
- char m_c[5];
- unsigned int m_id;
- } TableId;
- TableId tableId;
- tableId.m_id = name;
-#ifndef WORDS_BIGENDIAN
- TableId swapped;
- swapped.m_c[3] = tableId.m_c[0];
- swapped.m_c[2] = tableId.m_c[1];
- swapped.m_c[1] = tableId.m_c[2];
- swapped.m_c[0] = tableId.m_c[3];
- tableId.m_id = swapped.m_id;
-#endif
- tableId.m_c[4] = '\0';
- sal_uLong nLength = 0;
- const void * pTable = static_cast<const void*>(pFontInfo->GetTable(tableId.m_c, &nLength));
- if (len) *len = static_cast<size_t>(nLength);
- return pTable;
-}
-#endif
-
-// =======================================================================
-
-FtFontInfo::FtFontInfo( const ImplDevFontAttributes& rDevFontAttributes,
- const ::rtl::OString& rNativeFileName, int nFaceNum, sal_IntPtr nFontId, int nSynthetic,
- const ExtraKernInfo* pExtraKernInfo )
-:
- maFaceFT( NULL ),
- mpFontFile( FtFontFile::FindFontFile( rNativeFileName ) ),
- mnFaceNum( nFaceNum ),
- mnRefCount( 0 ),
- mnSynthetic( nSynthetic ),
-#ifdef ENABLE_GRAPHITE
- mbCheckedGraphite(false),
- mpGraphiteFace(NULL),
-#endif
- mnFontId( nFontId ),
- maDevFontAttributes( rDevFontAttributes ),
- mpFontCharMap( NULL ),
- mpChar2Glyph( NULL ),
- mpGlyph2Char( NULL ),
- mpExtraKernInfo( pExtraKernInfo )
-{
- // prefer font with low ID
- maDevFontAttributes.mnQuality += 10000 - nFontId;
- // prefer font with matching file names
- maDevFontAttributes.mnQuality += mpFontFile->GetLangBoost();
- // prefer font with more external info
- if( pExtraKernInfo )
- maDevFontAttributes.mnQuality += 100;
-}
-
-// -----------------------------------------------------------------------
-
-FtFontInfo::~FtFontInfo()
-{
- if( mpFontCharMap )
- mpFontCharMap->DeReference();
- delete mpExtraKernInfo;
- delete mpChar2Glyph;
- delete mpGlyph2Char;
-#ifdef ENABLE_GRAPHITE
- if (mpGraphiteFace)
- delete mpGraphiteFace;
-#endif
-}
-
-void FtFontInfo::InitHashes() const
-{
- // TODO: avoid pointers when empty stl::hash_* objects become cheap
- mpChar2Glyph = new Int2IntMap();
- mpGlyph2Char = new Int2IntMap();
-}
-
-// -----------------------------------------------------------------------
-
-FT_FaceRec_* FtFontInfo::GetFaceFT()
-{
- // get faceFT once/multiple depending on availability of SizeFT APIs
- if( (mnRefCount++ <= 0) || !bEnableSizeFT )
- {
- if( !mpFontFile->Map() )
- return NULL;
- FT_Error rc = FT_New_Memory_Face( aLibFT,
- (FT_Byte*)mpFontFile->GetBuffer(),
- mpFontFile->GetFileSize(), mnFaceNum, &maFaceFT );
- if( (rc != FT_Err_Ok) || (maFaceFT->num_glyphs <= 0) )
- maFaceFT = NULL;
- }
-
- return maFaceFT;
-}
-
-#ifdef ENABLE_GRAPHITE
-GraphiteFaceWrapper * FtFontInfo::GetGraphiteFace()
-{
- if (mbCheckedGraphite)
- return mpGraphiteFace;
- // test for graphite here so that it is cached most efficiently
- if (GetTable("Silf", 0))
- {
- int graphiteSegCacheSize = 10000;
- static const char* pGraphiteCacheStr = getenv( "SAL_GRAPHITE_CACHE_SIZE" );
- graphiteSegCacheSize = pGraphiteCacheStr ? (atoi(pGraphiteCacheStr)) : 0;
- gr_face * pGraphiteFace;
- if (graphiteSegCacheSize > 500)
- pGraphiteFace = gr_make_face_with_seg_cache(this, graphiteFontTable, graphiteSegCacheSize, gr_face_cacheCmap);
- else
- pGraphiteFace = gr_make_face(this, graphiteFontTable, gr_face_cacheCmap);
- if (pGraphiteFace)
- mpGraphiteFace = new GraphiteFaceWrapper(pGraphiteFace);
- }
- mbCheckedGraphite = true;
- return mpGraphiteFace;
-}
-#endif
-
-// -----------------------------------------------------------------------
-
-void FtFontInfo::ReleaseFaceFT( FT_FaceRec_* pFaceFT )
-{
- // release last/each depending on SizeFT availability
- if( (--mnRefCount <= 0) || !bEnableSizeFT )
- {
- FT_Done_Face( pFaceFT );
- maFaceFT = NULL;
- mpFontFile->Unmap();
- }
-}
-
-// -----------------------------------------------------------------------
-
-bool FtFontInfo::HasExtraKerning() const
-{
- if( !mpExtraKernInfo )
- return false;
- // TODO: how to enable the line below without getting #i29881# back?
- // on the other hand being to optimistic doesn't cause problems
- // return mpExtraKernInfo->HasKernPairs();
- return true;
-}
-
-// -----------------------------------------------------------------------
-
-int FtFontInfo::GetExtraKernPairs( ImplKernPairData** ppKernPairs ) const
-{
- if( !mpExtraKernInfo )
- return 0;
- return mpExtraKernInfo->GetUnscaledKernPairs( ppKernPairs );
-}
-
-// -----------------------------------------------------------------------
-
-int FtFontInfo::GetExtraGlyphKernValue( int nLeftGlyph, int nRightGlyph ) const
-{
- if( !mpExtraKernInfo )
- return 0;
- if( !mpGlyph2Char )
- return 0;
- sal_Unicode cLeftChar = (*mpGlyph2Char)[ nLeftGlyph ];
- sal_Unicode cRightChar = (*mpGlyph2Char)[ nRightGlyph ];
- return mpExtraKernInfo->GetUnscaledKernValue( cLeftChar, cRightChar );
-}
-
-// -----------------------------------------------------------------------
-
-static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);}
-static unsigned GetUShort( const unsigned char* p ){ return((p[0]<<8)+p[1]);}
-//static signed GetSShort( const unsigned char* p ){ return((short)((p[0]<<8)+p[1]));}
-
-// -----------------------------------------------------------------------
-
-const unsigned char* FtFontInfo::GetTable( const char* pTag, sal_uLong* pLength ) const
-{
- const unsigned char* pBuffer = mpFontFile->GetBuffer();
- int nFileSize = mpFontFile->GetFileSize();
- if( !pBuffer || nFileSize<1024 )
- return NULL;
-
- // we currently only handle TTF and TTC headers
- unsigned nFormat = GetUInt( pBuffer );
- const unsigned char* p = pBuffer + 12;
- if( nFormat == 0x74746366 ) // TTC_MAGIC
- p += GetUInt( p + 4 * mnFaceNum );
- else if( (nFormat!=0x00010000) && (nFormat!=0x74727565) ) // TTF_MAGIC and Apple TTF Magic
- return NULL;
-
- // walk table directory until match
- int nTables = GetUShort( p - 8 );
- if( nTables >= 64 ) // something fishy?
- return NULL;
- for( int i = 0; i < nTables; ++i, p+=16 )
- {
- if( p[0]==pTag[0] && p[1]==pTag[1] && p[2]==pTag[2] && p[3]==pTag[3] )
- {
- sal_uLong nLength = GetUInt( p + 12 );
- if( pLength != NULL )
- *pLength = nLength;
- const unsigned char* pTable = pBuffer + GetUInt( p + 8 );
- if( (pTable + nLength) <= (mpFontFile->GetBuffer() + nFileSize) )
- return pTable;
- }
- }
-
- return NULL;
-}
-
-// -----------------------------------------------------------------------
-
-void FtFontInfo::AnnounceFont( ImplDevFontList* pFontList )
-{
- ImplFTSFontData* pFD = new ImplFTSFontData( this, maDevFontAttributes );
- pFontList->Add( pFD );
-}
-
-// =======================================================================
-
-FreetypeManager::FreetypeManager()
-: mnMaxFontId( 0 ), mnNextFontId( 0x1000 )
-{
- /*FT_Error rcFT =*/ FT_Init_FreeType( &aLibFT );
-
-#ifdef RTLD_DEFAULT // true if a good dlfcn.h header was included
- // Get version of freetype library to enable workarounds.
- // Freetype <= 2.0.9 does not have FT_Library_Version().
- // Using dl_sym() instead of osl_getSymbol() because latter
- // isn't designed to work with oslModule=NULL
- void (*pFTLibraryVersion)(FT_Library library,
- FT_Int *amajor, FT_Int *aminor, FT_Int *apatch);
- pFTLibraryVersion = (void (*)(FT_Library library,
- FT_Int *amajor, FT_Int *aminor, FT_Int *apatch))(sal_IntPtr)dlsym( RTLD_DEFAULT, "FT_Library_Version" );
-
- pFTNewSize = (FT_Error(*)(FT_Face,FT_Size*))(sal_IntPtr)dlsym( RTLD_DEFAULT, "FT_New_Size" );
- pFTActivateSize = (FT_Error(*)(FT_Size))(sal_IntPtr)dlsym( RTLD_DEFAULT, "FT_Activate_Size" );
- pFTDoneSize = (FT_Error(*)(FT_Size))(sal_IntPtr)dlsym( RTLD_DEFAULT, "FT_Done_Size" );
- pFTEmbolden = (FT_Error(*)(FT_GlyphSlot))(sal_IntPtr)dlsym( RTLD_DEFAULT, "FT_GlyphSlot_Embolden" );
- pFTOblique = (FT_Error(*)(FT_GlyphSlot))(sal_IntPtr)dlsym( RTLD_DEFAULT, "FT_GlyphSlot_Oblique" );
-
- bEnableSizeFT = (pFTNewSize!=NULL) && (pFTActivateSize!=NULL) && (pFTDoneSize!=NULL);
-
- FT_Int nMajor = 0, nMinor = 0, nPatch = 0;
- if( pFTLibraryVersion )
- pFTLibraryVersion( aLibFT, &nMajor, &nMinor, &nPatch );
- nFTVERSION = nMajor * 1000 + nMinor * 100 + nPatch;
-
- // disable embedded bitmaps for Freetype-2.1.3 unless explicitly
- // requested by env var below because it crashes StarOffice on RH9
- // reason: double free in freetype's embedded bitmap handling
- if( nFTVERSION == 2103 )
- nDefaultPrioEmbedded = 0;
- // disable artificial emboldening with the Freetype API for older versions
- if( nFTVERSION < 2110 )
- pFTEmbolden = NULL;
-
-#else // RTLD_DEFAULT
- // assume systems where dlsym is not possible use supplied library
- nFTVERSION = FTVERSION;
-#endif
-
- // TODO: remove when the priorities are selected by UI
- char* pEnv;
- pEnv = ::getenv( "SAL_EMBEDDED_BITMAP_PRIORITY" );
- if( pEnv )
- nDefaultPrioEmbedded = pEnv[0] - '0';
- pEnv = ::getenv( "SAL_ANTIALIASED_TEXT_PRIORITY" );
- if( pEnv )
- nDefaultPrioAntiAlias = pEnv[0] - '0';
- pEnv = ::getenv( "SAL_AUTOHINTING_PRIORITY" );
- if( pEnv )
- nDefaultPrioAutoHint = pEnv[0] - '0';
-
- InitGammaTable();
- vclFontFileList::get();
-}
-
-// -----------------------------------------------------------------------
-
-void* FreetypeServerFont::GetFtFace() const
-{
- if( maSizeFT )
- pFTActivateSize( maSizeFT );
-
- return maFaceFT;
-}
-
-// -----------------------------------------------------------------------
-
-FreetypeManager::~FreetypeManager()
-{
- ClearFontList();
-// This crashes on Solaris 10
-// TODO: check which versions have this problem
-//
-// FT_Error rcFT = FT_Done_FreeType( aLibFT );
-}
-
-// -----------------------------------------------------------------------
-
-void FreetypeManager::AddFontFile( const rtl::OString& rNormalizedName,
- int nFaceNum, sal_IntPtr nFontId, const ImplDevFontAttributes& rDevFontAttr,
- const ExtraKernInfo* pExtraKernInfo )
-{
- if( !rNormalizedName.getLength() )
- return;
-
- if( maFontList.find( nFontId ) != maFontList.end() )
- return;
-
- FtFontInfo* pFontInfo = new FtFontInfo( rDevFontAttr,
- rNormalizedName, nFaceNum, nFontId, 0, pExtraKernInfo );
- maFontList[ nFontId ] = pFontInfo;
- if( mnMaxFontId < nFontId )
- mnMaxFontId = nFontId;
-}
-
-// -----------------------------------------------------------------------
-
-void FreetypeManager::AnnounceFonts( ImplDevFontList* pToAdd ) const
-{
- for( FontList::const_iterator it = maFontList.begin(); it != maFontList.end(); ++it )
- {
- FtFontInfo* pFtFontInfo = it->second;
- pFtFontInfo->AnnounceFont( pToAdd );
- }
-}
-
-// -----------------------------------------------------------------------
-
-void FreetypeManager::ClearFontList( )
-{
- for( FontList::iterator it = maFontList.begin(); it != maFontList.end(); ++it )
- {
- FtFontInfo* pFtFontInfo = it->second;
- delete pFtFontInfo;
- }
- maFontList.clear();
-}
-
-// -----------------------------------------------------------------------
-
-FreetypeServerFont* FreetypeManager::CreateFont( const ImplFontSelectData& rFSD )
-{
- FtFontInfo* pFontInfo = NULL;
-
- // find a FontInfo matching to the font id
- sal_IntPtr nFontId = reinterpret_cast<sal_IntPtr>( rFSD.mpFontData );
- FontList::iterator it = maFontList.find( nFontId );
- if( it != maFontList.end() )
- pFontInfo = it->second;
-
- if( !pFontInfo )
- return NULL;
-
- FreetypeServerFont* pNew = new FreetypeServerFont( rFSD, pFontInfo );
-
- return pNew;
-}
-
-// =======================================================================
-
-ImplFTSFontData::ImplFTSFontData( FtFontInfo* pFI, const ImplDevFontAttributes& rDFA )
-: ImplFontData( rDFA, IFTSFONT_MAGIC ),
- mpFtFontInfo( pFI )
-{
- mbDevice = false;
- mbOrientation = true;
-}
-
-// -----------------------------------------------------------------------
-
-ImplFontEntry* ImplFTSFontData::CreateFontInstance( ImplFontSelectData& rFSD ) const
-{
- ImplServerFontEntry* pEntry = new ImplServerFontEntry( rFSD );
- return pEntry;
-}
-
-// =======================================================================
-// FreetypeServerFont
-// =======================================================================
-
-FreetypeServerFont::FreetypeServerFont( const ImplFontSelectData& rFSD, FtFontInfo* pFI )
-: ServerFont( rFSD ),
- mnPrioEmbedded(nDefaultPrioEmbedded),
- mnPrioAntiAlias(nDefaultPrioAntiAlias),
- mnPrioAutoHint(nDefaultPrioAutoHint),
- mpFontInfo( pFI ),
- maFaceFT( NULL ),
- maSizeFT( NULL ),
- mbFaceOk( false ),
- maRecodeConverter( NULL ),
- mpLayoutEngine( NULL )
-{
- maFaceFT = pFI->GetFaceFT();
-
- if( !maFaceFT )
- return;
-
- // set the pixel size of the font instance
- mnWidth = rFSD.mnWidth;
- if( !mnWidth )
- mnWidth = rFSD.mnHeight;
- mfStretch = (double)mnWidth / rFSD.mnHeight;
- // sanity check (e.g. #i66394#, #i66244#, #66537#)
- if( (mnWidth < 0) || (mfStretch > +64.0) || (mfStretch < -64.0) )
- return;
-
- // perf: use maSizeFT if available
- if( bEnableSizeFT )
- {
- pFTNewSize( maFaceFT, &maSizeFT );
- pFTActivateSize( maSizeFT );
- }
- FT_Error rc = FT_Set_Pixel_Sizes( maFaceFT, mnWidth, rFSD.mnHeight );
- if( rc != FT_Err_Ok )
- return;
-
- // prepare for font encodings other than unicode or symbol
- FT_Encoding eEncoding = FT_ENCODING_UNICODE;
- if( mpFontInfo->IsSymbolFont() )
- {
-#if (FTVERSION < 2000)
- eEncoding = FT_ENCODING_NONE;
-#else
- if( FT_IS_SFNT( maFaceFT ) )
- eEncoding = ft_encoding_symbol;
- else
- eEncoding = FT_ENCODING_ADOBE_CUSTOM; // freetype wants this for PS symbol fonts
-#endif
- }
- rc = FT_Select_Charmap( maFaceFT, eEncoding );
- // no standard encoding applies => we need an encoding converter
- if( rc != FT_Err_Ok )
- {
- rtl_TextEncoding eRecodeFrom = RTL_TEXTENCODING_UNICODE;
- for( int i = maFaceFT->num_charmaps; --i >= 0; )
- {
- const FT_CharMap aCM = maFaceFT->charmaps[i];
- if( aCM->platform_id == TT_PLATFORM_MICROSOFT )
- {
- switch( aCM->encoding_id )
- {
- case TT_MS_ID_SJIS:
- eEncoding = FT_ENCODING_SJIS;
- eRecodeFrom = RTL_TEXTENCODING_SHIFT_JIS;
- break;
- case TT_MS_ID_GB2312:
- eEncoding = FT_ENCODING_GB2312;
- eRecodeFrom = RTL_TEXTENCODING_GB_2312;
- break;
- case TT_MS_ID_BIG_5:
- eEncoding = FT_ENCODING_BIG5;
- eRecodeFrom = RTL_TEXTENCODING_BIG5;
- break;
- case TT_MS_ID_WANSUNG:
- eEncoding = FT_ENCODING_WANSUNG;
- eRecodeFrom = RTL_TEXTENCODING_MS_949;
- break;
- case TT_MS_ID_JOHAB:
- eEncoding = FT_ENCODING_JOHAB;
- eRecodeFrom = RTL_TEXTENCODING_MS_1361;
- break;
- }
- }
- else if( aCM->platform_id == TT_PLATFORM_MACINTOSH )
- {
- switch( aCM->encoding_id )
- {
- case TT_MAC_ID_ROMAN:
- eEncoding = FT_ENCODING_APPLE_ROMAN;
- eRecodeFrom = RTL_TEXTENCODING_UNICODE; // TODO: use better match
- break;
- // TODO: add other encodings when Mac-only
- // non-unicode fonts show up
- }
- }
- else if( aCM->platform_id == TT_PLATFORM_ADOBE )
- {
- switch( aCM->encoding_id )
- {
-#ifdef TT_ADOBE_ID_LATIN1
- case TT_ADOBE_ID_LATIN1: // better unicode than nothing
- eEncoding = FT_ENCODING_ADOBE_LATIN_1;
- eRecodeFrom = RTL_TEXTENCODING_ISO_8859_1;
- break;
-#endif // TT_ADOBE_ID_LATIN1
- case TT_ADOBE_ID_STANDARD: // better unicode than nothing
- eEncoding = FT_ENCODING_ADOBE_STANDARD;
- eRecodeFrom = RTL_TEXTENCODING_UNICODE; // TODO: use better match
- break;
- }
- }
- }
-
- if( FT_Err_Ok != FT_Select_Charmap( maFaceFT, eEncoding ) )
- return;
-
- if( eRecodeFrom != RTL_TEXTENCODING_UNICODE )
- maRecodeConverter = rtl_createUnicodeToTextConverter( eRecodeFrom );
- }
-
- mbFaceOk = true;
-
- ApplyGSUB( rFSD );
-
- // TODO: query GASP table for load flags
- mnLoadFlags = FT_LOAD_DEFAULT;
-#if 1 // #i97326# cairo sometimes uses FT_Set_Transform() on our FT_FACE
- // we are not using FT_Set_Transform() yet, so just ignore it for now
- mnLoadFlags |= FT_LOAD_IGNORE_TRANSFORM;
-#endif
-
- mbArtItalic = (rFSD.meItalic != ITALIC_NONE && pFI->GetFontAttributes().GetSlant() == ITALIC_NONE);
- mbArtBold = (rFSD.meWeight > WEIGHT_MEDIUM && pFI->GetFontAttributes().GetWeight() <= WEIGHT_MEDIUM);
- mbUseGamma = false;
- if( mbArtBold )
- {
- //static const int TT_CODEPAGE_RANGE_874 = (1L << 16); // Thai
- //static const int TT_CODEPAGE_RANGE_932 = (1L << 17); // JIS/Japan
- //static const int TT_CODEPAGE_RANGE_936 = (1L << 18); // Chinese: Simplified
- //static const int TT_CODEPAGE_RANGE_949 = (1L << 19); // Korean Wansung
- //static const int TT_CODEPAGE_RANGE_950 = (1L << 20); // Chinese: Traditional
- //static const int TT_CODEPAGE_RANGE_1361 = (1L << 21); // Korean Johab
- static const int TT_CODEPAGE_RANGES1_CJKT = 0x3F0000; // all of the above
- const TT_OS2* pOs2 = (const TT_OS2*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_os2 );
- if ((pOs2) && (pOs2->ulCodePageRange1 & TT_CODEPAGE_RANGES1_CJKT )
- && rFSD.mnHeight < 20)
- mbUseGamma = true;
- }
-
- if( ((mnCos != 0) && (mnSin != 0)) || (mnPrioEmbedded <= 0) )
- mnLoadFlags |= FT_LOAD_NO_BITMAP;
-}
-
-void FreetypeServerFont::SetFontOptions( boost::shared_ptr<ImplFontOptions> pFontOptions)
-{
- mpFontOptions = pFontOptions;
-
- if (!mpFontOptions)
- return;
-
- FontAutoHint eHint = mpFontOptions->GetUseAutoHint();
- if( eHint == AUTOHINT_DONTKNOW )
- eHint = mbUseGamma ? AUTOHINT_TRUE : AUTOHINT_FALSE;
-
- if( eHint == AUTOHINT_TRUE )
- mnLoadFlags |= FT_LOAD_FORCE_AUTOHINT;
-
- if( (mnSin != 0) && (mnCos != 0) ) // hinting for 0/90/180/270 degrees only
- mnLoadFlags |= FT_LOAD_NO_HINTING;
- mnLoadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; //#88334#
-
- if( mpFontOptions->DontUseAntiAlias() )
- mnPrioAntiAlias = 0;
- if( mpFontOptions->DontUseEmbeddedBitmaps() )
- mnPrioEmbedded = 0;
- if( mpFontOptions->DontUseHinting() )
- mnPrioAutoHint = 0;
-
-#if (FTVERSION >= 2005) || defined(TT_CONFIG_OPTION_BYTECODE_INTERPRETER)
- if( mnPrioAutoHint <= 0 )
-#endif
- mnLoadFlags |= FT_LOAD_NO_HINTING;
-
-#if defined(FT_LOAD_TARGET_LIGHT) && defined(FT_LOAD_TARGET_NORMAL)
- if( !(mnLoadFlags & FT_LOAD_NO_HINTING) && (nFTVERSION >= 2103))
- {
- mnLoadFlags |= FT_LOAD_TARGET_NORMAL;
- switch( mpFontOptions->GetHintStyle() )
- {
- case HINT_NONE:
- mnLoadFlags |= FT_LOAD_NO_HINTING;
- break;
- case HINT_SLIGHT:
- mnLoadFlags |= FT_LOAD_TARGET_LIGHT;
- break;
- case HINT_MEDIUM:
- break;
- case HINT_FULL:
- default:
- break;
- }
- }
-#endif
-
- if( mnPrioEmbedded <= 0 )
- mnLoadFlags |= FT_LOAD_NO_BITMAP;
-}
-
-boost::shared_ptr<ImplFontOptions> FreetypeServerFont::GetFontOptions() const
-{
- return mpFontOptions;
-}
-
-// -----------------------------------------------------------------------
-
-bool FreetypeServerFont::TestFont() const
-{
- return mbFaceOk;
-}
-
-// -----------------------------------------------------------------------
-
-FreetypeServerFont::~FreetypeServerFont()
-{
- if( mpLayoutEngine )
- delete mpLayoutEngine;
-
- if( maRecodeConverter )
- rtl_destroyUnicodeToTextConverter( maRecodeConverter );
-
- if( maSizeFT )
- pFTDoneSize( maSizeFT );
-
- mpFontInfo->ReleaseFaceFT( maFaceFT );
-}
-
- // -----------------------------------------------------------------------
-
-int FreetypeServerFont::GetEmUnits() const
-{
- return maFaceFT->units_per_EM;
-}
-
-// -----------------------------------------------------------------------
-
-void FreetypeServerFont::FetchFontMetric( ImplFontMetricData& rTo, long& rFactor ) const
-{
- static_cast<ImplFontAttributes&>(rTo) = mpFontInfo->GetFontAttributes();
-
- rTo.mbScalableFont = true;
- rTo.mbDevice = true;
- rTo.mbKernableFont = (FT_HAS_KERNING( maFaceFT ) != 0) || mpFontInfo->HasExtraKerning();
- rTo.mnOrientation = GetFontSelData().mnOrientation;
-
- //Always consider [star]symbol as symbol fonts
- if (
- (rTo.GetFamilyName().EqualsAscii("OpenSymbol")) ||
- (rTo.GetFamilyName().EqualsAscii("StarSymbol"))
- )
- {
- rTo.mbSymbolFlag = true;
- }
-
- if( maSizeFT )
- pFTActivateSize( maSizeFT );
-
- rFactor = 0x100;
-
- rTo.mnWidth = mnWidth;
-
- const FT_Size_Metrics& rMetrics = maFaceFT->size->metrics;
- rTo.mnAscent = (+rMetrics.ascender + 32) >> 6;
-#if (FTVERSION < 2000)
- rTo.mnDescent = (+rMetrics.descender + 32) >> 6;
-#else
- rTo.mnDescent = (-rMetrics.descender + 32) >> 6;
-#endif
- rTo.mnIntLeading = ((rMetrics.height + 32) >> 6) - (rTo.mnAscent + rTo.mnDescent);
- rTo.mnSlant = 0;
-
- const TT_OS2* pOS2 = (const TT_OS2*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_os2 );
- const TT_HoriHeader* pHHEA = (const TT_HoriHeader*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_hhea );
- if( pOS2 && (pOS2->version != 0xFFFF) )
- {
- // map the panose info from the OS2 table to their VCL counterparts
- switch( pOS2->panose[0] )
- {
- case 1: rTo.meFamily = FAMILY_ROMAN; break;
- case 2: rTo.meFamily = FAMILY_SWISS; break;
- case 3: rTo.meFamily = FAMILY_MODERN; break;
- case 4: rTo.meFamily = FAMILY_SCRIPT; break;
- case 5: rTo.meFamily = FAMILY_DECORATIVE; break;
- // TODO: is it reasonable to override the attribute with DONTKNOW?
- case 0: // fall through
- default: rTo.meFamilyType = FAMILY_DONTKNOW; break;
- }
-
- switch( pOS2->panose[3] )
- {
- case 2: // fall through
- case 3: // fall through
- case 4: // fall through
- case 5: // fall through
- case 6: // fall through
- case 7: // fall through
- case 8: rTo.mePitch = PITCH_VARIABLE; break;
- case 9: rTo.mePitch = PITCH_FIXED; break;
- // TODO: is it reasonable to override the attribute with DONTKNOW?
- case 0: // fall through
- case 1: // fall through
- default: rTo.mePitch = PITCH_DONTKNOW; break;
- }
-
- // #108862# sanity check, some fonts treat descent as signed !!!
- int nDescent = pOS2->usWinDescent;
- if( nDescent > 5*maFaceFT->units_per_EM )
- nDescent = (short)pOS2->usWinDescent; // interpret it as signed!
-
- const double fScale = (double)GetFontSelData().mnHeight / maFaceFT->units_per_EM;
- if( pOS2->usWinAscent || pOS2->usWinDescent ) // #i30551#
- {
- rTo.mnAscent = (long)( +pOS2->usWinAscent * fScale + 0.5 );
- rTo.mnDescent = (long)( +nDescent * fScale + 0.5 );
- rTo.mnIntLeading = (long)( (+pOS2->usWinAscent + pOS2->usWinDescent - maFaceFT->units_per_EM) * fScale + 0.5 );
- }
- rTo.mnExtLeading = 0;
- if( (pHHEA != NULL) && (pOS2->usWinAscent || pOS2->usWinDescent) )
- {
- int nExtLeading = pHHEA->Line_Gap;
- nExtLeading -= (pOS2->usWinAscent + pOS2->usWinDescent);
- nExtLeading += (pHHEA->Ascender - pHHEA->Descender);
- if( nExtLeading > 0 )
- rTo.mnExtLeading = (long)(nExtLeading * fScale + 0.5);
- }
-
- // Check for CJK capabilities of the current font
- // #107888# workaround for Asian...
- // TODO: remove when ExtLeading fully implemented
- sal_Bool bCJKCapable = ((pOS2->ulUnicodeRange2 & 0x2DF00000) != 0);
-
- if ( bCJKCapable && (pOS2->usWinAscent || pOS2->usWinDescent) )
- {
- rTo.mnIntLeading += rTo.mnExtLeading;
-
- // #109280# The line height for Asian fonts is too small.
- // Therefore we add half of the external leading to the
- // ascent, the other half is added to the descent.
- const long nHalfTmpExtLeading = rTo.mnExtLeading / 2;
- const long nOtherHalfTmpExtLeading = rTo.mnExtLeading -
- nHalfTmpExtLeading;
-
- // #110641# external leading for Asian fonts.
- // The factor 0.3 has been verified during experiments.
- const long nCJKExtLeading = (long)(0.30 * (rTo.mnAscent + rTo.mnDescent));
-
- if ( nCJKExtLeading > rTo.mnExtLeading )
- rTo.mnExtLeading = nCJKExtLeading - rTo.mnExtLeading;
- else
- rTo.mnExtLeading = 0;
-
- rTo.mnAscent += nHalfTmpExtLeading;
- rTo.mnDescent += nOtherHalfTmpExtLeading;
- }
- }
-
- // initialize kashida width
- // TODO: what if there are different versions of this glyph available
- rTo.mnMinKashida = rTo.mnAscent / 4; // a reasonable default
- const int nKashidaGlyphId = GetRawGlyphIndex( 0x0640 );
- if( nKashidaGlyphId )
- {
- GlyphData aGlyphData;
- InitGlyphData( nKashidaGlyphId, aGlyphData );
- rTo.mnMinKashida = aGlyphData.GetMetric().GetCharWidth();
- }
-}
-
-// -----------------------------------------------------------------------
-
-static inline void SplitGlyphFlags( const FreetypeServerFont& rFont, int& nGlyphIndex, int& nGlyphFlags )
-{
- nGlyphFlags = nGlyphIndex & GF_FLAGMASK;
- nGlyphIndex &= GF_IDXMASK;
-
- if( nGlyphIndex & GF_ISCHAR )
- nGlyphIndex = rFont.GetRawGlyphIndex( nGlyphIndex );
-}
-
-// -----------------------------------------------------------------------
-
-int FreetypeServerFont::ApplyGlyphTransform( int nGlyphFlags,
- FT_Glyph pGlyphFT, bool bForBitmapProcessing ) const
-{
- int nAngle = GetFontSelData().mnOrientation;
- // shortcut most common case
- if( !nAngle && !nGlyphFlags )
- return nAngle;
-
- const FT_Size_Metrics& rMetrics = maFaceFT->size->metrics;
- FT_Vector aVector;
- FT_Matrix aMatrix;
-
- bool bStretched = false;
-
- switch( nGlyphFlags & GF_ROTMASK )
- {
- default: // straight
- aVector.x = 0;
- aVector.y = 0;
- aMatrix.xx = +mnCos;
- aMatrix.yy = +mnCos;
- aMatrix.xy = -mnSin;
- aMatrix.yx = +mnSin;
- break;
- case GF_ROTL: // left
- nAngle += 900;
- bStretched = (mfStretch != 1.0);
- aVector.x = (FT_Pos)(+rMetrics.descender * mfStretch);
- aVector.y = -rMetrics.ascender;
- aMatrix.xx = (FT_Pos)(-mnSin / mfStretch);
- aMatrix.yy = (FT_Pos)(-mnSin * mfStretch);
- aMatrix.xy = (FT_Pos)(-mnCos * mfStretch);
- aMatrix.yx = (FT_Pos)(+mnCos / mfStretch);
- break;
- case GF_ROTR: // right
- nAngle -= 900;
- bStretched = (mfStretch != 1.0);
- aVector.x = -maFaceFT->glyph->metrics.horiAdvance;
- aVector.x += (FT_Pos)(rMetrics.descender * mnSin/65536.0);
- aVector.y = (FT_Pos)(-rMetrics.descender * mfStretch * mnCos/65536.0);
- aMatrix.xx = (FT_Pos)(+mnSin / mfStretch);
- aMatrix.yy = (FT_Pos)(+mnSin * mfStretch);
- aMatrix.xy = (FT_Pos)(+mnCos * mfStretch);
- aMatrix.yx = (FT_Pos)(-mnCos / mfStretch);
- break;
- }
-
- while( nAngle < 0 )
- nAngle += 3600;
-
- if( pGlyphFT->format != FT_GLYPH_FORMAT_BITMAP )
- {
- FT_Glyph_Transform( pGlyphFT, NULL, &aVector );
-
- // orthogonal transforms are better handled by bitmap operations
- if( bStretched || (bForBitmapProcessing && (nAngle % 900) != 0) )
- {
- // workaround for compatibility with older FT versions
- if( nFTVERSION < 2102 )
- {
- FT_Fixed t = aMatrix.xy;
- aMatrix.xy = aMatrix.yx;
- aMatrix.yx = t;
- }
-
- // apply non-orthogonal or stretch transformations
- FT_Glyph_Transform( pGlyphFT, &aMatrix, NULL );
- nAngle = 0;
- }
- }
- else
- {
- // FT<=2005 ignores transforms for bitmaps, so do it manually
- FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<FT_BitmapGlyph>(pGlyphFT);
- pBmpGlyphFT->left += (aVector.x + 32) >> 6;
- pBmpGlyphFT->top += (aVector.y + 32) >> 6;
- }
-
- return nAngle;
-}
-
-// -----------------------------------------------------------------------
-
-int FreetypeServerFont::GetRawGlyphIndex( sal_UCS4 aChar ) const
-{
- if( mpFontInfo->IsSymbolFont() )
- {
- if( !FT_IS_SFNT( maFaceFT ) )
- {
- if( (aChar & 0xFF00) == 0xF000 )
- aChar &= 0xFF; // PS font symbol mapping
- else if( aChar > 0xFF )
- return 0;
- }
- }
-
- // if needed recode from unicode to font encoding
- if( maRecodeConverter )
- {
- sal_Char aTempArray[8];
- sal_Size nTempSize;
- sal_uInt32 nCvtInfo;
-
- // assume that modern UCS4 fonts have unicode CMAPs
- // => no encoding remapping to unicode is needed
- if( aChar > 0xFFFF )
- return 0;
-
- sal_Unicode aUCS2Char = static_cast<sal_Unicode>(aChar);
- rtl_UnicodeToTextContext aContext = rtl_createUnicodeToTextContext( maRecodeConverter );
- int nChars = rtl_convertUnicodeToText( maRecodeConverter, aContext,
- &aUCS2Char, 1, aTempArray, sizeof(aTempArray),
- RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK
- | RTL_UNICODETOTEXT_FLAGS_INVALID_QUESTIONMARK,
- &nCvtInfo, &nTempSize );
- rtl_destroyUnicodeToTextContext( maRecodeConverter, aContext );
-
- aChar = 0;
- for( int i = 0; i < nChars; ++i )
- aChar = aChar*256 + (aTempArray[i] & 0xFF);
- }
-
- // cache glyph indexes in font info to share between different sizes
- int nGlyphIndex = mpFontInfo->GetGlyphIndex( aChar );
- if( nGlyphIndex < 0 )
- {
- nGlyphIndex = FT_Get_Char_Index( maFaceFT, aChar );
- if( !nGlyphIndex)
- {
- // check if symbol aliasing helps
- if( (aChar <= 0x00FF) && mpFontInfo->IsSymbolFont() )
- nGlyphIndex = FT_Get_Char_Index( maFaceFT, aChar | 0xF000 );
- }
- mpFontInfo->CacheGlyphIndex( aChar, nGlyphIndex );
- }
-
- return nGlyphIndex;
-}
-
-// -----------------------------------------------------------------------
-
-int FreetypeServerFont::FixupGlyphIndex( int nGlyphIndex, sal_UCS4 aChar ) const
-{
- int nGlyphFlags = GF_NONE;
-
- // do glyph substitution if necessary
- // CJK vertical writing needs special treatment
- if( GetFontSelData().mbVertical )
- {
- // TODO: rethink when GSUB is used for non-vertical case
- GlyphSubstitution::const_iterator it = maGlyphSubstitution.find( nGlyphIndex );
- if( it == maGlyphSubstitution.end() )
- {
- int nTemp = GetVerticalChar( aChar );
- if( nTemp ) // is substitution possible
- nTemp = GetRawGlyphIndex( nTemp );
- if( nTemp ) // substitute manually if sensible
- nGlyphIndex = nTemp | (GF_GSUB | GF_ROTL);
- else
- nGlyphFlags |= GetVerticalFlags( aChar );
- }
- else
- {
- // for vertical GSUB also compensate for nOrientation=2700
- nGlyphIndex = (*it).second;
- nGlyphFlags |= GF_GSUB | GF_ROTL;
- }
- }
-
- if( nGlyphIndex != 0 )
- nGlyphIndex |= nGlyphFlags;
-
- return nGlyphIndex;
-}
-
-
-// -----------------------------------------------------------------------
-
-int FreetypeServerFont::GetGlyphIndex( sal_UCS4 aChar ) const
-{
- int nGlyphIndex = GetRawGlyphIndex( aChar );
- nGlyphIndex = FixupGlyphIndex( nGlyphIndex, aChar );
- return nGlyphIndex;
-}
-
-// -----------------------------------------------------------------------
-
-static int lcl_GetCharWidth( FT_FaceRec_* pFaceFT, double fStretch, int nGlyphFlags )
-{
- int nCharWidth = pFaceFT->glyph->metrics.horiAdvance;
-
- if( nGlyphFlags & GF_ROTMASK ) // for bVertical rotated glyphs
- {
- const FT_Size_Metrics& rMetrics = pFaceFT->size->metrics;
-#if (FTVERSION < 2000)
- nCharWidth = (int)((rMetrics.height - rMetrics.descender) * fStretch);
-#else
- nCharWidth = (int)((rMetrics.height + rMetrics.descender) * fStretch);
-#endif
- }
-
- return (nCharWidth + 32) >> 6;
-}
-
-// -----------------------------------------------------------------------
-
-void FreetypeServerFont::InitGlyphData( int nGlyphIndex, GlyphData& rGD ) const
-{
- if( maSizeFT )
- pFTActivateSize( maSizeFT );
-
- int nGlyphFlags;
- SplitGlyphFlags( *this, nGlyphIndex, nGlyphFlags );
-
- int nLoadFlags = mnLoadFlags;
-
-// if( mbArtItalic )
-// nLoadFlags |= FT_LOAD_NO_BITMAP;
-
- FT_Error rc = -1;
-#if (FTVERSION <= 2008)
- // #88364# freetype<=2005 prefers autohinting to embedded bitmaps
- // => first we have to try without hinting
- if( (nLoadFlags & (FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)) == 0 )
- {
- rc = FT_Load_Glyph( maFaceFT, nGlyphIndex, nLoadFlags|FT_LOAD_NO_HINTING );
- if( (rc==FT_Err_Ok) && (maFaceFT->glyph->format!=FT_GLYPH_FORMAT_BITMAP) )
- rc = -1; // mark as "loading embedded bitmap" was unsuccessful
- nLoadFlags |= FT_LOAD_NO_BITMAP;
- }
-
- if( rc != FT_Err_Ok )
-#endif
- rc = FT_Load_Glyph( maFaceFT, nGlyphIndex, nLoadFlags );
-
- if( rc != FT_Err_Ok )
- {
- // we get here e.g. when a PS font lacks the default glyph
- rGD.SetCharWidth( 0 );
- rGD.SetDelta( 0, 0 );
- rGD.SetOffset( 0, 0 );
- rGD.SetSize( Size( 0, 0 ) );
- return;
- }
-
- const bool bOriginallyZeroWidth = (maFaceFT->glyph->metrics.horiAdvance == 0);
- if( mbArtBold && pFTEmbolden )
- (*pFTEmbolden)( maFaceFT->glyph );
-
- const int nCharWidth = bOriginallyZeroWidth ? 0 : lcl_GetCharWidth( maFaceFT, mfStretch, nGlyphFlags );
- rGD.SetCharWidth( nCharWidth );
-
- FT_Glyph pGlyphFT;
- rc = FT_Get_Glyph( maFaceFT->glyph, &pGlyphFT );
-
- ApplyGlyphTransform( nGlyphFlags, pGlyphFT, false );
- if( mbArtBold && pFTEmbolden && (nFTVERSION < 2200) ) // #i71094# workaround staircase bug
- pGlyphFT->advance.y = 0;
- rGD.SetDelta( (pGlyphFT->advance.x + 0x8000) >> 16, -((pGlyphFT->advance.y + 0x8000) >> 16) );
-
- FT_BBox aBbox;
- FT_Glyph_Get_CBox( pGlyphFT, FT_GLYPH_BBOX_PIXELS, &aBbox );
- if( aBbox.yMin > aBbox.yMax ) // circumvent freetype bug
- {
- int t=aBbox.yMin; aBbox.yMin=aBbox.yMax, aBbox.yMax=t;
- }
-
- rGD.SetOffset( aBbox.xMin, -aBbox.yMax );
- rGD.SetSize( Size( (aBbox.xMax-aBbox.xMin+1), (aBbox.yMax-aBbox.yMin) ) );
-
- FT_Done_Glyph( pGlyphFT );
-}
-
-// -----------------------------------------------------------------------
-
-bool FreetypeServerFont::GetAntialiasAdvice( void ) const
-{
- if( GetFontSelData().mbNonAntialiased || (mnPrioAntiAlias<=0) )
- return false;
- bool bAdviseAA = true;
- // TODO: also use GASP info
- return bAdviseAA;
-}
-
-// -----------------------------------------------------------------------
-
-bool FreetypeServerFont::GetGlyphBitmap1( int nGlyphIndex, RawBitmap& rRawBitmap ) const
-{
- if( maSizeFT )
- pFTActivateSize( maSizeFT );
-
- int nGlyphFlags;
- SplitGlyphFlags( *this, nGlyphIndex, nGlyphFlags );
-
- FT_Int nLoadFlags = mnLoadFlags;
- // #i70930# force mono-hinting for monochrome text
- if( nFTVERSION >= 2110 ) //#i71947# unless it looks worse
- {
- nLoadFlags &= ~0xF0000;
- nLoadFlags |= FT_LOAD_TARGET_MONO;
- }
-
- if( mbArtItalic )
- nLoadFlags |= FT_LOAD_NO_BITMAP;
-
-#if (FTVERSION >= 2002)
- // for 0/90/180/270 degree fonts enable hinting even if not advisable
- // non-hinted and non-antialiased bitmaps just look too ugly
- if( (mnCos==0 || mnSin==0) && (mnPrioAutoHint > 0) )
- nLoadFlags &= ~FT_LOAD_NO_HINTING;
-#endif
-
- if( mnPrioEmbedded <= mnPrioAutoHint )
- nLoadFlags |= FT_LOAD_NO_BITMAP;
-
- FT_Error rc = -1;
-#if (FTVERSION <= 2008)
- // #88364# freetype<=2005 prefers autohinting to embedded bitmaps
- // => first we have to try without hinting
- if( (nLoadFlags & (FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)) == 0 )
- {
- rc = FT_Load_Glyph( maFaceFT, nGlyphIndex, nLoadFlags|FT_LOAD_NO_HINTING );
- if( (rc==FT_Err_Ok) && (maFaceFT->glyph->format != FT_GLYPH_FORMAT_BITMAP) )
- rc = -1; // mark as "loading embedded bitmap" was unsuccessful
- nLoadFlags |= FT_LOAD_NO_BITMAP;
- }
-
- if( rc != FT_Err_Ok )
-#endif
- rc = FT_Load_Glyph( maFaceFT, nGlyphIndex, nLoadFlags );
- if( rc != FT_Err_Ok )
- return false;
-
- if( mbArtBold && pFTEmbolden )
- (*pFTEmbolden)( maFaceFT->glyph );
-
- FT_Glyph pGlyphFT;
- rc = FT_Get_Glyph( maFaceFT->glyph, &pGlyphFT );
- if( rc != FT_Err_Ok )
- return false;
-
- int nAngle = ApplyGlyphTransform( nGlyphFlags, pGlyphFT, true );
-
- if( mbArtItalic )
- {
- FT_Matrix aMatrix;
- aMatrix.xx = aMatrix.yy = 0x10000L;
- if( nFTVERSION >= 2102 ) // Freetype 2.1.2 API swapped xy with yx
- aMatrix.xy = 0x6000L, aMatrix.yx = 0;
- else
- aMatrix.yx = 0x6000L, aMatrix.xy = 0;
- FT_Glyph_Transform( pGlyphFT, &aMatrix, NULL );
- }
-
- // Check for zero area bounding boxes as this crashes some versions of FT.
- // This also provides a handy short cut as much of the code following
- // becomes an expensive nop when a glyph covers no pixels.
- FT_BBox cbox;
- FT_Glyph_Get_CBox(pGlyphFT, ft_glyph_bbox_unscaled, &cbox);
-
- if( (cbox.xMax - cbox.xMin) == 0 || (cbox.yMax - cbox.yMin == 0) )
- {
- nAngle = 0;
- memset(&rRawBitmap, 0, sizeof rRawBitmap);
- FT_Done_Glyph( pGlyphFT );
- return true;
- }
-
- if( pGlyphFT->format != FT_GLYPH_FORMAT_BITMAP )
- {
- if( pGlyphFT->format == FT_GLYPH_FORMAT_OUTLINE )
- ((FT_OutlineGlyphRec*)pGlyphFT)->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
- // #i15743# freetype API 2.1.3 changed the FT_RENDER_MODE_MONO constant
- FT_Render_Mode nRenderMode = (FT_Render_Mode)((nFTVERSION<2103) ? 1 : FT_RENDER_MODE_MONO);
-
- rc = FT_Glyph_To_Bitmap( &pGlyphFT, nRenderMode, NULL, sal_True );
- if( rc != FT_Err_Ok )
- {
- FT_Done_Glyph( pGlyphFT );
- return false;
- }
- }
-
- const FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph>(pGlyphFT);
- // NOTE: autohinting in FT<=2.0.2 miscalculates the offsets below by +-1
- rRawBitmap.mnXOffset = +pBmpGlyphFT->left;
- rRawBitmap.mnYOffset = -pBmpGlyphFT->top;
-
- const FT_Bitmap& rBitmapFT = pBmpGlyphFT->bitmap;
- rRawBitmap.mnHeight = rBitmapFT.rows;
- rRawBitmap.mnBitCount = 1;
- if( mbArtBold && !pFTEmbolden )
- {
- rRawBitmap.mnWidth = rBitmapFT.width + 1;
- int nLineBytes = (rRawBitmap.mnWidth + 7) >> 3;
- rRawBitmap.mnScanlineSize = (nLineBytes > rBitmapFT.pitch) ? nLineBytes : rBitmapFT.pitch;
- }
- else
- {
- rRawBitmap.mnWidth = rBitmapFT.width;
- rRawBitmap.mnScanlineSize = rBitmapFT.pitch;
- }
-
- const sal_uLong nNeededSize = rRawBitmap.mnScanlineSize * rRawBitmap.mnHeight;
-
- if( rRawBitmap.mnAllocated < nNeededSize )
- {
- delete[] rRawBitmap.mpBits;
- rRawBitmap.mnAllocated = 2*nNeededSize;
- rRawBitmap.mpBits = new unsigned char[ rRawBitmap.mnAllocated ];
- }
-
- if( !mbArtBold || pFTEmbolden )
- {
- memcpy( rRawBitmap.mpBits, rBitmapFT.buffer, nNeededSize );
- }
- else
- {
- memset( rRawBitmap.mpBits, 0, nNeededSize );
- const unsigned char* pSrcLine = rBitmapFT.buffer;
- unsigned char* pDstLine = rRawBitmap.mpBits;
- for( int h = rRawBitmap.mnHeight; --h >= 0; )
- {
- memcpy( pDstLine, pSrcLine, rBitmapFT.pitch );
- pDstLine += rRawBitmap.mnScanlineSize;
- pSrcLine += rBitmapFT.pitch;
- }
-
- unsigned char* p = rRawBitmap.mpBits;
- for( sal_uLong y=0; y < rRawBitmap.mnHeight; y++ )
- {
- unsigned char nLastByte = 0;
- for( sal_uLong x=0; x < rRawBitmap.mnScanlineSize; x++ )
- {
- unsigned char nTmp = p[x] << 7;
- p[x] |= (p[x] >> 1) | nLastByte;
- nLastByte = nTmp;
- }
- p += rRawBitmap.mnScanlineSize;
- }
- }
-
- FT_Done_Glyph( pGlyphFT );
-
- // special case for 0/90/180/270 degree orientation
- switch( nAngle )
- {
- case -900:
- case +900:
- case +1800:
- case +2700:
- rRawBitmap.Rotate( nAngle );
- break;
- }
-
- return true;
-}
-
-// -----------------------------------------------------------------------
-
-bool FreetypeServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap ) const
-{
- if( maSizeFT )
- pFTActivateSize( maSizeFT );
-
- int nGlyphFlags;
- SplitGlyphFlags( *this, nGlyphIndex, nGlyphFlags );
-
- FT_Int nLoadFlags = mnLoadFlags;
-
- if( mbArtItalic )
- nLoadFlags |= FT_LOAD_NO_BITMAP;
-
-#if (FTVERSION <= 2004) && !defined(TT_CONFIG_OPTION_BYTECODE_INTERPRETER)
- // autohinting in FT<=2.0.4 makes antialiased glyphs look worse
- nLoadFlags |= FT_LOAD_NO_HINTING;
-#else
- if( (nGlyphFlags & GF_UNHINTED) || (mnPrioAutoHint < mnPrioAntiAlias) )
- nLoadFlags |= FT_LOAD_NO_HINTING;
-#endif
-
- if( mnPrioEmbedded <= mnPrioAntiAlias )
- nLoadFlags |= FT_LOAD_NO_BITMAP;
-
- FT_Error rc = -1;
-#if (FTVERSION <= 2008)
- // #88364# freetype<=2005 prefers autohinting to embedded bitmaps
- // => first we have to try without hinting
- if( (nLoadFlags & (FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)) == 0 )
- {
- rc = FT_Load_Glyph( maFaceFT, nGlyphIndex, nLoadFlags|FT_LOAD_NO_HINTING );
- if( (rc==FT_Err_Ok) && (maFaceFT->glyph->format != FT_GLYPH_FORMAT_BITMAP) )
- rc = -1; // mark as "loading embedded bitmap" was unsuccessful
- nLoadFlags |= FT_LOAD_NO_BITMAP;
- }
-
- if( rc != FT_Err_Ok )
-#endif
- rc = FT_Load_Glyph( maFaceFT, nGlyphIndex, nLoadFlags );
-
- if( rc != FT_Err_Ok )
- return false;
-
- if( mbArtBold && pFTEmbolden )
- (*pFTEmbolden)( maFaceFT->glyph );
-
- FT_Glyph pGlyphFT;
- rc = FT_Get_Glyph( maFaceFT->glyph, &pGlyphFT );
- if( rc != FT_Err_Ok )
- return false;
-
- int nAngle = ApplyGlyphTransform( nGlyphFlags, pGlyphFT, true );
-
- if( mbArtItalic )
- {
- FT_Matrix aMatrix;
- aMatrix.xx = aMatrix.yy = 0x10000L;
- if( nFTVERSION >= 2102 ) // Freetype 2.1.2 API swapped xy with yx
- aMatrix.xy = 0x6000L, aMatrix.yx = 0;
- else
- aMatrix.yx = 0x6000L, aMatrix.xy = 0;
- FT_Glyph_Transform( pGlyphFT, &aMatrix, NULL );
- }
-
- if( pGlyphFT->format == FT_GLYPH_FORMAT_OUTLINE )
- ((FT_OutlineGlyph)pGlyphFT)->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
-
- bool bEmbedded = (pGlyphFT->format == FT_GLYPH_FORMAT_BITMAP);
- if( !bEmbedded )
- {
- rc = FT_Glyph_To_Bitmap( &pGlyphFT, FT_RENDER_MODE_NORMAL, NULL, sal_True );
- if( rc != FT_Err_Ok )
- {
- FT_Done_Glyph( pGlyphFT );
- return false;
- }
- }
-
- const FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph>(pGlyphFT);
- rRawBitmap.mnXOffset = +pBmpGlyphFT->left;
- rRawBitmap.mnYOffset = -pBmpGlyphFT->top;
-
- const FT_Bitmap& rBitmapFT = pBmpGlyphFT->bitmap;
- rRawBitmap.mnHeight = rBitmapFT.rows;
- rRawBitmap.mnWidth = rBitmapFT.width;
- rRawBitmap.mnBitCount = 8;
- rRawBitmap.mnScanlineSize = bEmbedded ? rBitmapFT.width : rBitmapFT.pitch;
- if( mbArtBold && !pFTEmbolden )
- {
- ++rRawBitmap.mnWidth;
- ++rRawBitmap.mnScanlineSize;
- }
- rRawBitmap.mnScanlineSize = (rRawBitmap.mnScanlineSize + 3) & -4;
-
- const sal_uLong nNeededSize = rRawBitmap.mnScanlineSize * rRawBitmap.mnHeight;
- if( rRawBitmap.mnAllocated < nNeededSize )
- {
- delete[] rRawBitmap.mpBits;
- rRawBitmap.mnAllocated = 2*nNeededSize;
- rRawBitmap.mpBits = new unsigned char[ rRawBitmap.mnAllocated ];
- }
-
- const unsigned char* pSrc = rBitmapFT.buffer;
- unsigned char* pDest = rRawBitmap.mpBits;
- if( !bEmbedded )
- {
- for( int y = rRawBitmap.mnHeight, x; --y >= 0 ; )
- {
- for( x = 0; x < rBitmapFT.width; ++x )
- *(pDest++) = *(pSrc++);
- for(; x < int(rRawBitmap.mnScanlineSize); ++x )
- *(pDest++) = 0;
- }
- }
- else
- {
- for( int y = rRawBitmap.mnHeight, x; --y >= 0 ; )
- {
- unsigned char nSrc = 0;
- for( x = 0; x < rBitmapFT.width; ++x, nSrc+=nSrc )
- {
- if( (x & 7) == 0 )
- nSrc = *(pSrc++);
- *(pDest++) = (0x7F - nSrc) >> 8;
- }
- for(; x < int(rRawBitmap.mnScanlineSize); ++x )
- *(pDest++) = 0;
- }
- }
-
- if( mbArtBold && !pFTEmbolden )
- {
- // overlay with glyph image shifted by one left pixel
- unsigned char* p = rRawBitmap.mpBits;
- for( sal_uLong y=0; y < rRawBitmap.mnHeight; y++ )
- {
- unsigned char nLastByte = 0;
- for( sal_uLong x=0; x < rRawBitmap.mnWidth; x++ )
- {
- unsigned char nTmp = p[x];
- p[x] |= p[x] | nLastByte;
- nLastByte = nTmp;
- }
- p += rRawBitmap.mnScanlineSize;
- }
- }
-
- if( !bEmbedded && mbUseGamma )
- {
- unsigned char* p = rRawBitmap.mpBits;
- for( sal_uLong y=0; y < rRawBitmap.mnHeight; y++ )
- {
- for( sal_uLong x=0; x < rRawBitmap.mnWidth; x++ )
- {
- p[x] = aGammaTable[ p[x] ];
- }
- p += rRawBitmap.mnScanlineSize;
- }
- }
-
- FT_Done_Glyph( pGlyphFT );
-
- // special case for 0/90/180/270 degree orientation
- switch( nAngle )
- {
- case -900:
- case +900:
- case +1800:
- case +2700:
- rRawBitmap.Rotate( nAngle );
- break;
- }
-
- return true;
-}
-
-// -----------------------------------------------------------------------
-// determine unicode ranges in font
-// -----------------------------------------------------------------------
-
-const ImplFontCharMap* FreetypeServerFont::GetImplFontCharMap( void ) const
-{
- const ImplFontCharMap* pIFCMap = mpFontInfo->GetImplFontCharMap();
- return pIFCMap;
-}
-
-const ImplFontCharMap* FtFontInfo::GetImplFontCharMap( void )
-{
- // check if the charmap is already cached
- if( mpFontCharMap )
- return mpFontCharMap;
-
- // get the charmap and cache it
- CmapResult aCmapResult;
- bool bOK = GetFontCodeRanges( aCmapResult );
- if( bOK )
- mpFontCharMap = new ImplFontCharMap( aCmapResult );
- else
- mpFontCharMap = ImplFontCharMap::GetDefaultMap();
- mpFontCharMap->AddReference();
- return mpFontCharMap;
-}
-
-// TODO: merge into method GetFontCharMap()
-bool FtFontInfo::GetFontCodeRanges( CmapResult& rResult ) const
-{
- rResult.mbSymbolic = IsSymbolFont();
-
- // TODO: is the full CmapResult needed on platforms calling this?
- if( FT_IS_SFNT( maFaceFT ) )
- {
- sal_uLong nLength = 0;
- const unsigned char* pCmap = GetTable( "cmap", &nLength );
- if( pCmap && (nLength > 0) )
- if( ParseCMAP( pCmap, nLength, rResult ) )
- return true;
- }
-
- typedef std::vector<sal_uInt32> U32Vector;
- U32Vector aCodes;
-
- // FT's coverage is available since FT>=2.1.0 (OOo-baseline>=2.1.4 => ok)
- aCodes.reserve( 0x1000 );
- FT_UInt nGlyphIndex;
- for( sal_uInt32 cCode = FT_Get_First_Char( maFaceFT, &nGlyphIndex );; )
- {
- if( !nGlyphIndex )
- break;
- aCodes.push_back( cCode ); // first code inside range
- sal_uInt32 cNext = cCode;
- do cNext = FT_Get_Next_Char( maFaceFT, cCode, &nGlyphIndex ); while( cNext == ++cCode );
- aCodes.push_back( cCode ); // first code outside range
- cCode = cNext;
- }
-
- const int nCount = aCodes.size();
- if( !nCount) {
- if( !rResult.mbSymbolic )
- return false;
-
- // we usually get here for Type1 symbol fonts
- aCodes.push_back( 0xF020 );
- aCodes.push_back( 0xF100 );
- }
-
- sal_uInt32* pCodes = new sal_uInt32[ nCount ];
- for( int i = 0; i < nCount; ++i )
- pCodes[i] = aCodes[i];
- rResult.mpRangeCodes = pCodes;
- rResult.mnRangeCount = nCount / 2;
- return true;
-}
-
-bool FreetypeServerFont::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
-{
- bool bRet = false;
-
- sal_uLong nLength = 0;
- // load GSUB table
- const FT_Byte* pGSUB = mpFontInfo->GetTable("GSUB", &nLength);
- if (pGSUB)
- vcl::getTTScripts(rFontCapabilities.maGSUBScriptTags, pGSUB, nLength);
-
- // load OS/2 table
- const FT_Byte* pOS2 = mpFontInfo->GetTable("OS/2", &nLength);
- if (pOS2)
- {
- bRet = vcl::getTTCoverage(
- rFontCapabilities.maUnicodeRange,
- rFontCapabilities.maCodePageRange,
- pOS2, nLength);
- }
-
- return bRet;
-}
-
-// -----------------------------------------------------------------------
-// kerning stuff
-// -----------------------------------------------------------------------
-
-int FreetypeServerFont::GetGlyphKernValue( int nGlyphLeft, int nGlyphRight ) const
-{
- // if no kerning info is available from Freetype
- // then we may have to use extra info provided by e.g. psprint
- if( !FT_HAS_KERNING( maFaceFT ) || !FT_IS_SFNT( maFaceFT ) )
- {
- int nKernVal = mpFontInfo->GetExtraGlyphKernValue( nGlyphLeft, nGlyphRight );
- if( !nKernVal )
- return 0;
- // scale the kern value to match the font size
- const ImplFontSelectData& rFSD = GetFontSelData();
- nKernVal *= rFSD.mnWidth ? rFSD.mnWidth : rFSD.mnHeight;
- return (nKernVal + 500) / 1000;
- }
-
- // when font faces of different sizes share the same maFaceFT
- // then we have to make sure that it uses the correct maSizeFT
- if( maSizeFT )
- pFTActivateSize( maSizeFT );
-
- // use Freetype's kerning info
- FT_Vector aKernVal;
- FT_Error rcFT = FT_Get_Kerning( maFaceFT, nGlyphLeft, nGlyphRight,
- FT_KERNING_DEFAULT, &aKernVal );
- int nResult = (rcFT == FT_Err_Ok) ? (aKernVal.x + 32) >> 6 : 0;
- return nResult;
-}
-
-// -----------------------------------------------------------------------
-
-sal_uLong FreetypeServerFont::GetKernPairs( ImplKernPairData** ppKernPairs ) const
-{
- // if no kerning info is available in the font file
- *ppKernPairs = NULL;
- if( !FT_HAS_KERNING( maFaceFT ) || !FT_IS_SFNT( maFaceFT ) )
- {
- // then we have may have extra kerning info from e.g. psprint
- int nCount = mpFontInfo->GetExtraKernPairs( ppKernPairs );
- // scale the kern values to match the font size
- const ImplFontSelectData& rFSD = GetFontSelData();
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list