Back to index

lightning-sunbird  0.9+nobinonly
nsFontMetricsOS2.h
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Mozilla OS/2 libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * John Fairhurst, <john_fairhurst@iname.com>.
00018  * Portions created by the Initial Developer are Copyright (C) 1999
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either of the GNU General Public License Version 2 or later (the "GPL"),
00025  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK *****
00036  *
00037  * This Original Code has been modified by IBM Corporation.
00038  * Modifications made by IBM described herein are
00039  * Copyright (c) International Business Machines
00040  * Corporation, 2000
00041  *
00042  * Modifications to Mozilla code or documentation
00043  * identified per MPL Section 3.3
00044  *
00045  * Date           Modified by     Description of modification
00046  * 03/28/2000   IBM Corp.        Changes to make os2.h file similar to windows.h file
00047  */
00048 
00049 #ifndef _nsFontMetricsOS2_h
00050 #define _nsFontMetricsOS2_h
00051 
00052 #include "nsGfxDefs.h"
00053 
00054 #include "plhash.h"
00055 #include "nsIFontMetrics.h"
00056 #include "nsIFontEnumerator.h"
00057 #include "nsFont.h"
00058 #include "nsString.h"
00059 #include "nsUnitConversion.h"
00060 #include "nsIDeviceContext.h"
00061 #include "nsCRT.h"
00062 #include "nsDeviceContextOS2.h"
00063 #include "nsCOMPtr.h"
00064 #include "nsVoidArray.h"
00065 #include "nsICharRepresentable.h"
00066 #include "nsUnicharUtils.h"
00067 #include "nsDrawingSurfaceOS2.h"
00068 #include "nsTHashtable.h"
00069 #include "nsHashKeys.h"
00070 
00071 #ifndef FM_DEFN_LATIN1
00072 #define FM_DEFN_LATIN1          0x0010   /* Base latin character set     */
00073 #define FM_DEFN_PC              0x0020   /* PC characters                */
00074 #define FM_DEFN_LATIN2          0x0040   /* Extended latin character set */
00075 #define FM_DEFN_CYRILLIC        0x0080   /* Cyrillic character set       */
00076 #define FM_DEFN_HEBREW          0x0100   /* Base Hebrew characters       */
00077 #define FM_DEFN_GREEK           0x0200   /* Base Greek characters        */
00078 #define FM_DEFN_ARABIC          0x0400   /* Base Arabic characters       */
00079 #define FM_DEFN_UGLEXT          0x0800   /* Additional UGL chars         */
00080 #define FM_DEFN_KANA            0x1000   /* Katakana and hiragana chars  */
00081 #define FM_DEFN_THAI            0x2000   /* Thai characters              */
00082 
00083 #define FM_DEFN_UGL383          0x0070   /* Chars in OS/2 2.1            */
00084 #define FM_DEFN_UGL504          0x00F0   /* Chars in OS/2 Warp 4         */
00085 #define FM_DEFN_UGL767          0x0FF0   /* Chars in ATM fonts           */
00086 #define FM_DEFN_UGL1105         0x3FF0   /* Chars in bitmap fonts        */
00087 #endif
00088 
00089 // Debug defines
00090 //#define DEBUG_FONT_SELECTION
00091 //#define DEBUG_FONT_STRUCT_ALLOCS
00092 
00093 #define USE_FREETYPE
00094 
00095 #ifdef USE_FREETYPE
00096   #define PERF_HASGLYPH_CHAR_MAP
00097   #define USE_EXPANDED_FREETYPE_FUNCS
00098 #endif
00099 
00100 struct nsMiniMetrics
00101 {
00102   char            szFacename[FACESIZE];
00103   USHORT          fsType;
00104   USHORT          fsDefn;
00105   USHORT          fsSelection;
00106   nsMiniMetrics*  mNext;
00107 };
00108 
00109 // GlobalFontEntry->mStr is an nsString which contains the family name of font.
00110 class GlobalFontEntry : public nsStringHashKey
00111 {
00112 public:
00113   GlobalFontEntry(KeyTypePointer aStr) : nsStringHashKey(aStr) { }
00114   GlobalFontEntry(const GlobalFontEntry& aToCopy)
00115       : nsStringHashKey(aToCopy) { }
00116   ~GlobalFontEntry()
00117   {
00118     nsMiniMetrics* metrics = mMetrics;
00119     while (metrics) {
00120       nsMiniMetrics* nextMetrics = metrics->mNext;
00121       if (metrics)
00122         delete metrics;
00123       metrics = nextMetrics;
00124     }
00125 #ifdef PERF_HASGLYPH_CHAR_MAP
00126     if (mHaveCheckedCharMap) {
00127       nsMemory::Free(mHaveCheckedCharMap);
00128       nsMemory::Free(mRepresentableCharMap);
00129     }
00130 #endif
00131   }
00132 
00133   // Override, since we want to compare font names as case insensitive
00134   PRBool KeyEquals(const KeyTypePointer aKey) const
00135   {
00136     return GetKeyPointer()->Equals(*aKey, nsCaseInsensitiveStringComparator());
00137   }
00138   static PLDHashNumber HashKey(const KeyTypePointer aKey)
00139   {
00140     nsAutoString low(*aKey);
00141     ToLowerCase(low);
00142     return HashString(low);
00143   }
00144 
00145   USHORT          mCodePage;
00146   nsMiniMetrics*  mMetrics;
00147 
00148 #ifdef PERF_HASGLYPH_CHAR_MAP
00149   PRUint32* mHaveCheckedCharMap;
00150   PRUint32* mRepresentableCharMap;
00151 #endif
00152 };
00153 
00154 // An nsFontHandle is actually a pointer to one of these.
00155 // It knows how to select itself into a ps.
00156 class nsFontOS2
00157 {
00158 public:
00159   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
00160 
00161   nsFontOS2(void);
00162   virtual ~nsFontOS2(void);
00163 
00164   inline void SelectIntoPS(HPS hps, long lcid);
00165   virtual PRBool HasGlyph(HPS aPS, PRUint32 aChar) { return PR_TRUE; };
00166   virtual PRInt32 GetWidth(HPS aPS, const char* aString, PRUint32 aLength);
00167   virtual PRInt32 GetWidth(HPS aPS, const PRUnichar* aString, PRUint32 aLength);
00168   virtual void DrawString(HPS aPS, nsDrawingSurfaceOS2* aSurface,
00169                           PRInt32 aX, PRInt32 aY,
00170                           const char* aString, PRUint32 aLength, INT* aDx0);
00171   virtual void DrawString(HPS aPS, nsDrawingSurfaceOS2* aSurface,
00172                           PRInt32 aX, PRInt32 aY,
00173                           const PRUnichar* aString, PRUint32 aLength);
00174 
00175   FATTRS    mFattrs;
00176   SIZEF     mCharbox;
00177   ULONG     mHashMe;
00178   nscoord   mMaxAscent;
00179   nscoord   mMaxDescent;
00180   int       mConvertCodePage;  /* XXX do we need this, or is it just a copy of mFattrs.usCodePage */
00181 #ifdef DEBUG_FONT_STRUCT_ALLOCS
00182   static unsigned long mRefCount;
00183 #endif
00184 
00185 #ifdef PERF_HASGLYPH_CHAR_MAP
00186   PRUint32* mHaveCheckedCharMap;
00187   PRUint32* mRepresentableCharMap;
00188 #endif
00189 };
00190 
00203 struct nsFontSwitch {
00204   // Simple wrapper on top of nsFontOS2 for the moment
00205   // Could hold other attributes of the font
00206   nsFontOS2* mFont;
00207 };
00208 
00209 typedef PRBool (*PR_CALLBACK nsFontSwitchCallback)
00210                (const nsFontSwitch* aFontSwitch,
00211                 const PRUnichar*    aSubstring,
00212                 PRUint32            aSubstringLength,
00213                 void*               aData);
00214 
00215 
00216 class nsFontMetricsOS2 : public nsIFontMetrics
00217 {
00218 public:
00219   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
00220   NS_DECL_ISUPPORTS
00221 
00222   nsFontMetricsOS2();
00223   virtual ~nsFontMetricsOS2();
00224 
00225   NS_IMETHOD Init(const nsFont& aFont, nsIAtom* aLangGroup,
00226                   nsIDeviceContext* aContext);
00227   NS_IMETHOD Destroy();
00228 
00229   NS_IMETHOD  GetXHeight(nscoord& aResult);
00230   NS_IMETHOD  GetSuperscriptOffset(nscoord& aResult);
00231   NS_IMETHOD  GetSubscriptOffset(nscoord& aResult);
00232   NS_IMETHOD  GetStrikeout(nscoord& aOffset, nscoord& aSize);
00233   NS_IMETHOD  GetUnderline(nscoord& aOffset, nscoord& aSize);
00234   NS_IMETHOD  GetHeight(nscoord& aHeight);
00235 #ifdef FONT_LEADING_APIS_V2
00236   NS_IMETHOD  GetInternalLeading(nscoord &aLeading);
00237   NS_IMETHOD  GetExternalLeading(nscoord &aLeading);
00238 #else
00239   NS_IMETHOD  GetLeading(nscoord &aLeading);
00240   NS_IMETHOD  GetNormalLineHeight(nscoord &aHeight);
00241 #endif //FONT_LEADING_APIS_V2
00242   NS_IMETHOD  GetEmHeight(nscoord &aHeight);
00243   NS_IMETHOD  GetEmAscent(nscoord &aAscent);
00244   NS_IMETHOD  GetEmDescent(nscoord &aDescent);
00245   NS_IMETHOD  GetMaxHeight(nscoord &aHeight);
00246   NS_IMETHOD  GetMaxAscent(nscoord &aAscent);
00247   NS_IMETHOD  GetMaxDescent(nscoord &aDescent);
00248   NS_IMETHOD  GetMaxAdvance(nscoord &aAdvance);
00249   NS_IMETHOD  GetLangGroup(nsIAtom** aLangGroup);
00250   NS_IMETHOD  GetFontHandle(nsFontHandle &aHandle);
00251   NS_IMETHOD  GetAveCharWidth(nscoord &aAveCharWidth);
00252   NS_IMETHOD  GetSpaceWidth(nscoord &aSpaceWidth);
00253   // No known string length limits on OS/2
00254   virtual PRInt32 GetMaxStringLength() { return PR_INT32_MAX; }
00255 
00256   virtual nsresult
00257   ResolveForwards(HPS                  aPS,
00258                   const PRUnichar*     aString,
00259                   PRUint32             aLength,
00260                   nsFontSwitchCallback aFunc, 
00261                   void*                aData);
00262 
00263   virtual nsresult
00264   ResolveBackwards(HPS                  aPS,
00265                    const PRUnichar*     aString,
00266                    PRUint32             aLength,
00267                    nsFontSwitchCallback aFunc, 
00268                    void*                aData);
00269 
00270   nsFontOS2*         FindFont(HPS aPS, PRUint32 aChar);
00271   nsFontOS2*         FindUserDefinedFont(HPS aPS, PRUint32 aChar);
00272   nsFontOS2*         FindLocalFont(HPS aPS, PRUint32 aChar);
00273   nsFontOS2*         FindGenericFont(HPS aPS, PRUint32 aChar);
00274   virtual nsFontOS2* FindPrefFont(HPS aPS, PRUint32 aChar);
00275   virtual nsFontOS2* FindGlobalFont(HPS aPS, PRUint32 aChar);
00276 #ifdef USE_FREETYPE
00277   virtual nsFontOS2* FindSubstituteFont(HPS aPS, PRUint32 aChar)
00278       { return nsnull; };
00279 #endif
00280 
00281   nsFontOS2*          LoadFont(HPS aPS, const nsAString& aName);
00282   nsFontOS2*          LoadGenericFont(HPS aPS, PRUint32 aChar, const nsAString& aName);
00283   nsFontOS2*          LoadUnicodeFont(HPS aPS, const nsAString& aName);
00284   static nsresult     InitializeGlobalFonts();
00285 
00286   static nsTHashtable<GlobalFontEntry>* gGlobalFonts;
00287   static PLHashTable*  gFamilyNames;
00288   static PRBool        gSubstituteVectorFonts;
00289 #ifdef USE_FREETYPE
00290   static PRBool        gUseFTFunctions;
00291 #endif
00292 
00293   nsCOMPtr<nsIAtom>   mLangGroup;
00294   nsStringArray       mFonts;
00295   PRInt32             mFontsIndex;
00296   nsVoidArray         mLoadedFonts;
00297   nsFontOS2*          mUnicodeFont;
00298   nsFontOS2*          mWesternFont;
00299 
00300   PRInt32             mGenericIndex;
00301   nsString            mGeneric;
00302   nsString            mUserDefined;
00303 
00304   PRBool              mTriedAllGenerics;
00305   PRBool              mTriedAllPref;
00306   PRBool              mIsUserDefined;
00307 
00308   int                 mConvertCodePage;
00309 
00310 protected:
00311   nsresult      RealizeFont(void);
00312   PRBool        GetVectorSubstitute(HPS aPS, const nsAString& aFacename, 
00313                                     nsAString& aAlias);
00314   void          FindUnicodeFont(HPS aPS);
00315   void          FindWesternFont();
00316   nsFontOS2*    SetFontHandle(HPS aPS, GlobalFontEntry* aEntry,
00317                               nsMiniMetrics* aMetrics, PRBool aDoFakeEffects);
00318   PLHashTable*  InitializeFamilyNames(void);
00319 
00320   nscoord  mSuperscriptYOffset;
00321   nscoord  mSubscriptYOffset;
00322   nscoord  mStrikeoutPosition;
00323   nscoord  mStrikeoutSize;
00324   nscoord  mUnderlinePosition;
00325   nscoord  mUnderlineSize;
00326   nscoord  mExternalLeading;
00327   nscoord  mInternalLeading;
00328   nscoord  mEmHeight;
00329   nscoord  mEmAscent;
00330   nscoord  mEmDescent;
00331   nscoord  mMaxHeight;
00332   nscoord  mMaxAscent;
00333   nscoord  mMaxDescent;
00334   nscoord  mMaxAdvance;
00335   nscoord  mSpaceWidth;
00336   nscoord  mXHeight;
00337   nscoord  mAveCharWidth;
00338 
00339   nsFontOS2          *mFontHandle;
00340   nsDeviceContextOS2 *mDeviceContext;
00341 
00342 #ifdef DEBUG_FONT_STRUCT_ALLOCS
00343   static unsigned long mRefCount;
00344 #endif
00345 };
00346 
00347 class nsFontEnumeratorOS2 : public nsIFontEnumerator
00348 {
00349 public:
00350   nsFontEnumeratorOS2();
00351   NS_DECL_ISUPPORTS
00352   NS_DECL_NSIFONTENUMERATOR
00353 
00354 protected:
00355 };
00356 
00357 #ifdef USE_FREETYPE
00358 typedef BOOL (APIENTRY * Ft2EnableFontEngine) (BOOL fEnable);
00359 
00360 class nsFontMetricsOS2FT : public nsFontMetricsOS2
00361 {
00362 public:
00363   virtual ~nsFontMetricsOS2FT();
00364 
00365   virtual nsresult
00366   ResolveForwards(HPS                  aPS,
00367                   const PRUnichar*     aString,
00368                   PRUint32             aLength,
00369                   nsFontSwitchCallback aFunc, 
00370                   void*                aData);
00371 
00372   virtual nsresult
00373   ResolveBackwards(HPS                  aPS,
00374                    const PRUnichar*     aString,
00375                    PRUint32             aLength,
00376                    nsFontSwitchCallback aFunc, 
00377                    void*                aData);
00378 
00379   virtual nsFontOS2* FindPrefFont(HPS aPS, PRUint32 aChar);
00380   virtual nsFontOS2* FindGlobalFont(HPS aPS, PRUint32 aChar);
00381   virtual nsFontOS2* FindSubstituteFont(HPS aPS, PRUint32 aChar);
00382 
00383   static Ft2EnableFontEngine pfnFt2EnableFontEngine;
00384 
00385   nsFontOS2* mSubstituteFont;
00386 
00387 protected:
00388   nsFontOS2* LocateFont(HPS aPS, PRUint32 aChar, PRInt32 & aCount);
00389 };
00390 
00391 typedef BOOL (APIENTRY * Ft2FontSupportsUnicodeChar1) (PSTR8 pName,
00392                                                        PFATTRS pfatAttrs,
00393                                                        BOOL isUnicode,
00394                                                        UniChar ch);
00395 #ifdef USE_EXPANDED_FREETYPE_FUNCS
00396 typedef USHORT       *LPWSTR;
00397 typedef BOOL (APIENTRY * Ft2QueryTextBoxW) (HPS hps, LONG lCount1, 
00398                                             LPWSTR pchString,LONG lCount2, 
00399                                             PPOINTL aptlPoints);
00400 typedef LONG (APIENTRY * Ft2CharStringPosAtW) (HPS hps, PPOINTL pptlStart, 
00401                                                PRECTL prclRect, ULONG flOptions,
00402                                                LONG lCount, LPWSTR pchString,
00403                                                PLONG alAdx, ULONG fuWin32Options);
00404 #endif /* use_expanded_freetype_funcs */
00405 
00406 
00407 class nsFontOS2FT : public nsFontOS2
00408 {
00409 public:
00410   nsFontOS2FT(void);
00411   virtual ~nsFontOS2FT(void);
00412 
00413   virtual PRBool HasGlyph(HPS aPS, PRUint32 aChar);
00414 
00415   using nsFontOS2::GetWidth;
00416   using nsFontOS2::DrawString;
00417   virtual PRInt32 GetWidth(HPS aPS, const PRUnichar* aString, PRUint32 aLength);
00418   virtual void DrawString(HPS aPS, nsDrawingSurfaceOS2* aSurface,
00419                          PRInt32 aX, PRInt32 aY,
00420                          const PRUnichar* aString, PRUint32 aLength);
00421 
00422   PRBool IsSymbolFont() { return mFattrs.usCodePage == 65400; };
00423 
00424   static Ft2FontSupportsUnicodeChar1 pfnFt2FontSupportsUnicodeChar1;
00425 #ifdef USE_EXPANDED_FREETYPE_FUNCS
00426   static Ft2QueryTextBoxW pfnFt2QueryTextBoxW;
00427   static Ft2CharStringPosAtW pfnFt2CharStringPosAtW;
00428 #endif /* use_expanded_freetype_funcs */
00429 #ifdef DEBUG_FONT_STRUCT_ALLOCS
00430   static unsigned long mRefCount;
00431 #endif
00432 };
00433 
00434 // A "substitute font" to deal with missing glyphs -- see bug 6585
00435 // We now use transliteration+fallback to the REPLACEMENT CHAR + 
00436 // HEX representation to handle this issue.
00437 class nsFontOS2Substitute : public nsFontOS2
00438 {
00439 public:
00440   nsFontOS2Substitute(nsFontOS2* aFont);
00441   virtual ~nsFontOS2Substitute(void);
00442 
00443   virtual PRBool HasGlyph(HPS aPS, PRUint32 ch)
00444     { return !IS_IN_BMP(ch) || IS_REPRESENTABLE(mRepresentableCharMap, ch); };
00445   virtual void SetRepresentable(PRUint32 ch)
00446     { if (IS_IN_BMP(ch)) SET_REPRESENTABLE(mRepresentableCharMap, ch); };
00447 
00448   using nsFontOS2::GetWidth;
00449   using nsFontOS2::DrawString;
00450   virtual PRInt32 GetWidth(HPS aPS, const PRUnichar* aString, PRUint32 aLength);
00451   virtual void DrawString(HPS aPS, nsDrawingSurfaceOS2* aSurface,
00452                           PRInt32 aX, PRInt32 aY,
00453                           const PRUnichar* aString, PRUint32 aLength);
00454 
00455 private:
00456   //We need to have a easily operatable charmap for substitute font
00457   PRUint32 mRepresentableCharMap[UCS2_MAP_LEN];
00458 };
00459 #endif /* use_freetype */
00460 
00461 #endif