Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Protected Attributes
nsFontMetricsWin Class Reference

#include <nsFontMetricsWin.h>

Inheritance diagram for nsFontMetricsWin:
Inheritance graph
[legend]
Collaboration diagram for nsFontMetricsWin:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
NS_DECL_ISUPPORTS 
nsFontMetricsWin ()
virtual ~nsFontMetricsWin ()
NS_IMETHOD Init (const nsFont &aFont, nsIAtom *aLangGroup, nsIDeviceContext *aContext)
 Initialize the font metrics.
NS_IMETHOD Destroy ()
 Destroy this font metrics.
NS_IMETHOD GetXHeight (nscoord &aResult)
 Return the font's xheight property, scaled into app-units.
NS_IMETHOD GetSuperscriptOffset (nscoord &aResult)
 Return the font's superscript offset (the distance from the baseline to where a superscript's baseline should be placed).
NS_IMETHOD GetSubscriptOffset (nscoord &aResult)
 Return the font's subscript offset (the distance from the baseline to where a subscript's baseline should be placed).
NS_IMETHOD GetStrikeout (nscoord &aOffset, nscoord &aSize)
 Return the font's strikeout offset (the distance from the baseline to where a strikeout should be placed) and size Positive values are above the baseline, negative below.
NS_IMETHOD GetUnderline (nscoord &aOffset, nscoord &aSize)
 Return the font's underline offset (the distance from the baseline to where a underline should be placed) and size.
NS_IMETHOD GetHeight (nscoord &aHeight)
 Returns the height (in app units) of the font.
NS_IMETHOD GetLeading (nscoord &aLeading)
 Returns the amount of internal leading (in app units) for the font.
NS_IMETHOD GetNormalLineHeight (nscoord &aHeight)
 Returns the normal line height (em height + leading).
NS_IMETHOD GetEmHeight (nscoord &aHeight)
 Returns the height (in app units) of the Western font's em square.
NS_IMETHOD GetEmAscent (nscoord &aAscent)
 Returns, in app units, the ascent part of the Western font's em square.
NS_IMETHOD GetEmDescent (nscoord &aDescent)
 Returns, in app units, the descent part of the Western font's em square.
NS_IMETHOD GetMaxHeight (nscoord &aHeight)
 Returns the height (in app units) of the Western font's bounding box.
NS_IMETHOD GetMaxAscent (nscoord &aAscent)
 Returns, in app units, the maximum distance characters in this font extend above the base line.
NS_IMETHOD GetMaxDescent (nscoord &aDescent)
 Returns, in app units, the maximum distance characters in this font extend below the base line.
NS_IMETHOD GetMaxAdvance (nscoord &aAdvance)
 Returns, in app units, the maximum character advance for the font.
NS_IMETHOD GetLangGroup (nsIAtom **aLangGroup)
 Returns the language group associated with these metrics.
NS_IMETHOD GetFontHandle (nsFontHandle &aHandle)
 Returns the font handle associated with these metrics.
NS_IMETHOD GetAveCharWidth (nscoord &aAveCharWidth)
 Returns the average character width.
NS_IMETHOD GetSpaceWidth (nscoord &aSpaceWidth)
 Returns the often needed width of the space character.
virtual PRInt32 GetMaxStringLength ()
virtual nsresult ResolveForwards (HDC aDC, const PRUnichar *aString, PRUint32 aLength, nsFontSwitchCallback aFunc, void *aData)
virtual nsresult ResolveBackwards (HDC aDC, const PRUnichar *aString, PRUint32 aLength, nsFontSwitchCallback aFunc, void *aData)
nsFontWinFindFont (HDC aDC, PRUint32 aChar)
virtual nsFontWinFindUserDefinedFont (HDC aDC, PRUint32 aChar)
virtual nsFontWinFindLocalFont (HDC aDC, PRUint32 aChar)
virtual nsFontWinFindGenericFont (HDC aDC, PRUint32 aChar)
virtual nsFontWinFindPrefFont (HDC aDC, PRUint32 aChar)
virtual nsFontWinFindGlobalFont (HDC aDC, PRUint32 aChar)
virtual nsFontWinFindSubstituteFont (HDC aDC, PRUint32 aChar)
virtual nsFontWinLoadFont (HDC aDC, const nsString &aName, PRBool aNameQuirks=PR_FALSE)
virtual nsFontWinLoadGenericFont (HDC aDC, PRUint32 aChar, const nsString &aName)
virtual nsFontWinLoadGlobalFont (HDC aDC, nsGlobalFont *aGlobalFontItem)
virtual nsFontWinLoadSubstituteFont (HDC aDC, const nsString &aName)
virtual nsFontWinGetFontFor (HFONT aHFONT)
HFONT CreateFontHandle (HDC aDC, const nsString &aName, LOGFONT *aLogFont)
HFONT CreateFontHandle (HDC aDC, nsGlobalFont *aGlobalFont, LOGFONT *aLogFont)
HFONT CreateFontAdjustHandle (HDC aDC, LOGFONT *aLogFont)
void InitMetricsFor (HDC aDC, nsFontWin *aFontWin)
const nsFontFont ()
 Returns the font associated with these metrics.

Static Public Member Functions

static nsVoidArrayInitializeGlobalFonts (HDC aDC)
static void SetFontWeight (PRInt32 aWeight, PRUint16 *aWeightTable)
static PRBool IsFontWeightAvailable (PRInt32 aWeight, PRUint16 aWeightTable)
static PRUint16GetFontCCMAP (HDC aDC, const char *aShortName, PRBool aNameQuirks, eFontType &aFontType, PRUint8 &aCharset)
static PRUint16GetCCMAP (HDC aDC, const char *aShortName, PRBool *aNameQuirks, eFontType *aFontType, PRUint8 *aCharset)
static int SameAsPreviousMap (int aIndex)

Public Attributes

nsCOMPtr< nsIAtommLangGroup
nsStringArray mFonts
PRInt32 mFontsIndex
nsVoidArray mLoadedFonts
nsFontWinmSubstituteFont
PRInt32 mGenericIndex
nsString mGeneric
nsString mUserDefined
PRBool mTriedAllGenerics
PRBool mTriedAllPref
PRBool mIsUserDefined

Static Public Attributes

static PRUint16gEmptyCCMap = nsnull
static PLHashTablegFontMaps = nsnull
static PLHashTablegFamilyNames
static PLHashTablegFontWeights = nsnull
static nsVoidArraygGlobalFonts = nsnull

Protected Member Functions

PRUint16 LookForFontWeightTable (HDC aDc, const nsString &aName)
PRInt32 GetBolderWeight (PRInt32 aWeight, PRInt32 aDistance, PRUint16 aWeightTable)
PRInt32 GetLighterWeight (PRInt32 aWeight, PRInt32 aDistance, PRUint16 aWeightTable)
PRInt32 GetFontWeight (PRInt32 aWeight, PRUint16 aWeightTable)
PRInt32 GetClosestWeight (PRInt32 aWeight, PRUint16 aWeightTable)
PRUint16 GetFontWeightTable (HDC aDC, const nsString &aFontName)
nsFontWinLocateFont (HDC aDC, PRUint32 aChar, PRInt32 &aCount)
nsresult RealizeFont ()
 
See documentation in nsFontMetricsWin.h 05/28/99 dwc
void FillLogFont (LOGFONT *aLogFont, PRInt32 aWeight, PRBool aSizeOnly=PR_FALSE)

Protected Attributes

nsDeviceContextWinmDeviceContext
HFONT mFontHandle
nscoord mExternalLeading
nscoord mInternalLeading
nscoord mEmHeight
nscoord mEmAscent
nscoord mEmDescent
nscoord mMaxHeight
nscoord mMaxAscent
nscoord mMaxDescent
nscoord mMaxAdvance
nscoord mAveCharWidth
nscoord mXHeight
nscoord mSuperscriptOffset
nscoord mSubscriptOffset
nscoord mStrikeoutSize
nscoord mStrikeoutOffset
nscoord mUnderlineSize
nscoord mUnderlineOffset
nscoord mSpaceWidth
PRInt32 mMaxStringLength
nsFont mFont

Detailed Description

Definition at line 209 of file nsFontMetricsWin.h.


Constructor & Destructor Documentation

Definition at line 514 of file nsFontMetricsWin.cpp.

{
}

Definition at line 518 of file nsFontMetricsWin.cpp.

{
  mSubstituteFont = nsnull; // released below
  mFontHandle = nsnull; // released below

  // mLoadedFont[0] is gFontForIgnorable that will be deleted in FreeGlobal
  for (PRInt32 i = mLoadedFonts.Count()-1; i > 0; --i) {
    delete (nsFontWin*)mLoadedFonts[i];
  }
  mLoadedFonts.Clear();

  if (mDeviceContext) {
    // Notify our device context that owns us so that it can update its font cache
    mDeviceContext->FontMetricsDeleted(this);
    mDeviceContext = nsnull;
  }
}

Member Function Documentation

HFONT nsFontMetricsWin::CreateFontAdjustHandle ( HDC  aDC,
LOGFONT *  aLogFont 
)

Definition at line 2397 of file nsFontMetricsWin.cpp.

{
  // Adjust the aspect-value so that the x-height of the final font
  // is mFont.size * mFont.sizeAdjust

  PRInt32 dummy = 0;
  nscoord baseSize = mFont.size; 
  nscoord size72 = NSIntPointsToTwips(72); // large value improves accuracy
  mFont.size = size72;
  nscoord baselfHeight = aLogFont->lfHeight;
  FillLogFont(aLogFont, dummy, PR_TRUE);

  HFONT hfont = ::CreateFontIndirect(aLogFont);
  mFont.size = baseSize;
  aLogFont->lfHeight = baselfHeight;

  if (hfont) {
    HFONT oldFont = (HFONT)::SelectObject(aDC, (HGDIOBJ)hfont);
    char name[sizeof(aLogFont->lfFaceName)];
    if (::GetTextFace(aDC, sizeof(name), name) &&
        !strcmpi(name, aLogFont->lfFaceName)) {
      float dev2app;
      dev2app = mDeviceContext->DevUnitsToAppUnits();

      // Get the x-height
      nscoord xheight72;
      OUTLINETEXTMETRIC oMetrics;
      TEXTMETRIC& metrics = oMetrics.otmTextMetrics;
      if (0 < ::GetOutlineTextMetrics(aDC, sizeof(oMetrics), &oMetrics)) {
        xheight72 = NSToCoordRound((float)metrics.tmAscent * dev2app * 0.56f); // 50% of ascent, best guess for true type
        GLYPHMETRICS gm;
        DWORD len = gGlyphAgent.GetGlyphMetrics(aDC, PRUnichar('x'), 0, &gm);
        if (GDI_ERROR != len && gm.gmptGlyphOrigin.y > 0) {
          xheight72 = NSToCoordRound(gm.gmptGlyphOrigin.y * dev2app);
        }
      }
      else {
        ::GetTextMetrics(aDC, &metrics);
        xheight72 = NSToCoordRound((float)metrics.tmAscent * dev2app * 0.56f); // 56% of ascent, best guess for non-true type
      }
      ::SelectObject(aDC, (HGDIOBJ)oldFont);  

      // Apply the adjustment
      float adjust = mFont.sizeAdjust / (float(xheight72) / float(size72));
      mFont.size = NSToCoordRound(float(baseSize) * adjust);
      FillLogFont(aLogFont, dummy, PR_TRUE);

      hfont = ::CreateFontIndirect(aLogFont);

      // restore the original values before leaving
      mFont.size = baseSize;
      aLogFont->lfHeight = baselfHeight;
      return hfont;
    }
    ::SelectObject(aDC, (HGDIOBJ)oldFont);  
    ::DeleteObject((HFONT)hfont);  
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

HFONT nsFontMetricsWin::CreateFontHandle ( HDC  aDC,
const nsString aName,
LOGFONT *  aLogFont 
)

Definition at line 2458 of file nsFontMetricsWin.cpp.

{
  PRUint16 weightTable = LookForFontWeightTable(aDC, aName);
  PRInt32 weight = GetFontWeight(mFont.weight, weightTable);

  FillLogFont(aLogFont, weight);
 
  // The risk of losing characters not covered by the current codepage 
  // is reduced because LookupWinFontName invoked earlier has taken care 
  // of most cases. 
  WideCharToMultiByte(CP_ACP, 0, aName.get(), aName.Length() + 1,
                      aLogFont->lfFaceName, sizeof(aLogFont->lfFaceName),
                      nsnull, nsnull);

  if (mFont.sizeAdjust <= 0) {
    // Quick return for the common case where no adjustement is needed
    return ::CreateFontIndirect(aLogFont);
  }
  return CreateFontAdjustHandle(aDC, aLogFont);
}

Here is the call graph for this function:

Here is the caller graph for this function:

HFONT nsFontMetricsWin::CreateFontHandle ( HDC  aDC,
nsGlobalFont aGlobalFont,
LOGFONT *  aLogFont 
)

Definition at line 2480 of file nsFontMetricsWin.cpp.

{
  PRUint16 weightTable = LookForFontWeightTable(aDC, aGlobalFont->name);
  PRInt32 weight = GetFontWeight(mFont.weight, weightTable);

  FillLogFont(aLogFont, weight);
  aLogFont->lfCharSet = aGlobalFont->logFont.lfCharSet;
  aLogFont->lfPitchAndFamily = aGlobalFont->logFont.lfPitchAndFamily;
  strcpy(aLogFont->lfFaceName, aGlobalFont->logFont.lfFaceName);

  if (mFont.sizeAdjust <= 0) {
    // Quick return for the common case where no adjustement is needed
    return ::CreateFontIndirect(aLogFont);
  }
  return CreateFontAdjustHandle(aDC, aLogFont);
}

Here is the call graph for this function:

Destroy this font metrics.

This breaks the association between the font metrics and the device context.

Implements nsIFontMetrics.

Definition at line 594 of file nsFontMetricsWin.cpp.

{
  mDeviceContext = nsnull;
  return NS_OK;
}
void nsFontMetricsWin::FillLogFont ( LOGFONT *  aLogFont,
PRInt32  aWeight,
PRBool  aSizeOnly = PR_FALSE 
) [protected]

Definition at line 609 of file nsFontMetricsWin.cpp.

{
  float app2dev;
  app2dev = mDeviceContext->AppUnitsToDevUnits();
  logFont->lfHeight = - NSToIntRound(mFont.size * app2dev);

  if (logFont->lfHeight == 0) {
    logFont->lfHeight = -1;
  }

  // Quick return if we came here just to compute the font size
  if (aSizeOnly) return;

  // Fill in logFont structure
  logFont->lfWidth          = 0; 
  logFont->lfEscapement     = 0;
  logFont->lfOrientation    = 0;
  logFont->lfUnderline      =
    (mFont.decorations & NS_FONT_DECORATION_UNDERLINE)
    ? TRUE : FALSE;
  logFont->lfStrikeOut      =
    (mFont.decorations & NS_FONT_DECORATION_LINE_THROUGH)
    ? TRUE : FALSE;
#ifndef WINCE
  logFont->lfCharSet        = mIsUserDefined ? ANSI_CHARSET : DEFAULT_CHARSET;
  logFont->lfOutPrecision   = OUT_TT_PRECIS;
  logFont->lfClipPrecision  = CLIP_TURNOFF_FONTASSOCIATION;
#else
  logFont->lfCharSet        = DEFAULT_CHARSET;
  logFont->lfOutPrecision   = OUT_DEFAULT_PRECIS;
  logFont->lfClipPrecision  = CLIP_DEFAULT_PRECIS;
#endif
  logFont->lfQuality        = DEFAULT_QUALITY;
  logFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  logFont->lfWeight = aWeight;
  logFont->lfItalic = (mFont.style & (NS_FONT_STYLE_ITALIC | NS_FONT_STYLE_OBLIQUE))
    ? TRUE : FALSE;   // XXX need better oblique support

#ifdef NS_DEBUG
  // Make Purify happy
  memset(logFont->lfFaceName, 0, sizeof(logFont->lfFaceName));
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::FindFont ( HDC  aDC,
PRUint32  aChar 
)

Definition at line 3607 of file nsFontMetricsWin.cpp.

{
#ifdef DEBUG_emk
  LARGE_INTEGER start, end;
  QueryPerformanceFrequency(&freq);
  QueryPerformanceCounter(&start);
#endif
  // the first font should be for invisible ignorable characters
  if (mLoadedFonts.Count() < 1)
    mLoadedFonts.AppendElement(gFontForIgnorable);
  if (gFontForIgnorable->HasGlyph(aChar))
      return gFontForIgnorable;

  nsFontWin* font = FindUserDefinedFont(aDC, aChar);
  if (!font) {
    font = FindLocalFont(aDC, aChar);
    if (!font) {
      font = FindGenericFont(aDC, aChar);
      if (!font) {
        font = FindPrefFont(aDC, aChar);
        if (!font) {
#ifdef DEBUG_emk
          QueryPerformanceCounter(&prev);
#endif
          font = FindGlobalFont(aDC, aChar);
          if (!font) {
#ifdef DEBUG_emk
            QueryPerformanceCounter(&end);
            printf("%g sec.\n", (end.QuadPart - start.QuadPart) / (double)freq.QuadPart);
#endif
            font = FindSubstituteFont(aDC, aChar);
          }
        }
      }
    }
  }
  return font;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::FindGenericFont ( HDC  aDC,
PRUint32  aChar 
) [virtual]

Definition at line 3469 of file nsFontMetricsWin.cpp.

{
  if (mTriedAllGenerics) {
    // don't bother anymore because mLoadedFonts[] already has all our generic fonts
    return nsnull;
  }

  // This is a nifty hook that we will use to just iterate over
  // the list of names using the callback mechanism of nsFont...
  nsFont font("", 0, 0, 0, 0, 0);

  if (mLangGroup) {
    const char* langGroup;
    mLangGroup->GetUTF8String(&langGroup);
  
    // x-unicode pseudo-langGroup should be the last resort to turn to.
    // That is, it should be refered to only when we don't  recognize 
    // |langGroup| specified by the authors of documents and  the 
    // determination of |langGroup| based  on Unicode range also fails 
    // in |FindPrefFont|. 

    if (!strcmp(langGroup, "x-unicode")) {
      mTriedAllGenerics = 1;
      return nsnull;
    }

    AppendGenericFontFromPref(font.name, langGroup, 
                              NS_ConvertUCS2toUTF8(mGeneric).get());
  }

  // Iterate over the list of names using the callback mechanism of nsFont...
  GenericFontEnumContext context = {aDC, aChar, nsnull, this};
  font.EnumerateFamilies(GenericFontEnumCallback, &context);
  if (context.mFont) { // a suitable font was found
    return context.mFont;
  }

#if defined(DEBUG_rbs) || defined(DEBUG_shanjian)
  const char* lang;
  mLangGroup->GetUTF8String(&lang);
  NS_ConvertUCS2toUTF8 generic(mGeneric);
  NS_ConvertUCS2toUTF8 family(mFont.name);
  printf("FindGenericFont missed:U+%04X langGroup:%s generic:%s mFont.name:%s\n", 
         aChar, lang, generic.get(), family.get());
#endif

  mTriedAllGenerics = 1;
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::FindGlobalFont ( HDC  aDC,
PRUint32  aChar 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 2770 of file nsFontMetricsWin.cpp.

{
  //now try global font
  if (!gGlobalFonts) {
    if (!InitializeGlobalFonts(aDC)) {
      return nsnull;
    }
  }
#ifndef WINCE
  PRUint32 range = (c <= 0xFFFF) ? FindCharUnicodeRange(c) : kRangeSurrogate;
  DWORD usb[4];
  memset(usb, 0, sizeof(usb));
  BitFromUnicodeRange(range, usb);
#endif
  int count = gGlobalFonts->Count();
  for (int i = 0; i < count; ++i) {
    nsGlobalFont* font = (nsGlobalFont*)gGlobalFonts->ElementAt(i);
    if (font->flags & NS_GLOBALFONT_SKIP) {
      continue;
    }
    if (!font->ccmap) {
#ifndef WINCE
      // bail out if Unicode range indicates the font have no glyph
      if (font->flags & NS_GLOBALFONT_TRUETYPE &&
          !(font->signature.fsUsb[0] & usb[0]) &&
          !(font->signature.fsUsb[1] & usb[1]) &&
          !(font->signature.fsUsb[2] & usb[2])) {
        continue;
      }
#endif
      // don't adjust here, we just want to quickly get the CMAP. Adjusting
      // is meant to only happen when loading the final font in LoadFont()
      HFONT hfont = ::CreateFontIndirect(&font->logFont);
      if (!hfont) {
        continue;
      }
      HFONT oldFont = (HFONT)::SelectObject(aDC, hfont);
      font->ccmap = GetCCMAP(aDC, font->logFont.lfFaceName, 
        nsnull, &font->fonttype, nsnull);
      ::SelectObject(aDC, oldFont);
      ::DeleteObject(hfont);
      if (!font->ccmap || font->ccmap == gEmptyCCMap) {
        font->flags |= NS_GLOBALFONT_SKIP;
        continue;
      }
#ifdef DEBUG_emk
      LARGE_INTEGER now;
      QueryPerformanceCounter(&now);
      printf("CCMAP loaded: %g sec, %s [%08X][%08X][%08X]\n", (now.QuadPart - prev.QuadPart) / (double)freq.QuadPart,
        font->logFont.lfFaceName, font->signature.fsUsb[0], font->signature.fsUsb[1], font->signature.fsUsb[2]);
      prev = now;
#endif
      if (SameAsPreviousMap(i)) {
        continue;
      }
    }
    if (CCMAP_HAS_CHAR_EXT(font->ccmap, c)) {
#ifdef DEBUG_emk
      printf("font found:[%s]\n", font->logFont.lfFaceName);
      printf("U+%04X (%d)[%08X][%08X][%08X]\n", c, range, usb[0], usb[1], usb[2]);
#endif
      return LoadGlobalFont(aDC, font);
    }
  }
#ifdef DEBUG_emk
  printf("U+%04X (%d)[%08X][%08X][%08X]\n", c, range, usb[0], usb[1], usb[2]);
#endif
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::FindLocalFont ( HDC  aDC,
PRUint32  aChar 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 3368 of file nsFontMetricsWin.cpp.

{
  while (mFontsIndex < mFonts.Count()) {
    if (mFontsIndex == mGenericIndex) {
      return nsnull;
    }

    nsString* name = mFonts.StringAt(mFontsIndex++);
    nsAutoString winName; 
    PRBool found = LookupWinFontName(*name, winName); 
    // the familyNameQuirks should not affect generic & global fonts
    nsFontWin* font = LoadFont(aDC, found ? winName : *name,
                               mFont.familyNameQuirks);
    if (font && font->HasGlyph(aChar)) {
      return font;
    }
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::FindPrefFont ( HDC  aDC,
PRUint32  aChar 
) [virtual]

Definition at line 3523 of file nsFontMetricsWin.cpp.

{
  if (mTriedAllPref) {
    // don't bother anymore because mLoadedFonts[] already has all our pref fonts
    return nsnull;
  }
  nsFont font("", 0, 0, 0, 0, 0);

  // Sometimes we could not find the font in doc's suggested langGroup,(this usually means  
  // the language specified by doc is incorrect). The characters can, to a certain degree, 
  // tell us what language it is. This allows us to quickly locate and use a more appropriate 
  // font as indicated by user's preference. In some situations a set of possible languages may
  // be identified instead of a single language (eg. CJK and latin). In this case we have to 
  // try every language in the set. gUserLocale and gSystemLocale provide some hints about 
  // which one should be tried first. This is important for CJK font, since the glyph for single 
  // char varies dramatically in different langauges. For latin languages, their glyphs are 
  // similar. In fact, they almost always share identical fonts. It will be a waste of time to 
  // figure out which one comes first. As a final fallback, unicode preference is always tried. 

  PRUint32 unicodeRange = FindCharUnicodeRange(aChar);
  if (unicodeRange < kRangeSpecificItemNum) {
    // a single language is identified
    AppendGenericFontFromPref(font.name, LangGroupFromUnicodeRange(unicodeRange), 
                              NS_ConvertUCS2toUTF8(mGeneric).get());
  } else if (kRangeSetLatin == unicodeRange) { 
    // Character is from a latin language set, so try western and central european
    // If mLangGroup is western or central european, this most probably will not be
    // used, but is here as a fallback scenario.    
    AppendGenericFontFromPref(font.name, "x-western",
                              NS_ConvertUCS2toUTF8(mGeneric).get());
    AppendGenericFontFromPref(font.name, "x-central-euro",
                              NS_ConvertUCS2toUTF8(mGeneric).get());
  } else if (kRangeSetCJK == unicodeRange) { 
    // CJK, we have to be careful about the order, use locale info as hint
    
    // then try user locale first, if it is CJK
    if ((gUsersLocale != mLangGroup) && IsCJKLangGroupAtom(gUsersLocale)) {
      nsCAutoString usersLocaleLangGroup;
      gUsersLocale->ToUTF8String(usersLocaleLangGroup);
      AppendGenericFontFromPref(font.name, usersLocaleLangGroup.get(), 
                                NS_ConvertUCS2toUTF8(mGeneric).get());
    }
    
    // then system locale (os language)
    if ((gSystemLocale != mLangGroup) && (gSystemLocale != gUsersLocale) && IsCJKLangGroupAtom(gSystemLocale)) {
      nsCAutoString systemLocaleLangGroup;
      gSystemLocale->ToUTF8String(systemLocaleLangGroup);
      AppendGenericFontFromPref(font.name, systemLocaleLangGroup.get(), 
                                NS_ConvertUCS2toUTF8(mGeneric).get());
    }

    // try all other languages in this set.
    if (mLangGroup != gJA && gUsersLocale != gJA && gSystemLocale != gJA)
      AppendGenericFontFromPref(font.name, "ja",
                                NS_ConvertUCS2toUTF8(mGeneric).get());
    if (mLangGroup != gZHCN && gUsersLocale != gZHCN && gSystemLocale != gZHCN)
      AppendGenericFontFromPref(font.name, "zh-CN",
                                NS_ConvertUCS2toUTF8(mGeneric).get());
    if (mLangGroup != gZHTW && gUsersLocale != gZHTW && gSystemLocale != gZHTW)
      AppendGenericFontFromPref(font.name, "zh-TW",
                                NS_ConvertUCS2toUTF8(mGeneric).get());
    if (mLangGroup != gZHHK && gUsersLocale != gZHHK && gSystemLocale != gZHHK)
      AppendGenericFontFromPref(font.name, "zh-HK",
                                NS_ConvertUCS2toUTF8(mGeneric).get());
    if (mLangGroup != gKO && gUsersLocale != gKO && gSystemLocale != gKO)
      AppendGenericFontFromPref(font.name, "ko",
                                NS_ConvertUCS2toUTF8(mGeneric).get());
  } 

  // always try unicode as fallback
  AppendGenericFontFromPref(font.name, "x-unicode",
                            NS_ConvertUCS2toUTF8(mGeneric).get());
  
  // use the font list to find font
  GenericFontEnumContext context = {aDC, aChar, nsnull, this};
  font.EnumerateFamilies(GenericFontEnumCallback, &context);
  if (context.mFont) { // a suitable font was found
    return context.mFont;
  }
  mTriedAllPref = 1;
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::FindSubstituteFont ( HDC  aDC,
PRUint32  aChar 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 2844 of file nsFontMetricsWin.cpp.

{
  /*
  When this function is called, it means all other alternatives have
  been unsuccessfully tried! So the idea is this:
  
  See if the "substitute font" is already loaded?
  a/ if yes, ADD_GLYPH(c), to record that the font should be used
     to render this char from now on. 
  b/ if no, load the font, and ADD_GLYPH(c)
  */

  // Assumptions: 
  // The nsFontInfo of the "substitute font" is not in the hashtable!
  // This way, its name doesn't matter since it cannot be retrieved with
  // a lookup in the hashtable. We only know its entry in mLoadedFonts[]
  // (Notice that the nsFontInfo of the font that is picked as the
  // "substitute font" *can* be in the hashtable, and as expected, its 
  // own map can be retrieved with the normal lookup).

  // The "substitute font" is a *unicode font*. No conversion here.
  // XXX Is it worth having another subclass which has a converter? 
  // Such a variant may allow to display a boxed question mark, etc.

  if (mSubstituteFont) {
    //make the char representable so that we don't have to go over all font before fallback to 
    //subsituteFont.
    ((nsFontWinSubstitute*)mSubstituteFont)->SetRepresentable(c);
    return mSubstituteFont;
  }

  // The "substitute font" has not yet been created... 
  // The first unicode font (no converter) that has the
  // replacement char is taken and placed as the substitute font.

  // Try local/loaded fonts first
  int i, count = mLoadedFonts.Count();
  for (i = 0; i < count; ++i) {
    nsAutoString name;
    nsFontWin* font = (nsFontWin*)mLoadedFonts[i];

    if (!font->mFont)
      continue;

    HFONT oldFont = (HFONT)::SelectObject(aDC, font->mFont);
    eGetNameError res = GetNAME(aDC, &name);
    ::SelectObject(aDC, oldFont);
    if (res == eGetName_OK) { // TrueType font
      nsFontInfo* info = (nsFontInfo*)PL_HashTableLookup(gFontMaps, &name);
      if (!info || info->mType != eFontType_Unicode) {
        continue;
      }
    }
    else if (res == eGetName_GDIError) { // Bitmap font
      // alright, was treated as unicode font in GetCCMAP()

#ifdef WINCE
      name.AssignWithConversion(font->mName);
      font = LoadSubstituteFont(aDC, name);
      if (font) {
        ((nsFontWinSubstitute*)font)->SetRepresentable(c);
        mSubstituteFont = font;
        return font;
      }
#endif
    }
    else {
      continue;
    }
    if (font->HasGlyph(NS_REPLACEMENT_CHAR)) {
      // XXX if the mode is to display unicode points "&#xNNNN;", should we check
      // that the substitute font also has glyphs for '&', '#', 'x', ';' and digits?
      // (Because this is a unicode font, those glyphs should in principle be there.)
      name.AssignWithConversion(font->mName);
      font = LoadSubstituteFont(aDC, name);
      if (font) {
        ((nsFontWinSubstitute*)font)->SetRepresentable(c);
        mSubstituteFont = font;
        return font;
      }
    }
  }

  // Try global fonts
  // Since we reach here after FindGlobalFont() is called, we have already
  // scanned the global list of fonts and have set the attributes of interest
  count = gGlobalFonts->Count();
  for (i = 0; i < count; ++i) {
    nsGlobalFont* globalFont = (nsGlobalFont*)gGlobalFonts->ElementAt(i);
    if (!globalFont->ccmap || 
        globalFont->flags & NS_GLOBALFONT_SKIP ||
        globalFont->fonttype != eFontType_Unicode) {
      continue;
    }
    if (CCMAP_HAS_CHAR(globalFont->ccmap, NS_REPLACEMENT_CHAR)) {
      nsFontWin* font = LoadSubstituteFont(aDC, globalFont->name);
      if (font) {
        ((nsFontWinSubstitute*)font)->SetRepresentable(c);
        mSubstituteFont = font;
        return font;
      }
    }
  }
  // We are running out of resources if we reach here... Try a stock font
  NS_ASSERTION(::GetMapMode(aDC) == MM_TEXT, "mapping mode needs to be MM_TEXT");
  nsFontWin* font = LoadSubstituteFont(aDC, EmptyString());
  if (font) {
    ((nsFontWinSubstitute*)font)->SetRepresentable(c);
    mSubstituteFont = font;
    return font;
  }

  NS_ERROR("Could not provide a substititute font");
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::FindUserDefinedFont ( HDC  aDC,
PRUint32  aChar 
) [virtual]

Definition at line 3355 of file nsFontMetricsWin.cpp.

{
  if (mIsUserDefined) {
    // the user-defined font is always loaded as the first font
    nsFontWin* font = LoadFont(aDC, mUserDefined);
    mIsUserDefined = PR_FALSE;
    if (font && font->HasGlyph(aChar))
      return font;    
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const nsFont& nsIFontMetrics::Font ( ) [inline, inherited]

Returns the font associated with these metrics.

The return value is only defined after Init() has been called.

Definition at line 214 of file nsIFontMetrics.h.

{ return mFont; }

Here is the caller graph for this function:

Returns the average character width.

Implements nsIFontMetrics.

Definition at line 3993 of file nsFontMetricsWin.cpp.

{
  aAveCharWidth = mAveCharWidth;
  return NS_OK;
}

Here is the caller graph for this function:

PRInt32 nsFontMetricsWin::GetBolderWeight ( PRInt32  aWeight,
PRInt32  aDistance,
PRUint16  aWeightTable 
) [protected]

Definition at line 3236 of file nsFontMetricsWin.cpp.

{
  PRInt32 newWeight = aWeight;
  PRInt32 proposedWeight = aWeight + 100; // Start 1 bolder than the current
  for (PRInt32 j = 0; j < aDistance; ++j) {
    PRBool foundWeight = PR_FALSE;
    while (!foundWeight && (proposedWeight <= NS_MAX_FONT_WEIGHT)) {
      if (IsFontWeightAvailable(proposedWeight, aWeightTable)) {
        newWeight = proposedWeight; 
        foundWeight = PR_TRUE;
      }
      proposedWeight += 100; 
    }
  }
  return newWeight;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUint16 * nsFontMetricsWin::GetCCMAP ( HDC  aDC,
const char *  aShortName,
PRBool aNameQuirks,
eFontType aFontType,
PRUint8 aCharset 
) [static]

Definition at line 1819 of file nsFontMetricsWin.cpp.

{
  if (!gFontMaps) {
    gFontMaps = PL_NewHashTable(0, HashKey, CompareKeys, nsnull, &fontmap_HashAllocOps,
      nsnull);
    if (!gFontMaps) { // error checking
      return nsnull;
    }
    gEmptyCCMap = CreateEmptyCCMap();
    if (!gEmptyCCMap) {
      PL_HashTableDestroy(gFontMaps);
      gFontMaps = nsnull;
      return nsnull;
    }
  }
  eFontType fontType = aFontType ? *aFontType : eFontType_Unicode;
  PRUint8 charset = DEFAULT_CHARSET;
  nsString* name = new nsString(); // deleted by fontmap_FreeEntry
  if (!name) {
    return nsnull;
  }
  nsFontInfo* info;
  PLHashEntry *he, **hep = NULL; // shouldn't be NULL, using it as a flag to catch bad changes
  PLHashNumber hash;
  PRBool nameQuirks = aNameQuirks ? *aNameQuirks : PR_FALSE;
  PRBool isSymbolEncoding = PR_FALSE;
  eGetNameError ret = GetNAME(aDC, name, &isSymbolEncoding);
  if (ret == eGetName_OK) {
    // see if we should treat this name as a quirks name
    if (nameQuirks && (isSymbolEncoding || fontType != eFontType_Unicode)) {
      name->SetCharAt(PRUnichar('1'), 0); // change the prefix: name[0] = '1'
    }
    else {
      nameQuirks = PR_FALSE;
      if (aNameQuirks) {
        *aNameQuirks = PR_FALSE;
      }
    }
    // lookup the hashtable (if we miss, the computed hash and hep are fed back in HT-RawAdd)
    hash = HashKey(name);
    hep = PL_HashTableRawLookup(gFontMaps, hash, name);
    he = *hep;
    if (he) {
      // an identical map has already been added
      delete name;
      info = NS_STATIC_CAST(nsFontInfo *, he);
      if (aCharset) {
        *aCharset = info->mCharset;
      }
      if (aFontType) {
        *aFontType = info->mType;
      }
      return info->mCCMap;
    }
  }
  // GDIError occurs when we have raster font (not TrueType)
  else if (ret == eGetName_GDIError) {
    delete name;
    charset = GetTextCharset(aDC);
    if (charset & (~0xFF)) {
      return gEmptyCCMap;
    }
    int j = gCharsetToIndex[charset];
    
    //default charset is not dependable, skip it at this time
    if (j == eCharset_DEFAULT) {
      return gEmptyCCMap;
    }
    PRUint16* charsetCCMap = gCharsetInfo[j].mCCMap;
    if (!charsetCCMap) {
      charsetCCMap = gCharsetInfo[j].GenerateMap(&gCharsetInfo[j]);
      if (charsetCCMap)
        gCharsetInfo[j].mCCMap = charsetCCMap;
      else
        return gEmptyCCMap;
    }
    if (aCharset) {
      *aCharset = charset;
    }
    if (aFontType) {
      *aFontType = eFontType_Unicode;
    }
    return charsetCCMap;   
  }
  else {
    // return an empty map, so that we never try this font again
    delete name;
    return gEmptyCCMap;
  }

  if (aFontType)
    fontType = *aFontType;
  if (aCharset)
    charset = *aCharset;
  PRUint16* ccmap = GetFontCCMAP(aDC, aShortName, nameQuirks, fontType, charset);
  if (aFontType)
    *aFontType = fontType; 
  if (aCharset)
    *aCharset = charset;

  if (!ccmap) {
    delete name;
    return gEmptyCCMap;
  }

  // XXX Need to check if an identical map has already been added - Bug 75260
  NS_ASSERTION(hep, "bad code");
  he = PL_HashTableRawAdd(gFontMaps, hep, hash, name, nsnull);
  if (he) {
    info = NS_STATIC_CAST(nsFontInfo*, he);
    he->value = info;    // so PL_HashTableLookup returns an nsFontInfo*
    info->mType = fontType;
    info->mCharset = charset;
    info->mCCMap = ccmap;
    return ccmap;
  }
  delete name;
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsFontMetricsWin::GetClosestWeight ( PRInt32  aWeight,
PRUint16  aWeightTable 
) [protected]

Definition at line 3173 of file nsFontMetricsWin.cpp.

{
  // Algorithm used From CSS2 section 15.5.1 Mapping font weight values to font names

  // Check for exact match
  if ((aWeight > 0) && IsFontWeightAvailable(aWeight, aWeightTable)) {
    return aWeight;
  }

  // Find lighter and darker weights to be used later.

  // First look for lighter
  PRBool done = PR_FALSE;
  PRInt32 lighterWeight = 0;
  PRInt32 proposedLighterWeight = PR_MAX(0, aWeight - 100);
  while (!done && (proposedLighterWeight >= 100)) {
    if (IsFontWeightAvailable(proposedLighterWeight, aWeightTable)) {
      lighterWeight = proposedLighterWeight;
      done = PR_TRUE;
    } else {
      proposedLighterWeight -= 100;
    }
  }

  // Now look for darker
  done = PR_FALSE;
  PRInt32 darkerWeight = 0;
  PRInt32 proposedDarkerWeight = PR_MIN(aWeight + 100, 900);
  while (!done && (proposedDarkerWeight <= 900)) {
    if (IsFontWeightAvailable(proposedDarkerWeight, aWeightTable)) {
      darkerWeight = proposedDarkerWeight;
      done = PR_TRUE;   
    } else {
      proposedDarkerWeight += 100;
    }
  }

  // From CSS2 section 15.5.1 

  // If '500' is unassigned, it will be
  // assigned the same font as '400'.
  // If any of '300', '200', or '100' remains unassigned, it is
  // assigned to the next lighter assigned keyword, if any, or 
  // the next darker otherwise. 
  // What about if the desired  weight is 500 and 400 is unassigned?.
  // This is not inlcluded in the CSS spec so I'll treat it in a consistent
  // manner with unassigned '300', '200' and '100'

  if (aWeight <= 500) {
    return lighterWeight ? lighterWeight : darkerWeight;
  } 

  // Automatically chose the bolder weight if the next lighter weight
  // makes it normal. (i.e goes over the normal to bold threshold.)

  // From CSS2 section 15.5.1 
  // if any of the values '600', '700', '800', or '900' remains unassigned, 
  // they are assigned to the same face as the next darker assigned keyword, 
  // if any, or the next lighter one otherwise.
  return darkerWeight ? darkerWeight : lighterWeight;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Returns, in app units, the ascent part of the Western font's em square.

Implements nsIFontMetrics.

Definition at line 3951 of file nsFontMetricsWin.cpp.

{
  aAscent = mEmAscent;
  return NS_OK;
}

Returns, in app units, the descent part of the Western font's em square.

Implements nsIFontMetrics.

Definition at line 3958 of file nsFontMetricsWin.cpp.

{
  aDescent = mEmDescent;
  return NS_OK;
}

Returns the height (in app units) of the Western font's em square.

This is em ascent plus em descent.

Implements nsIFontMetrics.

Definition at line 3944 of file nsFontMetricsWin.cpp.

{
  aHeight = mEmHeight;
  return NS_OK;
}
PRUint16 * nsFontMetricsWin::GetFontCCMAP ( HDC  aDC,
const char *  aShortName,
PRBool  aNameQuirks,
eFontType aFontType,
PRUint8 aCharset 
) [static]

Definition at line 1710 of file nsFontMetricsWin.cpp.

{
  PRUint16 *ccmap = nsnull;

  DWORD len = GetFontData(aDC, CMAP, 0, nsnull, 0);
  if ((len == GDI_ERROR) || (!len)) {
    return nsnull;
  }
  nsAutoFontDataBuffer buffer;
  if (!buffer.EnsureElemCapacity(len)) {
    return nsnull;
  }
  PRUint8* buf = buffer.get();
  DWORD newLen = GetFontData(aDC, CMAP, 0, buf, len);
  if (newLen != len) {
    return nsnull;
  }

  PRUint32 map[UCS2_MAP_LEN];
  memset(map, 0, sizeof(map));
  PRUint8* p = buf + sizeof(PRUint16); // skip version, move to numberSubtables
  PRUint16 n = GET_SHORT(p); // get numberSubtables
  p += sizeof(PRUint16); // skip numberSubtables, move to the encoding subtables
  PRUint16 i;
  PRUint32 keepOffset;
  PRUint32 offset;
  PRUint32 keepFormat = eTTFormatUninitialize;

  for (i = 0; i < n; ++i) {
    PRUint16 platformID = GET_SHORT(p); // get platformID
    p += sizeof(PRUint16); // move to platformSpecificID
    PRUint16 encodingID = GET_SHORT(p); // get platformSpecificID
    p += sizeof(PRUint16); // move to offset
    offset = GET_LONG(p);  // get offset
    p += sizeof(PRUint32); // move to next entry
    if (platformID == eTTPlatformIDMicrosoft) { 
      if (encodingID == eTTMicrosoftEncodingUnicode) { // Unicode
        // Some fonts claim to be unicode when they are actually
        // 'pseudo-unicode' fonts that require a converter...
        // Here, we check if this font is a pseudo-unicode font that 
        // we know something about, and we force it to be treated as
        // a non-unicode font.
        ccmap = GetCCMapThroughConverter(aShortName, aNameQuirks);
        if (ccmap) {
          aCharset = DEFAULT_CHARSET;
          aFontType = eFontType_NonUnicode;
          return ccmap;
        }
        PRUint16 format = GET_SHORT(buf+offset);
        if (format == eTTFormat4SegmentMappingToDeltaValues) {
          keepFormat = eTTFormat4SegmentMappingToDeltaValues;
          keepOffset = offset;
        }
      } // if (encodingID == eTTMicrosoftEncodingUnicode) 
      else if (encodingID == eTTMicrosoftEncodingSymbol) { // symbol
        aCharset = SYMBOL_CHARSET;
        aFontType = eFontType_NonUnicode;
        return GetCCMapThroughConverter(aShortName, aNameQuirks);
      } // if (encodingID == eTTMicrosoftEncodingSymbol)
      else if (encodingID == eTTMicrosoftEncodingUCS4) {
        PRUint16 format = GET_SHORT(buf+offset);
        if (format == eTTFormat12SegmentedCoverage) {
          keepFormat = eTTFormat12SegmentedCoverage;
          keepOffset = offset;
          // we don't want to try anything else when this format is available.
          break;
        }
      }
    } // if (platformID == eTTPlatformIDMicrosoft) 
  } // for loop


  if (eTTFormat12SegmentedCoverage == keepFormat) {
    PRUint32* extMap[EXTENDED_UNICODE_PLANES+1];
    extMap[0] = map;
    memset(extMap+1, 0, sizeof(PRUint32*)*EXTENDED_UNICODE_PLANES);
    ReadCMAPTableFormat12(buf+keepOffset, len-keepOffset, extMap);
    ccmap = MapToCCMapExt(map, extMap+1, EXTENDED_UNICODE_PLANES);
    for (i = 1; i <= EXTENDED_UNICODE_PLANES; ++i) {
      if (extMap[i])
        delete [] extMap[i];
    }
    aCharset = DEFAULT_CHARSET;
    aFontType = eFontType_Unicode;
  }
  else if (eTTFormat4SegmentMappingToDeltaValues == keepFormat) {
    PRUint32 maxGlyph;
    nsAutoFontDataBuffer isSpace;
    PRBool isCFFOutline;
    if (NS_SUCCEEDED(GetSpaces(aDC, &isCFFOutline, &maxGlyph, isSpace))) {
      ReadCMAPTableFormat4(buf+keepOffset, len-keepOffset, map, isCFFOutline,
        isSpace.get(), maxGlyph);
      ccmap = MapToCCMap(map);
      aCharset = DEFAULT_CHARSET;
      aFontType = eFontType_Unicode;
    }
  }

  return ccmap;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::GetFontFor ( HFONT  aHFONT) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 3647 of file nsFontMetricsWin.cpp.

{
  int count = mLoadedFonts.Count();
  for (int i = 0; i < count; ++i) {
    nsFontWin* font = (nsFontWin*)mLoadedFonts[i];
    if (font->mFont == aHFONT)
      return font;
  }
  NS_ERROR("Cannot find the font that owns the handle");
  return nsnull;
}

Returns the font handle associated with these metrics.

Implements nsIFontMetrics.

Definition at line 4015 of file nsFontMetricsWin.cpp.

{
  aHandle = mFontHandle;
  return NS_OK;
}
PRInt32 nsFontMetricsWin::GetFontWeight ( PRInt32  aWeight,
PRUint16  aWeightTable 
) [protected]

Definition at line 3272 of file nsFontMetricsWin.cpp.

{
  // The remainder is used to determine whether to make
  // the font lighter or bolder
  PRInt32 remainder = aWeight % 100;
  PRInt32 normalizedWeight = aWeight / 100;
  PRInt32 selectedWeight = 0;

  // No remainder, so get the closest weight
  if (remainder == 0) {
    selectedWeight = GetClosestWeight(aWeight, aWeightTable);
  } else {
    NS_ASSERTION((remainder < 10) || (remainder > 90), "Invalid bolder or lighter value");
    if (remainder < 10) {
      PRInt32 weight = GetClosestWeight(normalizedWeight * 100, aWeightTable);
      selectedWeight = GetBolderWeight(weight, remainder, aWeightTable);
    } else {
      // Have to add back 1 for the lighter weight since aWeight really refers to the 
      // whole number. eq. 398 really means 2 lighter than font weight 400.
      PRInt32 weight = GetClosestWeight((normalizedWeight + 1) * 100, aWeightTable);
      selectedWeight = GetLighterWeight(weight, 100-remainder, aWeightTable);
    }
  }

//  printf("XXX Input weight %d output weight %d weight table hex %x\n", aWeight, selectedWeight, aWeightTable);
  return selectedWeight;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUint16 nsFontMetricsWin::GetFontWeightTable ( HDC  aDC,
const nsString aFontName 
) [protected]

Definition at line 3139 of file nsFontMetricsWin.cpp.

{
  // Look for all of the weights for a given font.
  LOGFONT logFont;
  logFont.lfCharSet = DEFAULT_CHARSET;

  // The risk of losing characters not covered by the current codepage 
  // is reduced because LookupWinFontName invoked earlier has taken care 
  // of most cases. 
  WideCharToMultiByte(CP_ACP, 0, aFontName.get(), aFontName.Length() + 1,
                      logFont.lfFaceName, sizeof(logFont.lfFaceName),
                      nsnull, nsnull);

  logFont.lfPitchAndFamily = 0;

  nsFontWeightInfo weightInfo;
  weightInfo.mWeights = 0;
  weightInfo.mFontCount = 0;
  ::EnumFontFamiliesEx(aDC, &logFont, nsFontWeightCallback, (LPARAM)&weightInfo, 0);
  if (weightInfo.mFontCount == 0)
    ::EnumFontFamilies(aDC, logFont.lfFaceName, nsFontWeightCallback, (LPARAM)&weightInfo);
  SearchSimulatedFontWeight(aDC, &weightInfo);
//  printf("font weights for %s dec %d hex %x \n", logFont.lfFaceName, weightInfo.mWeights, weightInfo.mWeights);
  return weightInfo.mWeights;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Returns the height (in app units) of the font.

This is ascent plus descent plus any internal leading

This method will be removed once the callers have been moved over to the new GetEmHeight (and possibly GetMaxHeight).

Implements nsIFontMetrics.

Definition at line 3907 of file nsFontMetricsWin.cpp.

{
  aHeight = mMaxHeight;
  return NS_OK;
}

Returns the language group associated with these metrics.

Implements nsIFontMetrics.

Definition at line 4006 of file nsFontMetricsWin.cpp.

{
  NS_ENSURE_ARG_POINTER(aLangGroup);
  *aLangGroup = mLangGroup;
  NS_IF_ADDREF(*aLangGroup);
  return NS_OK;
}

Returns the amount of internal leading (in app units) for the font.

This is computed as the "height - (ascent + descent)"

Implements nsIFontMetrics.

Definition at line 3929 of file nsFontMetricsWin.cpp.

{
  aLeading = mInternalLeading;
  return NS_OK;
}
PRInt32 nsFontMetricsWin::GetLighterWeight ( PRInt32  aWeight,
PRInt32  aDistance,
PRUint16  aWeightTable 
) [protected]

Definition at line 3254 of file nsFontMetricsWin.cpp.

{
  PRInt32 newWeight = aWeight;
  PRInt32 proposedWeight = aWeight - 100; // Start 1 lighter than the current
  for (PRInt32 j = 0; j < aDistance; ++j) {
    PRBool foundWeight = PR_FALSE;
    while (!foundWeight && (proposedWeight >= NS_MIN_FONT_WEIGHT)) {
      if (IsFontWeightAvailable(proposedWeight, aWeightTable)) {
        newWeight = proposedWeight; 
        foundWeight = PR_TRUE;
      }
      proposedWeight -= 100; 
    }
  }
  return newWeight;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Returns, in app units, the maximum character advance for the font.

Implements nsIFontMetrics.

Definition at line 3986 of file nsFontMetricsWin.cpp.

{
  aAdvance = mMaxAdvance;
  return NS_OK;
}

Returns, in app units, the maximum distance characters in this font extend above the base line.

Implements nsIFontMetrics.

Definition at line 3972 of file nsFontMetricsWin.cpp.

{
  aAscent = mMaxAscent;
  return NS_OK;
}

Returns, in app units, the maximum distance characters in this font extend below the base line.

Implements nsIFontMetrics.

Definition at line 3979 of file nsFontMetricsWin.cpp.

{
  aDescent = mMaxDescent;
  return NS_OK;
}

Returns the height (in app units) of the Western font's bounding box.

This is max ascent plus max descent.

Implements nsIFontMetrics.

Definition at line 3965 of file nsFontMetricsWin.cpp.

{
  aHeight = mMaxHeight;
  return NS_OK;
}

Definition at line 4000 of file nsFontMetricsWin.cpp.

{
  return mMaxStringLength;
}

Returns the normal line height (em height + leading).

Implements nsIFontMetrics.

Definition at line 3936 of file nsFontMetricsWin.cpp.

{
  aHeight = mEmHeight + mInternalLeading;
  return NS_OK;
}
NS_IMETHODIMP nsFontMetricsWin::GetSpaceWidth ( nscoord aSpaceCharWidth) [virtual]

Returns the often needed width of the space character.

Implements nsIFontMetrics.

Definition at line 3863 of file nsFontMetricsWin.cpp.

{
  aSpaceWidth = mSpaceWidth;
  return NS_OK;
}

Here is the caller graph for this function:

NS_IMETHODIMP nsFontMetricsWin::GetStrikeout ( nscoord aOffset,
nscoord aSize 
) [virtual]

Return the font's strikeout offset (the distance from the baseline to where a strikeout should be placed) and size Positive values are above the baseline, negative below.

Implements nsIFontMetrics.

Definition at line 3891 of file nsFontMetricsWin.cpp.

{
  aOffset = mStrikeoutOffset;
  aSize = mStrikeoutSize;
  return NS_OK;
}

Return the font's subscript offset (the distance from the baseline to where a subscript's baseline should be placed).

The value returned will be a positive value.

Implements nsIFontMetrics.

Definition at line 3884 of file nsFontMetricsWin.cpp.

Return the font's superscript offset (the distance from the baseline to where a superscript's baseline should be placed).

The value returned will be a positive value.

Implements nsIFontMetrics.

Definition at line 3877 of file nsFontMetricsWin.cpp.

NS_IMETHODIMP nsFontMetricsWin::GetUnderline ( nscoord aOffset,
nscoord aSize 
) [virtual]

Return the font's underline offset (the distance from the baseline to where a underline should be placed) and size.

Positive values are above the baseline, negative below.

Implements nsIFontMetrics.

Definition at line 3899 of file nsFontMetricsWin.cpp.

{
  aOffset = mUnderlineOffset;
  aSize = mUnderlineSize;
  return NS_OK;
}

Return the font's xheight property, scaled into app-units.

Implements nsIFontMetrics.

Definition at line 3870 of file nsFontMetricsWin.cpp.

{
  aResult = mXHeight;
  return NS_OK;
}
NS_IMETHODIMP nsFontMetricsWin::Init ( const nsFont aFont,
nsIAtom aLangGroup,
nsIDeviceContext aContext 
) [virtual]

Initialize the font metrics.

Call this after creating the font metrics. Font metrics you get from the font cache do NOT need to be initialized

See also:
nsIDeviceContext::GetMetricsFor()

Implements nsIFontMetrics.

Definition at line 561 of file nsFontMetricsWin.cpp.

{
  nsresult res;
  if (!gInitialized) {
    res = InitGlobals();
    //XXXrbs this should be a fatal startup error
    NS_ASSERTION(NS_SUCCEEDED(res), "No font at all has been created");
    if (NS_FAILED(res)) {
      return res;
    }
  }

  mFont = aFont;
  mLangGroup = aLangGroup;

  // do special checking for the following lang group
  // * use fonts?
  PRInt32 useDccFonts = 0;
  if (NS_SUCCEEDED(gPref->GetIntPref("browser.display.use_document_fonts", &useDccFonts)) && (useDccFonts != 0)) {
    CheckFontLangGroup(mLangGroup, gJA,   "ja");
    CheckFontLangGroup(mLangGroup, gKO,   "ko");
    CheckFontLangGroup(mLangGroup, gZHTW, "zh-TW");
    CheckFontLangGroup(mLangGroup, gZHCN, "zh-CN");
    CheckFontLangGroup(mLangGroup, gZHHK, "zh-HK");
  }

  //don't addref this to avoid circular refs
  mDeviceContext = (nsDeviceContextWin *)aContext;
  return RealizeFont();
}

Here is the call graph for this function:

Definition at line 2698 of file nsFontMetricsWin.cpp.

{
  if (!gGlobalFonts) {
    gGlobalFonts = new nsVoidArray();
    if (!gGlobalFonts) return nsnull;

    LOGFONT logFont;
    logFont.lfCharSet = DEFAULT_CHARSET;
    logFont.lfFaceName[0] = 0;
    logFont.lfPitchAndFamily = 0;

    /*
     * msdn.microsoft.com/library states that
     * EnumFontFamiliesExW is only on NT4+
     */
    EnumFontFamiliesEx(aDC, &logFont, enumProc, TRUETYPE_FONTTYPE, 0);
    if (gGlobalFonts->Count() == 0)
      EnumFontFamilies(aDC, nsnull, enumProc, 0);

    // Sort the global list of fonts to put the 'preferred' fonts first
    gGlobalFonts->Sort(CompareGlobalFonts, nsnull);
  }

  return gGlobalFonts;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsFontMetricsWin::InitMetricsFor ( HDC  aDC,
nsFontWin aFontWin 
)

Definition at line 2361 of file nsFontMetricsWin.cpp.

{
  float dev2app;
  dev2app = mDeviceContext->DevUnitsToAppUnits();

  TEXTMETRIC metrics;
  ::GetTextMetrics(aDC, &metrics);
  aFont->mMaxAscent = NSToCoordRound(metrics.tmAscent * dev2app);
  aFont->mMaxDescent = NSToCoordRound(metrics.tmDescent * dev2app);
  aFont->mOverhangCorrection = 0;
  if (IsWin95OrWin98()) {
    aFont->mOverhangCorrection = metrics.tmOverhang;
    if (metrics.tmOverhang < 3 && metrics.tmItalic &&
        !(metrics.tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE | TMPF_DEVICE))) {
      // bug 216670 - for several italicized bitmap fonts, we have to compute
      // a overhang value, since the built-in value is zero if the weight of
      // the font is normal or it is one if the weight of the font is bold.
      SIZE size;
      ::GetTextExtentPoint32(aDC, " ", 1, &size);
      if (!(metrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
        // optimization for monospace fonts: no need to make another GDI call.
        // We can use tmAveCharWidth since it does not include the overhang.
        aFont->mOverhangCorrection = size.cx - metrics.tmAveCharWidth;
      } else {
        SIZE size2;
        ::GetTextExtentPoint32(aDC, "  ", 2, &size2);
        aFont->mOverhangCorrection = size.cx * 2 - size2.cx;
      }
    }
  }
  aFont->mMaxCharWidthMetric = metrics.tmMaxCharWidth;
  aFont->mMaxHeightMetric = metrics.tmHeight;
  aFont->mPitchAndFamily = metrics.tmPitchAndFamily;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsFontMetricsWin::IsFontWeightAvailable ( PRInt32  aWeight,
PRUint16  aWeightTable 
) [static]

Definition at line 3062 of file nsFontMetricsWin.cpp.

                                                                                     {
  PRInt32 normalizedWeight = aWeight / 100;
  NS_ASSERTION((aWeight >= 100) && (aWeight <= 900), "Invalid font weight passed");
  PRUint16 bitwiseWeight = 1 << (normalizedWeight - 1);
  return (bitwiseWeight & aWeightTable) != 0;
}

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::LoadFont ( HDC  aDC,
const nsString aName,
PRBool  aNameQuirks = PR_FALSE 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 2498 of file nsFontMetricsWin.cpp.

{
  LOGFONT logFont;
  HFONT hfont = CreateFontHandle(aDC, aName, &logFont);
  if (hfont) {
    HFONT oldFont = (HFONT)::SelectObject(aDC, (HGDIOBJ)hfont);
    char name[sizeof(logFont.lfFaceName)];
    if (::GetTextFace(aDC, sizeof(name), name) &&
        !strcmpi(name, logFont.lfFaceName)) {
      nsFontWin* font = nsnull;
      if (mIsUserDefined) {
#ifndef WINCE
        font = new nsFontWinNonUnicode(&logFont, hfont, gUserDefinedCCMap,
                                       gUserDefinedConverter);
#else
        font = new nsFontWinUnicode(&logFont, hfont, gUserDefinedCCMap);
#endif
    } else {
        eFontType fontType = eFontType_Unicode;
        PRBool nameQuirks = aNameQuirks;
        // see if we should override the quirks -- not all fonts are treated as quirks
        if (nameQuirks) {
          nsCAutoString encoding;
          PRBool isWide = PR_FALSE;
          if (NS_SUCCEEDED(GetCustomEncoding(logFont.lfFaceName, encoding, &isWide))) {
            nameQuirks = !isWide;
            fontType = eFontType_NonUnicode;
          }
        }
        PRUint16* ccmap = GetCCMAP(aDC, logFont.lfFaceName, &nameQuirks,
                                   &fontType, nsnull);
        if (ccmap) {
          if (eFontType_Unicode == fontType) {
            font = new nsFontWinUnicode(&logFont, hfont, ccmap);
          }
          else if (eFontType_NonUnicode == fontType) {
            PRBool isWide = PR_FALSE;
            nsCOMPtr<nsIUnicodeEncoder> converter;
            if (NS_SUCCEEDED(GetConverter(logFont.lfFaceName, nameQuirks,
                  getter_AddRefs(converter), &isWide)))
#ifndef WINCE
               font = new nsFontWinNonUnicode(&logFont, hfont, ccmap, converter, isWide);
#else
               font = new nsFontWinUnicode(&logFont, hfont, ccmap);
#endif
          }
        }
      }

      if (font) {
        InitMetricsFor(aDC, font);
        mLoadedFonts.AppendElement(font);
        ::SelectObject(aDC, (HGDIOBJ)oldFont);  
        return font;
      }
      // do not free 'ccmap', it is cached in the gFontMaps hashtable and
      // it is going to be deleted by the cleanup observer
    }
    ::SelectObject(aDC, (HGDIOBJ)oldFont);
    ::DeleteObject(hfont);
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::LoadGenericFont ( HDC  aDC,
PRUint32  aChar,
const nsString aName 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 3389 of file nsFontMetricsWin.cpp.

{
  for (int i = mLoadedFonts.Count()-1; i >= 0; --i) {
    // woah, this seems bad
    const nsACString& fontName =
      nsDependentCString(((nsFontWin*)mLoadedFonts[i])->mName);
    if (aName.Equals(NS_ConvertASCIItoUCS2(fontName),
                     nsCaseInsensitiveStringComparator()))
      return nsnull;

  }
  nsFontWin* font = LoadFont(aDC, aName);
  if (font && font->HasGlyph(aChar)) {
    return font;
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::LoadGlobalFont ( HDC  aDC,
nsGlobalFont aGlobalFontItem 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 2563 of file nsFontMetricsWin.cpp.

{
  LOGFONT logFont;
  HFONT hfont = CreateFontHandle(aDC, aGlobalFont, &logFont);
  if (hfont) {
    nsFontWin* font = nsnull;
    if (eFontType_Unicode == aGlobalFont->fonttype) {
      font = new nsFontWinUnicode(&logFont, hfont, aGlobalFont->ccmap);
    }
    else if (eFontType_NonUnicode == aGlobalFont->fonttype) {
      nsCOMPtr<nsIUnicodeEncoder> converter;
      PRBool isWide;
      if (NS_SUCCEEDED(GetConverter(logFont.lfFaceName, PR_FALSE,
            getter_AddRefs(converter), &isWide))) {
#ifndef WINCE
        font = new nsFontWinNonUnicode(&logFont, hfont, aGlobalFont->ccmap, converter, isWide);
#else
        font = new nsFontWinUnicode(&logFont, hfont, aGlobalFont->ccmap);
#endif
      }
    }
    if (font) {
      HFONT oldFont = (HFONT)::SelectObject(aDC, (HGDIOBJ)hfont);
      InitMetricsFor(aDC, font);
      mLoadedFonts.AppendElement(font);
      ::SelectObject(aDC, (HGDIOBJ)oldFont);
      return font;
    }
    ::DeleteObject((HGDIOBJ)hfont);
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::LoadSubstituteFont ( HDC  aDC,
const nsString aName 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 2961 of file nsFontMetricsWin.cpp.

{
  LOGFONT logFont;
  HFONT hfont = !aName.IsEmpty()
    ? CreateFontHandle(aDC, aName, &logFont)
    : (HFONT)::GetStockObject(SYSTEM_FONT);
  if (hfont) {
    // XXX 'displayUnicode' has to be initialized based on the desired rendering mode
    PRBool displayUnicode = PR_FALSE;
    /* substitute font does not need ccmap */
    LOGFONT* lfont = !aName.IsEmpty() ? &logFont : nsnull;
    nsFontWinSubstitute* font = new nsFontWinSubstitute(lfont, hfont, nsnull, displayUnicode);
    if (font) {
      HFONT oldFont = (HFONT)::SelectObject(aDC, (HGDIOBJ)hfont);
      InitMetricsFor(aDC, font);
      mLoadedFonts.AppendElement((nsFontWin*)font);
      ::SelectObject(aDC, (HGDIOBJ)oldFont);
      return font;
    }
    ::DeleteObject((HGDIOBJ)hfont);
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontWin * nsFontMetricsWin::LocateFont ( HDC  aDC,
PRUint32  aChar,
PRInt32 aCount 
) [protected]

Definition at line 4022 of file nsFontMetricsWin.cpp.

{
  nsFontWin *font;
  PRInt32 i;

  // see if one of our loaded fonts can represent the character
  for (i = 0; i < aCount; ++i) {
    font = (nsFontWin*)mLoadedFonts[i];
    if (font->HasGlyph(aChar))
      return font;
  }

  font = FindFont(aDC, aChar);
  aCount = mLoadedFonts.Count(); // update since FindFont() can change it
  NS_ASSERTION(font && mLoadedFonts.IndexOf(font) >= 0,
               "Could not find a font");
  return font;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUint16 nsFontMetricsWin::LookForFontWeightTable ( HDC  aDc,
const nsString aName 
) [protected]

Definition at line 3301 of file nsFontMetricsWin.cpp.

{
  // Initialize the font weight table if need be.
  if (!gFontWeights) {
    gFontWeights = PL_NewHashTable(0, HashKeyFontWeight, CompareKeysFontWeight, nsnull, &fontweight_HashAllocOps,
      nsnull);
    if (!gFontWeights) {
      return 0;
    }
  }

  // Use lower case name for hash table searches. This eliminates
  // keeping multiple font weights entries when the font name varies 
  // only by case.
  nsAutoString low(aName);
  ToLowerCase(low);

   // See if the font weight has already been computed.
  nsFontWeightEntry searchEntry;
  searchEntry.mFontName = low;
  searchEntry.mWeightTable = 0;

  nsFontWeightEntry* weightEntry;
  PLHashEntry **hep, *he;
  PLHashNumber hash = HashKeyFontWeight(&searchEntry);
  hep = PL_HashTableRawLookup(gFontWeights, hash, &searchEntry);
  he = *hep;
  if (he) {
    // an identical fontweight has already been added
    weightEntry = NS_STATIC_CAST(nsFontWeightEntry *, he);
    return weightEntry->mWeightTable;
  }

   // Hasn't been computed, so need to compute and store it.
  PRUint16 weightTable = GetFontWeightTable(aDC, aName);
//  printf("Compute font weight %d\n",  weightTable);

   // Store it in font weight HashTable.
  he = PL_HashTableRawAdd(gFontWeights, hep, hash, &searchEntry, nsnull);
  if (he) {   
    weightEntry = NS_STATIC_CAST(nsFontWeightEntry*, he);
    weightEntry->mFontName = low;
    weightEntry->mWeightTable = weightTable;
    he->key = weightEntry;
    he->value = weightEntry;
    return weightEntry->mWeightTable;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


See documentation in nsFontMetricsWin.h 05/28/99 dwc

Definition at line 3680 of file nsFontMetricsWin.cpp.

{
  nsresult rv;
  HWND win = NULL;
  HDC  dc = NULL;
  HDC  dc1 = NULL;

  if (mDeviceContext->mDC){
    // XXX - DC If we are printing, we need to get the printer HDC and a screen HDC
    // The screen HDC is because there seems to be a bug or requirment that the 
    // GetFontData() method call have a screen HDC, some printers HDC's return nothing
    // thats will give us bad font data, and break us.  
    dc = mDeviceContext->mDC;
    win = (HWND)mDeviceContext->mWidget;
    dc1 = ::GetDC(win);
  } else {
    // Find font metrics and character widths
    win = (HWND)mDeviceContext->mWidget;
    dc = ::GetDC(win);
    dc1 = dc;
  }

  mFont.EnumerateFamilies(FontEnumCallback, this); 

  nsCAutoString pref;
  nsXPIDLString value;

  // set a fallback generic font if the font-family list didn't have one
  if (mGeneric.IsEmpty()) {
    pref.Assign("font.default.");
    const char* langGroup;
    mLangGroup->GetUTF8String(&langGroup);
    pref.Append(langGroup);
    rv = gPref->CopyUnicharPref(pref.get(), getter_Copies(value));
    if (NS_SUCCEEDED(rv)) {
      mGeneric.Assign(value);
    }
    else {
      mGeneric.AssignLiteral("serif");
    }
  }

  if (mLangGroup.get() == gUserDefined) {
    if (!gUserDefinedConverter) {
      rv = gCharsetManager->GetUnicodeEncoderRaw("x-user-defined", &gUserDefinedConverter);
      if (NS_FAILED(rv)) return rv;
      gUserDefinedConverter->SetOutputErrorBehavior(
        gUserDefinedConverter->kOnError_Replace, nsnull, '?');
      nsCOMPtr<nsICharRepresentable> mapper =
        do_QueryInterface(gUserDefinedConverter);
      if (mapper) {
        gUserDefinedCCMap = MapperToCCMap(mapper);
      }
    }

    // See if this is a special user-defined font encoding by checking:
    // font.name.[generic].x-user-def
    pref.Assign("font.name.");
    pref.AppendWithConversion(mGeneric);
    pref.Append(".x-user-def");
    rv = gPref->CopyUnicharPref(pref.get(), getter_Copies(value));
    if (NS_SUCCEEDED(rv)) {
      mUserDefined.Assign(value);
      mIsUserDefined = 1;
    }
  }

  nsFontWin* font = FindFont(dc1, 'a');
  NS_ASSERTION(font, "missing font");
  if (!font) {
    ::ReleaseDC(win, mDeviceContext->mDC ? dc1 : dc);
    return NS_ERROR_FAILURE;
  }
  mFontHandle = font->mFont;

  HFONT oldfont = (HFONT)::SelectObject(dc, (HGDIOBJ) mFontHandle);

  // Get font metrics
  float dev2app;
  dev2app = mDeviceContext->DevUnitsToAppUnits();
  OUTLINETEXTMETRIC oMetrics;
  TEXTMETRIC& metrics = oMetrics.otmTextMetrics;
  nscoord onePixel = NSToCoordRound(1 * dev2app);
  nscoord descentPos = 0;

  if (0 < ::GetOutlineTextMetrics(dc, sizeof(oMetrics), &oMetrics)) {
//    mXHeight = NSToCoordRound(oMetrics.otmsXHeight * dev2app);  XXX not really supported on windows
    mXHeight = NSToCoordRound((float)metrics.tmAscent * dev2app * 0.56f); // 50% of ascent, best guess for true type
    mSuperscriptOffset = NSToCoordRound(oMetrics.otmptSuperscriptOffset.y * dev2app);
    mSubscriptOffset = NSToCoordRound(oMetrics.otmptSubscriptOffset.y * dev2app);

    mStrikeoutSize = PR_MAX(onePixel, NSToCoordRound(oMetrics.otmsStrikeoutSize * dev2app));
    mStrikeoutOffset = NSToCoordRound(oMetrics.otmsStrikeoutPosition * dev2app);
    mUnderlineSize = PR_MAX(onePixel, NSToCoordRound(oMetrics.otmsUnderscoreSize * dev2app));
    if (gDoingLineheightFixup) {
      if(IsCJKLangGroupAtom(mLangGroup.get())) {
        mUnderlineOffset = NSToCoordRound(PR_MIN(oMetrics.otmsUnderscorePosition, 
                                                 oMetrics.otmDescent + oMetrics.otmsUnderscoreSize) 
                                                 * dev2app);
        // keep descent position, use it for mUnderlineOffset if leading allows
        descentPos = NSToCoordRound(oMetrics.otmDescent * dev2app);
      } else {
        mUnderlineOffset = NSToCoordRound(PR_MIN(oMetrics.otmsUnderscorePosition*dev2app, 
                                                 oMetrics.otmDescent*dev2app + mUnderlineSize));
      }
    }
    else
      mUnderlineOffset = NSToCoordRound(oMetrics.otmsUnderscorePosition * dev2app);

    // Begin -- section of code to get the real x-height with GetGlyphOutline()
    GLYPHMETRICS gm;
    DWORD len = gGlyphAgent.GetGlyphMetrics(dc, PRUnichar('x'), 0, &gm);
    if (GDI_ERROR != len && gm.gmptGlyphOrigin.y > 0)
    {
      mXHeight = NSToCoordRound(gm.gmptGlyphOrigin.y * dev2app);
    }
    // End -- getting x-height
  }
  else {
    // Make a best-effort guess at extended metrics
    // this is based on general typographic guidelines
    ::GetTextMetrics(dc, &metrics);
    mXHeight = NSToCoordRound((float)metrics.tmAscent * dev2app * 0.56f); // 56% of ascent, best guess for non-true type
    mSuperscriptOffset = mXHeight;     // XXX temporary code!
    mSubscriptOffset = mXHeight;     // XXX temporary code!

    mStrikeoutSize = onePixel; // XXX this is a guess
    mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0f); // 50% of xHeight
    mUnderlineSize = onePixel; // XXX this is a guess
    mUnderlineOffset = -NSToCoordRound((float)metrics.tmDescent * dev2app * 0.30f); // 30% of descent
  }

  mInternalLeading = NSToCoordRound(metrics.tmInternalLeading * dev2app);
  mExternalLeading = NSToCoordRound(metrics.tmExternalLeading * dev2app);
  mEmHeight = NSToCoordRound((metrics.tmHeight - metrics.tmInternalLeading) *
                             dev2app);
  mEmAscent = NSToCoordRound((metrics.tmAscent - metrics.tmInternalLeading) *
                             dev2app);
  mEmDescent = NSToCoordRound(metrics.tmDescent * dev2app);
  mMaxHeight = NSToCoordRound(metrics.tmHeight * dev2app);
  mMaxAscent = NSToCoordRound(metrics.tmAscent * dev2app);
  mMaxDescent = NSToCoordRound(metrics.tmDescent * dev2app);
  mMaxAdvance = NSToCoordRound(metrics.tmMaxCharWidth * dev2app);
  // Windows may screw up if we try to measure/draw more than 32767 pixels in
  // one operation.
  mMaxStringLength = (PRInt32)floor(32767.0/metrics.tmMaxCharWidth);
  mMaxStringLength = PR_MAX(1, mMaxStringLength);

  mAveCharWidth = PR_MAX(1, NSToCoordRound(metrics.tmAveCharWidth * dev2app));

  if (gDoingLineheightFixup) {
    if (mInternalLeading + mExternalLeading > mUnderlineSize &&
        descentPos < mUnderlineOffset) {
      // If underline positioned is too near from the text, descent position
      // is preferred, but we need to make sure there is enough space
      // available so that underline will stay within boundary.
      mUnderlineOffset = descentPos;
      nscoord extra = mUnderlineSize - mUnderlineOffset - mMaxDescent;
      if (extra > 0) {
        mEmDescent += extra;  
        mEmHeight += extra;
        mMaxDescent += extra;
        mMaxHeight += extra;
      }
    } else if (mUnderlineSize - mUnderlineOffset > mMaxDescent) {
      // If underline positioned is too far from the text, descent position
      // is preferred so that underline will stay within boundary.
      mUnderlineOffset = mUnderlineSize - mMaxDescent;
    }
  }
  // Cache the width of a single space.
  SIZE  size;
  ::GetTextExtentPoint32(dc, " ", 1, &size);
  size.cx -= font->mOverhangCorrection;
  mSpaceWidth = NSToCoordRound(size.cx * dev2app);

  ::SelectObject(dc, oldfont);

  ::ReleaseDC(win, mDeviceContext->mDC ? dc1 : dc);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFontMetricsWin::ResolveBackwards ( HDC  aDC,
const PRUnichar aString,
PRUint32  aLength,
nsFontSwitchCallback  aFunc,
void aData 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 4130 of file nsFontMetricsWin.cpp.

{
  NS_ASSERTION(aString || !aLength, "invalid call");
  const PRUnichar* firstChar = aString + aLength - 1;
  const PRUnichar* lastChar  = aString - 1;
  const PRUnichar* currChar  = firstChar;
  nsFontWin* currFont;
  nsFontWin* nextFont;
  PRInt32 count;
  nsFontSwitch fontSwitch;

  if (firstChar == lastChar)
    return NS_OK;

  count = mLoadedFonts.Count();

  // see if one of our loaded fonts can represent the current character
  if (IS_LOW_SURROGATE(*currChar) && (currChar-1) > lastChar && IS_HIGH_SURROGATE(*(currChar-1))) {
    currFont = LocateFont(aDC, SURROGATE_TO_UCS4(*(currChar-1), *currChar), count);
    currChar -= 2;
  }
  else {
    currFont = LocateFont(aDC, *currChar, count);
    --currChar;
  }

  //This if block is meant to speedup the process in normal situation, when
  //most characters can be found in first font
  NS_ASSERTION(count > 1, "only one font loaded");
  // mLoadedFont[0] == font for invisible ignorable characters
  PRUint32 firstFont = count > 1 ? 1 : 0; 
  if (currFont == mLoadedFonts[firstFont]) {
    while (currChar > lastChar && 
           (currFont->HasGlyph(*currChar)) &&
           !CCMAP_HAS_CHAR_EXT(gIgnorableCCMapExt, *currChar) &&
           !IS_RTL_PRESENTATION_FORM(*currChar))
      --currChar;
    fontSwitch.mFontWin = currFont;
    if (!(*aFunc)(&fontSwitch, currChar+1, firstChar - currChar, aData))
      return NS_OK;
    if (currChar == lastChar)
      return NS_OK;
    // continue with the next substring, re-using the available loaded fonts
    firstChar = currChar;
    if (IS_LOW_SURROGATE(*currChar) && (currChar-1) > lastChar && IS_HIGH_SURROGATE(*(currChar-1))) {
      currFont = LocateFont(aDC, SURROGATE_TO_UCS4(*(currChar-1), *currChar), count);
      currChar -= 2;
    }
    else {
      currFont = LocateFont(aDC, *currChar, count);
      --currChar;
    }
  }

  // see if we can keep the same font for adjacent characters
  PRInt32 lastCharLen;
  PRUint32 codepoint;

  while (currChar > lastChar) {
    if (IS_LOW_SURROGATE(*currChar) && (currChar-1) > lastChar && IS_HIGH_SURROGATE(*(currChar-1))) {
      codepoint =  SURROGATE_TO_UCS4(*(currChar-1), *currChar);
      nextFont = LocateFont(aDC, codepoint, count);
      lastCharLen = 2;
    }
    else {
      codepoint = *currChar;
      nextFont = LocateFont(aDC, codepoint, count);
      lastCharLen = 1;
    }
    if (nextFont != currFont ||
        /* render Hebrew and Arabic presentation forms and right-to-left
           characters outside the BMP one by one, because Windows doesn't reorder
           them. 
       XXX If a future version of Uniscribe corrects this, we will need to make a
           run-time check and set a rendering hint accordingly */
        codepoint > 0xFFFF ||
        IS_RTL_PRESENTATION_FORM(codepoint)) {
      // We have a substring that can be represented with the same font, and
      // we are about to switch fonts, it is time to notify our caller.
      fontSwitch.mFontWin = currFont;
      if (!(*aFunc)(&fontSwitch, currChar+1, firstChar - currChar, aData))
        return NS_OK;
      // continue with the next substring, re-using the available loaded fonts
      firstChar = currChar;
      currFont = nextFont; // use the font found earlier for the char
    }
    currChar -= lastCharLen;
  }

  //do it for last part of the string
  fontSwitch.mFontWin = currFont;
  (*aFunc)(&fontSwitch, currChar+1, firstChar - currChar, aData);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFontMetricsWin::ResolveForwards ( HDC  aDC,
const PRUnichar aString,
PRUint32  aLength,
nsFontSwitchCallback  aFunc,
void aData 
) [virtual]

Reimplemented in nsFontMetricsWinA.

Definition at line 4042 of file nsFontMetricsWin.cpp.

{
  NS_ASSERTION(aString || !aLength, "invalid call");
  const PRUnichar* firstChar = aString;
  const PRUnichar* currChar = firstChar;
  const PRUnichar* lastChar  = aString + aLength;
  nsFontWin* currFont;
  nsFontWin* nextFont;
  PRInt32 count;
  nsFontSwitch fontSwitch;

  if (firstChar == lastChar)
    return NS_OK;

  count = mLoadedFonts.Count();

  if (IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && IS_LOW_SURROGATE(*(currChar+1))) {
    currFont = LocateFont(aDC, SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count);
    currChar += 2;
  }
  else {
    currFont = LocateFont(aDC, *currChar, count);
    ++currChar;
  }

  //This if block is meant to speedup the process in normal situation, when
  //most characters can be found in first font
  NS_ASSERTION(count > 1, "only one font loaded");
  // mLoadedFont[0] == font for invisible ignorable characters
  PRUint32 firstFont = count > 1 ? 1 : 0; 
  if (currFont == mLoadedFonts[firstFont]) { 
    while (currChar < lastChar && 
           (currFont->HasGlyph(*currChar)) &&
           !CCMAP_HAS_CHAR_EXT(gIgnorableCCMapExt, *currChar))
      ++currChar;
    fontSwitch.mFontWin = currFont;
    if (!(*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData))
      return NS_OK;
    if (currChar == lastChar)
      return NS_OK;
    // continue with the next substring, re-using the available loaded fonts
    firstChar = currChar;
    if (IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && IS_LOW_SURROGATE(*(currChar+1))) {
      currFont = LocateFont(aDC, SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count);
      currChar += 2;
    }
    else {
      currFont = LocateFont(aDC, *currChar, count);
      ++currChar;
    }
  }

  // see if we can keep the same font for adjacent characters
  PRInt32 lastCharLen;
  while (currChar < lastChar) {
    if (IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && IS_LOW_SURROGATE(*(currChar+1))) {
      nextFont = LocateFont(aDC, SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count);
      lastCharLen = 2;
    }
    else {
      nextFont = LocateFont(aDC, *currChar, count);
      lastCharLen = 1;
    }
    if (nextFont != currFont) {
      // We have a substring that can be represented with the same font, and
      // we are about to switch fonts, it is time to notify our caller.
      fontSwitch.mFontWin = currFont;
      if (!(*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData))
        return NS_OK;
      // continue with the next substring, re-using the available loaded fonts
      firstChar = currChar;

      currFont = nextFont; // use the font found earlier for the char
    }
    currChar += lastCharLen;
  }

  //do it for last part of the string
  fontSwitch.mFontWin = currFont;
  (*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2725 of file nsFontMetricsWin.cpp.

{
  // aIndex is 0...gGlobalFonts.Count()-1 in caller
  nsGlobalFont* font = (nsGlobalFont*)gGlobalFonts->ElementAt(aIndex);
  for (int i = 0; i < aIndex; ++i) {
    nsGlobalFont* tmp = (nsGlobalFont*)gGlobalFonts->ElementAt(i);
    if (tmp->flags & NS_GLOBALFONT_SKIP) {
      continue;
    }
    if (!tmp->ccmap) {
      continue;
    }
    if (tmp->ccmap == font->ccmap) {
      font->flags |= NS_GLOBALFONT_SKIP;
      return 1;
    }

    if (IsSameCCMap(tmp->ccmap, font->ccmap)) {
      font->flags |= NS_GLOBALFONT_SKIP;
      return 1;
    }
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsFontMetricsWin::SetFontWeight ( PRInt32  aWeight,
PRUint16 aWeightTable 
) [static]

Definition at line 3056 of file nsFontMetricsWin.cpp.

                                                                            {
  NS_ASSERTION((aWeight >= 0) && (aWeight <= 9), "Invalid font weight passed");
  *aWeightTable |= 1 << (aWeight - 1);
}

Here is the caller graph for this function:


Member Data Documentation

Definition at line 292 of file nsFontMetricsWin.h.

Definition at line 294 of file nsFontMetricsWin.h.

Definition at line 293 of file nsFontMetricsWin.h.

Definition at line 295 of file nsFontMetricsWin.h.

Definition at line 296 of file nsFontMetricsWin.h.

Definition at line 357 of file nsFontMetricsWin.h.

Definition at line 344 of file nsFontMetricsWin.h.

Definition at line 351 of file nsFontMetricsWin.h.

Definition at line 352 of file nsFontMetricsWin.h.

Definition at line 350 of file nsFontMetricsWin.h.

Definition at line 348 of file nsFontMetricsWin.h.

nsFont nsIFontMetrics::mFont [protected, inherited]

Definition at line 238 of file nsIFontMetrics.h.

Definition at line 346 of file nsFontMetricsWin.h.

nsStringArray nsFontMetricsWin::mFonts

Definition at line 278 of file nsFontMetricsWin.h.

Definition at line 279 of file nsFontMetricsWin.h.

Definition at line 284 of file nsFontMetricsWin.h.

Definition at line 283 of file nsFontMetricsWin.h.

Definition at line 349 of file nsFontMetricsWin.h.

Definition at line 290 of file nsFontMetricsWin.h.

Definition at line 277 of file nsFontMetricsWin.h.

Definition at line 280 of file nsFontMetricsWin.h.

Definition at line 356 of file nsFontMetricsWin.h.

Definition at line 354 of file nsFontMetricsWin.h.

Definition at line 355 of file nsFontMetricsWin.h.

Definition at line 353 of file nsFontMetricsWin.h.

Definition at line 366 of file nsFontMetricsWin.h.

Definition at line 365 of file nsFontMetricsWin.h.

Definition at line 362 of file nsFontMetricsWin.h.

Definition at line 361 of file nsFontMetricsWin.h.

Definition at line 360 of file nsFontMetricsWin.h.

Definition at line 281 of file nsFontMetricsWin.h.

Definition at line 359 of file nsFontMetricsWin.h.

Definition at line 288 of file nsFontMetricsWin.h.

Definition at line 289 of file nsFontMetricsWin.h.

Definition at line 364 of file nsFontMetricsWin.h.

Definition at line 363 of file nsFontMetricsWin.h.

Definition at line 286 of file nsFontMetricsWin.h.

Definition at line 358 of file nsFontMetricsWin.h.


The documentation for this class was generated from the following files: