Back to index

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

#include <nsFontMetricsGTK.h>

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

List of all members.

Public Member Functions

 nsFontMetricsGTK ()
virtual ~nsFontMetricsGTK ()
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
NS_DECL_ISUPPORTS 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 GetNormalLineHeight (nscoord &aHeight)
 Returns the normal line height (em height + leading).
NS_IMETHOD GetLeading (nscoord &aLeading)
 Returns the amount of internal leading (in app units) for the font.
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 GetAveCharWidth (nscoord &aAveCharWidth)
 Returns the average character width.
virtual PRInt32 GetMaxStringLength ()
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 GetSpaceWidth (nscoord &aSpaceWidth)
 Returns the often needed width of the space character.
NS_IMETHOD ResolveForwards (const PRUnichar *aString, PRUint32 aLength, nsFontSwitchCallbackGTK aFunc, void *aData)
nsFontGTKFindFont (PRUint32 aChar)
nsFontGTKFindUserDefinedFont (PRUint32 aChar)
nsFontGTKFindStyleSheetSpecificFont (PRUint32 aChar)
nsFontGTKFindStyleSheetGenericFont (PRUint32 aChar)
nsFontGTKFindLangGroupPrefFont (nsIAtom *aLangGroup, PRUint32 aChar)
nsFontGTKFindLangGroupFont (nsIAtom *aLangGroup, PRUint32 aChar, nsCString *aName)
nsFontGTKFindAnyFont (PRUint32 aChar)
nsFontGTKFindSubstituteFont (PRUint32 aChar)
nsFontGTKSearchNode (nsFontNode *aNode, PRUint32 aChar)
nsFontGTKTryAliases (nsCString *aName, PRUint32 aChar)
nsFontGTKTryFamily (nsCString *aName, PRUint32 aChar)
nsFontGTKTryNode (nsCString *aName, PRUint32 aChar)
nsFontGTKTryNodes (nsACString &aFFREName, PRUint32 aChar)
nsFontGTKTryLangGroup (nsIAtom *aLangGroup, nsCString *aName, PRUint32 aChar)
nsFontGTKAddToLoadedFontsList (nsFontGTK *aFont)
nsFontGTKFindNearestSize (nsFontStretch *aStretch, PRUint16 aSize)
nsFontGTKGetAASBBaseFont (nsFontStretch *aStretch, nsFontCharSetInfo *aCharSet)
nsFontGTKPickASizeAndLoad (nsFontStretch *aStretch, nsFontCharSetInfo *aCharSet, PRUint32 aChar, const char *aName)
virtual nsresult GetWidth (const char *aString, PRUint32 aLength, nscoord &aWidth, nsRenderingContextGTK *aContext)
virtual nsresult GetWidth (const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, PRInt32 *aFontID, nsRenderingContextGTK *aContext)
virtual nsresult GetTextDimensions (const PRUnichar *aString, PRUint32 aLength, nsTextDimensions &aDimensions, PRInt32 *aFontID, nsRenderingContextGTK *aContext)
virtual nsresult GetTextDimensions (const char *aString, PRInt32 aLength, PRInt32 aAvailWidth, PRInt32 *aBreaks, PRInt32 aNumBreaks, nsTextDimensions &aDimensions, PRInt32 &aNumCharsFit, nsTextDimensions &aLastWordDimensions, PRInt32 *aFontID, nsRenderingContextGTK *aContext)
virtual nsresult GetTextDimensions (const PRUnichar *aString, PRInt32 aLength, PRInt32 aAvailWidth, PRInt32 *aBreaks, PRInt32 aNumBreaks, nsTextDimensions &aDimensions, PRInt32 &aNumCharsFit, nsTextDimensions &aLastWordDimensions, PRInt32 *aFontID, nsRenderingContextGTK *aContext)
virtual nsresult DrawString (const char *aString, PRUint32 aLength, nscoord aX, nscoord aY, const nscoord *aSpacing, nsRenderingContextGTK *aContext, nsDrawingSurfaceGTK *aSurface)
virtual nsresult DrawString (const PRUnichar *aString, PRUint32 aLength, nscoord aX, nscoord aY, PRInt32 aFontID, const nscoord *aSpacing, nsRenderingContextGTK *aContext, nsDrawingSurfaceGTK *aSurface)
virtual GdkFont * GetCurrentGDKFont (void)
virtual nsresult SetRightToLeftText (PRBool aIsRTL)
virtual PRBool GetRightToLeftText ()
virtual nsresult GetClusterInfo (const PRUnichar *aText, PRUint32 aLength, PRUint8 *aClusterStarts)
virtual PRInt32 GetPosition (const PRUnichar *aText, PRUint32 aLength, nsPoint aPt)
virtual nsresult GetRangeWidth (const PRUnichar *aText, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd, PRUint32 &aWidth)
virtual nsresult GetRangeWidth (const char *aText, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd, PRUint32 &aWidth)
const nsFontFont ()
 Returns the font associated with these metrics.

Static Public Member Functions

static nsresult FamilyExists (nsIDeviceContext *aDevice, const nsString &aName)
static PRUint32 GetHints (void)

Public Attributes

nsFontGTK ** mLoadedFonts
PRUint16 mLoadedFontsAlloc
PRUint16 mLoadedFontsCount
nsFontGTKmSubstituteFont
nsCStringArray mFonts
PRInt32 mFontsIndex
nsAutoVoidArray mFontIsGeneric
nsCAutoString mDefaultFont
nsCStringmGeneric
nsCOMPtr< nsIAtommLangGroup
nsCAutoString mUserDefined
PRUint8 mTriedAllGenerics
PRUint8 mIsUserDefined

Protected Member Functions

void RealizeFont ()
nsFontGTKLocateFont (PRUint32 aChar, PRInt32 &aCount)

Protected Attributes

nsIDeviceContextmDeviceContext
nsFontGTKmWesternFont
nsFontGTKmCurrentFont
nscoord mLeading
nscoord mEmHeight
nscoord mEmAscent
nscoord mEmDescent
nscoord mMaxHeight
nscoord mMaxAscent
nscoord mMaxDescent
nscoord mMaxAdvance
nscoord mXHeight
nscoord mSuperscriptOffset
nscoord mSubscriptOffset
nscoord mStrikeoutSize
nscoord mStrikeoutOffset
nscoord mUnderlineSize
nscoord mUnderlineOffset
nscoord mSpaceWidth
nscoord mAveCharWidth
PRInt32 mMaxStringLength
PRUint16 mPixelSize
PRUint8 mStretchIndex
PRUint8 mStyleIndex
nsFontCharSetConverter mDocConverterType
nsFont mFont

Detailed Description

Definition at line 227 of file nsFontMetricsGTK.h.


Constructor & Destructor Documentation

Definition at line 1512 of file nsFontMetricsGTK.cpp.

  : mFonts() // I'm not sure what the common size is here - I generally
  // see 2-5 entries.  For now, punt and let it be allocated later.  We can't
  // make it an nsAutoVoidArray since it's a cString array.
  // XXX mFontIsGeneric will generally need to be the same size; right now
  // it's an nsAutoVoidArray.  If the average is under 8, that's ok.
{
  gFontMetricsGTKCount++;
}

Definition at line 1522 of file nsFontMetricsGTK.cpp.

{
  // do not free mGeneric here

  if (mLoadedFonts) {
    PR_Free(mLoadedFonts);
    mLoadedFonts = nsnull;
  }

  if (mSubstituteFont) {
    delete mSubstituteFont;
    mSubstituteFont = nsnull;
  }

  mWesternFont = nsnull;
  mCurrentFont = nsnull;

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

  if (!--gFontMetricsGTKCount) {
    FreeGlobals();
  }
}

Here is the call graph for this function:


Member Function Documentation

Definition at line 3309 of file nsFontMetricsGTK.cpp.

{
  if (mLoadedFontsCount == mLoadedFontsAlloc) {
    int newSize;
    if (mLoadedFontsAlloc) {
      newSize = (2 * mLoadedFontsAlloc);
    }
    else {
      newSize = 1;
    }
    nsFontGTK** newPointer = (nsFontGTK**) 
      PR_Realloc(mLoadedFonts, newSize * sizeof(nsFontGTK*));
    if (newPointer) {
      mLoadedFonts = newPointer;
      mLoadedFontsAlloc = newSize;
    }
    else {
      return nsnull;
    }
  }
  mLoadedFonts[mLoadedFontsCount++] = aFont;
  return aFont;
}

Here is the call graph for this function:

Here is the caller 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 1709 of file nsFontMetricsGTK.cpp.

{
  mDeviceContext = nsnull;
  return NS_OK;
}
nsresult nsFontMetricsGTK::DrawString ( const char *  aString,
PRUint32  aLength,
nscoord  aX,
nscoord  aY,
const nscoord aSpacing,
nsRenderingContextGTK aContext,
nsDrawingSurfaceGTK aSurface 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 3736 of file nsFontMetricsGTK.cpp.

{
  if (!aLength)
      return NS_ERROR_FAILURE;

  nsresult rv = NS_OK;

  g_return_val_if_fail(aString != NULL, NS_ERROR_FAILURE);
  g_return_val_if_fail(mCurrentFont != NULL, NS_ERROR_FAILURE);

  nscoord x = aX;
  nscoord y = aY;

  aContext->UpdateGC();

  nsXFont *xFont = mCurrentFont->GetXFont();

  // Get the gc - note that we have to unref this later
  GdkGC *gc = aContext->GetGC();

  if (nsnull != aSpacing) {
      // Render the string, one character at a time...
      const char* end = aString + aLength;

      while (aString < end) {
          char ch = *aString++;
          nscoord xx = x;
          nscoord yy = y;
          aContext->GetTranMatrix()->TransformCoord(&xx, &yy);

          if (mCurrentFont->IsFreeTypeFont()) {
              // this function is only supposed to be called for ascii data
              rv = mCurrentFont->DrawString(aContext, aSurface, xx, yy, 
                                 NS_ConvertASCIItoUTF16(aString, aLength).get(),
                                 aLength);
          }
          else if (!mCurrentFont->GetXFontIs10646()) {
              // 8 bit data with an 8 bit font
              NS_ASSERTION(xFont->IsSingleByte(),"wrong string/font size");
              xFont->DrawText8(aSurface->GetDrawable(), gc, xx, yy, &ch, 1);
          }
          else {
              // we have 8 bit data but a 16 bit font
              NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size");
              Widen8To16AndDraw(aSurface->GetDrawable(), xFont, gc,
                                xx, yy, &ch, 1);
          }

          x += *aSpacing++;
      }
  }
  else {
      aContext->GetTranMatrix()->TransformCoord(&x, &y);

      if (mCurrentFont->IsFreeTypeFont()) {
          // this function is only supposed to be called for ascii data
          rv = mCurrentFont->DrawString(aContext, aSurface, x, y, 
                             NS_ConvertASCIItoUTF16(aString, aLength).get(),
                             aLength);
      }
      else if (!mCurrentFont->GetXFontIs10646()) { // keep 8 bit path fast
          // 8 bit data with an 8 bit font
          NS_ASSERTION(xFont->IsSingleByte(),"wrong string/font size");
          xFont->DrawText8(aSurface->GetDrawable(), gc,
                           x, y, aString, aLength);
      }
      else {
          // we have 8 bit data but a 16 bit font
          NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size");
          Widen8To16AndDraw(aSurface->GetDrawable(), xFont, gc,
                            x, y, aString, aLength);
      }
  }

  gdk_gc_unref(gc);

  return rv;
}

Here is the call graph for this function:

nsresult nsFontMetricsGTK::DrawString ( const PRUnichar aString,
PRUint32  aLength,
nscoord  aX,
nscoord  aY,
PRInt32  aFontID,
const nscoord aSpacing,
nsRenderingContextGTK aContext,
nsDrawingSurfaceGTK aSurface 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 3820 of file nsFontMetricsGTK.cpp.

{
    if (!aLength)
        return NS_ERROR_FAILURE;

    g_return_val_if_fail(aSurface != NULL, NS_ERROR_FAILURE);
    g_return_val_if_fail(aString != NULL, NS_ERROR_FAILURE);

    nscoord x = aX;
    nscoord y = aY;

    aContext->GetTranMatrix()->TransformCoord(&x, &y);

    nsFontGTK* prevFont = nsnull;
    PRUint32 start = 0;
    PRUint32 i;

    PRUint32 extraSurrogateLength;
    for (i = 0; i < aLength; i+=1+extraSurrogateLength) {
        PRUint32 c = aString[i];
        extraSurrogateLength=0;
        if(i < aLength-1 && IS_HIGH_SURROGATE(c) && IS_LOW_SURROGATE(aString[i+1])) {
          // if surrogate, make UCS4 code point from high aString[i] and
          // low surrogate aString[i+1]
          c = SURROGATE_TO_UCS4(c, aString[i+1]);
 
          // skip aString[i+1], it is already used as low surrogate
          extraSurrogateLength = 1;
        }
        nsFontGTK* currFont = nsnull;
        nsFontGTK** font = mLoadedFonts;
        nsFontGTK** lastFont = &mLoadedFonts[mLoadedFontsCount];
        while (font < lastFont) {
            if (SAFE_CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) {
                currFont = *font;
                goto FoundFont; // for speed -- avoid "if" statement
            }
            font++;
        }

        currFont = FindFont(c);

    FoundFont:
        // XXX avoid this test by duplicating code -- erik
        if (prevFont) {
            if (currFont != prevFont) {
                if (aSpacing) {
                    const PRUnichar* str = &aString[start];
                    const PRUnichar* end = &aString[i];

                    // save off mCurrentFont and set it so that we
                    // cache the GC's font correctly
                    nsFontGTK *oldFont = mCurrentFont;
                    mCurrentFont = prevFont;
                    aContext->UpdateGC();

                    while (str < end) {
                        x = aX;
                        y = aY;
                        aContext->GetTranMatrix()->TransformCoord(&x, &y);
                        prevFont->DrawString(aContext, aSurface, x, y, str, 1);
                        aX += *aSpacing++;
                        str++;
                    }

                    mCurrentFont = oldFont;
                }
                else {
                    nsFontGTK *oldFont = mCurrentFont;
                    mCurrentFont = prevFont;
                    aContext->UpdateGC();

                    x += prevFont->DrawString(aContext, aSurface,
                                              x, y, &aString[start],
                                              i - start);

                    mCurrentFont = oldFont;
                }

                prevFont = currFont;
                start = i;
            }
        }
        else {
            prevFont = currFont;
            start = i;
        }
    }

    if (prevFont) {
        nsFontGTK *oldFont = mCurrentFont;
        mCurrentFont = prevFont;
        aContext->UpdateGC();
    
        if (aSpacing) {
            const PRUnichar* str = &aString[start];
            const PRUnichar* end = &aString[i];

            while (str < end) {
                x = aX;
                y = aY;
                aContext->GetTranMatrix()->TransformCoord(&x, &y);
                prevFont->DrawString(aContext, aSurface, x, y, str, 1);
                aX += *aSpacing++;
                str++;
            }
        }
        else {
            prevFont->DrawString(aContext, aSurface, x, y,
                                 &aString[start], i - start);
        }

        mCurrentFont = oldFont;
    }

  return NS_OK;
}

Here is the call graph for this function:

Definition at line 5813 of file nsFontMetricsGTK.cpp.

{
  if (!gInitialized) {
    nsresult res = InitGlobals(aDevice);
    if (NS_FAILED(res))
      return res;
  }

  if (!IsASCIIFontName(aName)) {
    return NS_ERROR_FAILURE;
  }

  nsCAutoString name;
  name.AssignWithConversion(aName.get());
  ToLowerCase(name);
  nsFontFamily* family = FindFamily(&name);
  if (family && family->mNodes.Count()) {
    return NS_OK;
  }

  return NS_ERROR_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6335 of file nsFontMetricsGTK.cpp.

{
  FIND_FONT_PRINTF(("    FindAnyFont"));
  // XXX If we get to this point, that means that we have exhausted all the
  // families in the lists. Maybe we should try a list of fonts that are
  // specific to the vendor of the X server here. Because XListFonts for the
  // whole list is very expensive on some Unixes.

  /*
   * Try all the fonts on the system.
   */
  nsresult res = GetAllFontNames();
  if (NS_FAILED(res)) {
    return nsnull;
  }

  PRInt32 n = gGlobalList->Count();
  for (PRInt32 i = 0; i < n; i++) {
    nsFontGTK* font = SearchNode(gGlobalList->GetElement(i), aChar);
    if (font && font->SupportsChar(aChar)) {
      // XXX We should probably write this family name out to disk, so that
      // we can use it next time. I.e. prefs file or something.
      return font;
    }
  }

  // future work:
  // to properly support the substitute font we
  // need to indicate here that all fonts have been tried
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6555 of file nsFontMetricsGTK.cpp.

{
  FIND_FONT_PRINTF(("\nFindFont(%c/0x%04x)", aChar, aChar));

  // If this is is the 'unknown' char (ie: converter could not 
  // convert it) there is no sense in searching any further for 
  // a font. Just returing mWesternFont
  if (aChar == UCS2_REPLACEMENT_CHAR) {
    FIND_FONT_PRINTF(("      ignore the 'UCS2_REPLACEMENT_CHAR' character, return mWesternFont"));
    return mWesternFont;
  }

  nsFontGTK* font = FindUserDefinedFont(aChar);
  if (!font) {
    font = FindStyleSheetSpecificFont(aChar);
    if (!font) {
      font = FindStyleSheetGenericFont(aChar);
      if (!font) {
        font = FindAnyFont(aChar);
        if (!font) {
          font = FindSubstituteFont(aChar);
        }
      }
    }
  }

#ifdef NS_FONT_DEBUG_CALL_TRACE
  if (gFontDebug & NS_FONT_DEBUG_CALL_TRACE) {
    printf("FindFont(%04X)[", aChar);
    for (PRInt32 i = 0; i < mFonts.Count(); i++) {
      printf("%s, ", mFonts.CStringAt(i)->get());
    }
    printf("]\nreturns ");
    if (font) {
      printf("%s\n", font->mName ? font->mName : "(substitute)");
    }
    else {
      printf("NULL\n");
    }
  }
#endif

  return font;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontGTK * nsFontMetricsGTK::FindLangGroupFont ( nsIAtom aLangGroup,
PRUint32  aChar,
nsCString aName 
)

Definition at line 6475 of file nsFontMetricsGTK.cpp.

{
  nsFontGTK* font;

  FIND_FONT_PRINTF(("      lang group = %s", atomToName(aLangGroup)));

  //  scan gCharSetMap for encodings with matching lang groups
  nsFontCharSetMap* charSetMap;
  for (charSetMap=gCharSetMap; charSetMap->mName; charSetMap++) {
    nsFontLangGroup* fontLangGroup = charSetMap->mFontLangGroup;

    if ((!fontLangGroup) || (!fontLangGroup->mFontLangGroupName)) {
      continue;
    }

    if (!charSetMap->mInfo->mLangGroup) {
      SetCharsetLangGroup(charSetMap->mInfo);
    }

    if (!fontLangGroup->mFontLangGroupAtom) {
      SetFontLangGroupInfo(charSetMap);
    }

    // if font's langGroup is different from requested langGroup, continue.
    // An exception is that font's langGroup ZHTWHK is regarded as matching
    // both ZHTW and ZHHK (Freetype2 and Solaris).
    if ((aLangGroup != fontLangGroup->mFontLangGroupAtom) &&
        (aLangGroup != charSetMap->mInfo->mLangGroup) &&
        (fontLangGroup->mFontLangGroupAtom != gZHTWHK || 
        (aLangGroup != gZHHK && aLangGroup != gZHTW))) {
      continue;
    }
    // look for a font with this charset (registry-encoding) & char
    //
    nsCAutoString ffreName;
    if(aName) {
      // if aName was specified so call TryNode() not TryNodes()
      ffreName.Assign(*aName);
      FFRESubstituteCharset(ffreName, charSetMap->mName); 
      FIND_FONT_PRINTF(("      %s ffre = %s", charSetMap->mName, ffreName.get()));
      if(aName->First() == '*') {
         // called from TryFamily()
         font = TryNodes(ffreName, aChar);
      } else {
         font = TryNode(&ffreName, aChar);
      }
      NS_ASSERTION(font ? font->SupportsChar(aChar) : 1, "font supposed to support this char");
    } else {
      // no name was specified so call TryNodes() for this charset
      ffreName.Assign("*-*-*-*");
      FFRESubstituteCharset(ffreName, charSetMap->mName); 
      FIND_FONT_PRINTF(("      %s ffre = %s", charSetMap->mName, ffreName.get()));
      font = TryNodes(ffreName, aChar);
      NS_ASSERTION(font ? font->SupportsChar(aChar) : 1, "font supposed to support this char");
    }
    if (font) {
      NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
      return font;
    }
  }

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6406 of file nsFontMetricsGTK.cpp.

{ 
  nsFontGTK* font;
  //
  // get the font specified in prefs
  //
  nsCAutoString prefix("font.name."); 
  prefix.Append(*mGeneric); 
  if (aLangGroup) { 
    // check user set pref
    nsCAutoString pref = prefix;
    pref.Append(char('.'));
    const char* langGroup = nsnull;
    aLangGroup->GetUTF8String(&langGroup);
    pref.Append(langGroup);
    nsXPIDLCString value;
    gPref->CopyCharPref(pref.get(), getter_Copies(value));
    nsCAutoString str;
    nsCAutoString str_user;
    if (value.get()) {
      str = value.get();
      str_user = value.get();
      FIND_FONT_PRINTF(("      user pref %s = %s", pref.get(), str.get()));
      font = TryNode(&str, aChar);
      if (font) {
        NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
        return font;
      }
      font = TryLangGroup(aLangGroup, &str, aChar);
      if (font) {
        NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
        return font;
      }
    }
    // check factory set pref
    gPref->CopyDefaultCharPref(pref.get(), getter_Copies(value));
    if (value.get()) {
      str = value.get();
      // check if we already tried this name
      if (str != str_user) {
        FIND_FONT_PRINTF(("      default pref %s = %s", pref.get(), str.get()));
        font = TryNode(&str, aChar);
        if (font) {
          NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
          return font;
        }
        font = TryLangGroup(aLangGroup, &str, aChar);
        if (font) {
          NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
          return font;
        }
      }
    }
  }

  //
  // find any style font based on lang group
  //
  FIND_FONT_PRINTF(("      find font based on lang group"));
  font = FindLangGroupFont(aLangGroup, aChar, nsnull);
  if (font) {
    NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
    return font;
  }

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3338 of file nsFontMetricsGTK.cpp.

{
  nsFontGTK* font = nsnull;
  if (aStretch->mSizes) {
    nsFontGTK** begin = aStretch->mSizes;
    nsFontGTK** end = &aStretch->mSizes[aStretch->mSizesCount];
    nsFontGTK** s;
    // scan the list of sizes
    for (s = begin; s < end; s++) {
      // stop when we hit or overshoot the size
      if ((*s)->mSize >= aSize) {
        break;
      }
    }
    // backup if we hit the end of the list
    if (s == end) {
      s--;
    }
    else if (s != begin) {
      // if we overshot pick the closest size
      if (((*s)->mSize - aSize) >= (aSize - (*(s - 1))->mSize)) {
        s--;
      }
    }
    // this is the nearest bitmap font
    font = *s;
  }
  return font;
}

Here is the caller graph for this function:

Definition at line 6203 of file nsFontMetricsGTK.cpp.

{
  FIND_FONT_PRINTF(("    FindStyleSheetGenericFont"));
  nsFontGTK* font;

  if (mTriedAllGenerics) {
    return nsnull;
  }

  //
  // find font based on document's lang group
  //
  font = FindLangGroupPrefFont(mLangGroup, aChar);
  if (font) {
    NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
    return font;
  }

  //
  // Asian smart quote glyphs are much too large for western
  // documents so if this is a single byte document add a
  // special "font" to tranliterate those chars rather than
  // possibly find them in double byte fonts
  //
  // (risk management: since we are close to a ship point we have a 
  //  control (gAllowDoubleByteSpecialChars) to disable this new feature)
  //
if (gAllowDoubleByteSpecialChars) {
  if (!mDocConverterType) {
    if (mLoadedFontsCount) {
      FIND_FONT_PRINTF(("just use the 1st converter type"));
      nsFontGTK* first_font = mLoadedFonts[0];
      if (first_font->mCharSetInfo) {
        mDocConverterType = first_font->mCharSetInfo->Convert;
        if (mDocConverterType == SingleByteConvert ) {
          FIND_FONT_PRINTF(("single byte converter for %s", atomToName(mLangGroup)));
        }
        else {
          FIND_FONT_PRINTF(("double byte converter for %s", atomToName(mLangGroup)));
        }
      }
    }
    if (!mDocConverterType) {
      mDocConverterType = SingleByteConvert;
    }
    if (mDocConverterType == SingleByteConvert) {
      // before we put in the transliterator to disable double byte special chars
      // add the x-western font before the early transliterator
      // to get the EURO sign (hack)

      nsFontGTK* western_font = nsnull;
      if (mLangGroup != gWesternLocale)
        western_font = FindLangGroupPrefFont(gWesternLocale, aChar);

      // add the symbol font before the early transliterator
      // to get the bullet (hack)
      nsCAutoString symbol_ffre("*-symbol-adobe-fontspecific");
      nsFontGTK* symbol_font = TryNodes(symbol_ffre, 0x0030);

      // Add the Adobe Euro fonts before the early transliterator
      nsCAutoString euro_ffre("*-euro*-adobe-fontspecific");
      nsFontGTK* euro_font = TryNodes(euro_ffre, 0x20AC);

      // add the early transliterator
      // to avoid getting Japanese "special chars" such as smart
      // since they are very oversized compared to western fonts
      nsFontGTK* sub_font = FindSubstituteFont(aChar);
      NS_ASSERTION(sub_font, "failed to get a special chars substitute font");
      if (sub_font) {
        sub_font->mCCMap = gDoubleByteSpecialCharsCCMap;
        AddToLoadedFontsList(sub_font);
      }
      if (western_font && SAFE_CCMAP_HAS_CHAR_EXT(western_font->mCCMap, aChar)) {
        return western_font;
      }
      else if (symbol_font && SAFE_CCMAP_HAS_CHAR_EXT(symbol_font->mCCMap, aChar)) {
        return symbol_font;
      }
      else if (euro_font && SAFE_CCMAP_HAS_CHAR_EXT(euro_font->mCCMap, aChar)) {
        return euro_font;
      }
      else if (sub_font && SAFE_CCMAP_HAS_CHAR_EXT(sub_font->mCCMap, aChar)) {
        FIND_FONT_PRINTF(("      transliterate special chars for single byte docs"));
        return sub_font;
      }
    }
  }
}

  //
  // find font based on user's locale's lang group
  // if different from documents locale
  if (gUsersLocale != mLangGroup) {
    FIND_FONT_PRINTF(("      find font based on user's locale's lang group"));
    font = FindLangGroupPrefFont(gUsersLocale, aChar);
    if (font) {
      NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
      return font;
    }
  }

  //
  // Search all font prefs for generic
  //
  nsCAutoString prefix("font.name.");
  prefix.Append(*mGeneric);
  nsFontSearch search = { this, aChar, nsnull };
  FIND_FONT_PRINTF(("      Search all font prefs for generic"));
  gPref->EnumerateChildren(prefix.get(), PrefEnumCallback, &search);
  if (search.mFont) {
    NS_ASSERTION(search.mFont->SupportsChar(aChar), "font supposed to support this char");
    return search.mFont;
  }

  //
  // Search all font prefs
  //
  // find based on all prefs (no generic part (eg: sans-serif))
  nsCAutoString allPrefs("font.name.");
  search.mFont = nsnull;
  FIND_FONT_PRINTF(("      Search all font prefs"));
  gPref->EnumerateChildren(allPrefs.get(), PrefEnumCallback, &search);
  if (search.mFont) {
    NS_ASSERTION(search.mFont->SupportsChar(aChar), "font supposed to support this char");
    return search.mFont;
  }

  mTriedAllGenerics = 1;
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6101 of file nsFontMetricsGTK.cpp.

{
  FIND_FONT_PRINTF(("    FindStyleSheetSpecificFont"));
  while (mFontsIndex < mFonts.Count()) {
    if (mFontIsGeneric[mFontsIndex]) {
      return nsnull;
    }
    nsCString* familyName = mFonts.CStringAt(mFontsIndex);

    /*
     * count hyphens
     * XXX It might be good to try to pre-cache this information instead
     * XXX of recalculating it on every font access!
     */
    const char* str = familyName->get();
    FIND_FONT_PRINTF(("        familyName = %s", str));
    PRUint32 len = familyName->Length();
    int hyphens = 0;
    for (PRUint32 i = 0; i < len; i++) {
      if (str[i] == '-') {
        hyphens++;
      }
    }

    /*
     * if there are 3 hyphens, the name is in FFRE form
     * (foundry-family-registry-encoding)
     * ie: something like this:
     *
     *   adobe-times-iso8859-1
     *
     * otherwise it is something like
     *
     *   times new roman
     */
    nsFontGTK* font;
    if (hyphens == 3) {
      font = TryNode(familyName, aChar);
      if (font) {
        NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
        return font;
      }
    }
    else {
      font = TryFamily(familyName, aChar);
      if (font) {
        NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
        return font;
      }
      font = TryAliases(familyName, aChar);
      if (font) {
        NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
        return font;
      }
    }
    // bug 42917: increment only after all of the above fails
    mFontsIndex++;
  }

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6368 of file nsFontMetricsGTK.cpp.

{
  if (!mSubstituteFont) {
    for (int i = 0; i < mLoadedFontsCount; i++) {
      if (SAFE_CCMAP_HAS_CHAR_EXT(mLoadedFonts[i]->mCCMap, 'a')) {
        mSubstituteFont = new nsFontGTKSubstitute(mLoadedFonts[i]);
        break;
      }
    }
    // Currently the substitute font does not have a glyph map.
    // This means that even if we have already checked all fonts
    // for a particular character the mLoadedFonts will not know it.
    // Thus we reparse *all* font glyph maps every time we see
    // a character that ends up using a substitute font.
    // future work:
    // create an empty mCCMap and every time we determine a
    // character will get its "glyph" from the substitute font
    // mark that character in the mCCMap.
  }
  // mark the mCCMap to indicate that this character has a "glyph"

  // If we know that mLoadedFonts has every font's glyph map loaded
  // then we can now set all the bit in the substitute font's glyph map
  // and thus direct all umapped characters to the substitute
  // font (without the font search).
  // if tried all glyphs {
  //   create a substitute font with all bits set
  //   set all bits in mCCMap
  // }

  return mSubstituteFont;
}

Here is the caller graph for this function:

Definition at line 6085 of file nsFontMetricsGTK.cpp.

{
  if (mIsUserDefined) {
    FIND_FONT_PRINTF(("        FindUserDefinedFont"));
    nsFontGTK* font = TryNode(&mUserDefined, aChar);
    mIsUserDefined = PR_FALSE;
    if (font) {
      NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
      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:

Definition at line 3410 of file nsFontMetricsGTK.cpp.

{
  nsFontGTK* base_aafont;
  PRInt32 scale_size;
  PRUint32 aa_target_size;

  scale_size = PR_MAX(mPixelSize, aCharSet->mAABitmapScaleMin);
  aa_target_size = MAX((scale_size*2), 16);
  base_aafont = FindNearestSize(aStretch, aa_target_size);
  NS_ASSERTION(base_aafont,
             "failed to find a base font for Anti-Aliased bitmap Scaling");
  return base_aafont;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Returns the average character width.

Implements nsIFontMetrics.

Definition at line 2021 of file nsFontMetricsGTK.cpp.

{
  aAveCharWidth = mAveCharWidth;
  return NS_OK;
}

Here is the caller graph for this function:

nsresult nsFontMetricsGTK::GetClusterInfo ( const PRUnichar aText,
PRUint32  aLength,
PRUint8 aClusterStarts 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 4783 of file nsFontMetricsGTK.cpp.

GdkFont * nsFontMetricsGTK::GetCurrentGDKFont ( void  ) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 4765 of file nsFontMetricsGTK.cpp.

{
  return mCurrentFont->GetGDKFont();
}

Here is the call graph for this function:

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

Implements nsIFontMetrics.

Definition at line 1985 of file nsFontMetricsGTK.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 1991 of file nsFontMetricsGTK.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 1979 of file nsFontMetricsGTK.cpp.

{
  aHeight = mEmHeight;
  return NS_OK;
}

Returns the font handle associated with these metrics.

Implements nsIFontMetrics.

Definition at line 2044 of file nsFontMetricsGTK.cpp.

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 1961 of file nsFontMetricsGTK.cpp.

{
  aHeight = mMaxHeight;
  return NS_OK;
}

Definition at line 5837 of file nsFontMetricsGTK.cpp.

{
  PRUint32 result = 0;

  /* We can't enable fast text measuring (yet) on platforms which
   * force natural alignment of datatypes (see
   * http://bugzilla.mozilla.org/show_bug.cgi?id=36146#c46) ... ;-(
   */

#ifndef CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT
#if defined(__i386)
#define CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT 1
#endif /* __i386 */
#endif /* !CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT */

  static PRBool enable_fast_measure;
  static PRBool getenv_done = PR_FALSE;
    
  /* Check for the env vars "MOZILLA_GFX_ENABLE_FAST_MEASURE" and
   * "MOZILLA_GFX_DISABLE_FAST_MEASURE" to enable/disable fast text
   * measuring (for debugging the feature and doing regression tests).
   * This code will be removed one all issues around this new feature
   * have been fixed. */
  if (!getenv_done) {
#ifdef CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT
    enable_fast_measure = PR_TRUE;
#else
    enable_fast_measure = PR_FALSE;
#endif /* CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT */

    if (PR_GetEnv("MOZILLA_GFX_ENABLE_FAST_MEASURE"))
      enable_fast_measure = PR_TRUE;

    if (PR_GetEnv("MOZILLA_GFX_DISABLE_FAST_MEASURE"))
      enable_fast_measure = PR_FALSE;
        
    getenv_done = PR_TRUE;
  }

  if (enable_fast_measure) {
    // We have GetTextDimensions()
    result |= NS_RENDERING_HINT_FAST_MEASURE;
  }

  return result;
}

Here is the caller graph for this function:

Returns the language group associated with these metrics.

Implements nsIFontMetrics.

Definition at line 2032 of file nsFontMetricsGTK.cpp.

{
  if (!aLangGroup) {
    return NS_ERROR_NULL_POINTER;
  }

  *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 1973 of file nsFontMetricsGTK.cpp.

{
  aLeading = mLeading;
  return NS_OK;
}

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

Implements nsIFontMetrics.

Definition at line 2015 of file nsFontMetricsGTK.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 2003 of file nsFontMetricsGTK.cpp.

{
  aAscent = mMaxAscent;
  return NS_OK;
}

Here is the caller graph for this function:

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

Implements nsIFontMetrics.

Definition at line 2009 of file nsFontMetricsGTK.cpp.

{
  aDescent = mMaxDescent;
  return NS_OK;
}

Here is the caller graph for this function:

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 1997 of file nsFontMetricsGTK.cpp.

{
  aHeight = mMaxHeight;
  return NS_OK;
}

Implements nsIFontMetricsGTK.

Definition at line 2027 of file nsFontMetricsGTK.cpp.

{
  return mMaxStringLength;
}

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

Implements nsIFontMetrics.

Definition at line 1967 of file nsFontMetricsGTK.cpp.

{
  aHeight = mEmHeight + mLeading;
  return NS_OK;
}
PRInt32 nsFontMetricsGTK::GetPosition ( const PRUnichar aText,
PRUint32  aLength,
nsPoint  aPt 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 4791 of file nsFontMetricsGTK.cpp.

{
    return -1;
}
nsresult nsFontMetricsGTK::GetRangeWidth ( const PRUnichar aText,
PRUint32  aLength,
PRUint32  aStart,
PRUint32  aEnd,
PRUint32 aWidth 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 4800 of file nsFontMetricsGTK.cpp.

nsresult nsFontMetricsGTK::GetRangeWidth ( const char *  aText,
PRUint32  aLength,
PRUint32  aStart,
PRUint32  aEnd,
PRUint32 aWidth 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 4810 of file nsFontMetricsGTK.cpp.

Implements nsIFontMetricsGTK.

Definition at line 4777 of file nsFontMetricsGTK.cpp.

{
    return PR_FALSE;
}
NS_IMETHODIMP nsFontMetricsGTK::GetSpaceWidth ( nscoord aSpaceCharWidth) [virtual]

Returns the often needed width of the space character.

Implements nsIFontMetrics.

Definition at line 2151 of file nsFontMetricsGTK.cpp.

{
  aSpaceWidth = mSpaceWidth;
  return NS_OK;
}

Here is the caller graph for this function:

NS_IMETHODIMP nsFontMetricsGTK::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 1947 of file nsFontMetricsGTK.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 1941 of file nsFontMetricsGTK.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 1935 of file nsFontMetricsGTK.cpp.

nsresult nsFontMetricsGTK::GetTextDimensions ( const PRUnichar aString,
PRUint32  aLength,
nsTextDimensions aDimensions,
PRInt32 aFontID,
nsRenderingContextGTK aContext 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 4097 of file nsFontMetricsGTK.cpp.

{
    aDimensions.Clear();

    if (!aString || !aLength)
        return NS_ERROR_FAILURE;

    nsFontGTK* prevFont = nsnull;
    gint rawWidth = 0, rawAscent = 0, rawDescent = 0;
    PRUint32 start = 0;
    PRUint32 i;

    PRUint32 extraSurrogateLength;
    for (i = 0; i < aLength; i+=1+extraSurrogateLength) {
        PRUint32 c = aString[i];
        extraSurrogateLength=0;
        if(i < aLength-1 && IS_HIGH_SURROGATE(c) && IS_LOW_SURROGATE(aString[i+1])) {
          // if surrogate, make UCS4 code point from high aString[i] and
          // low surrogate aString[i+1]
          c = SURROGATE_TO_UCS4(c, aString[i+1]);
 
          // skip aString[i+1], it is already used as low surrogate
          extraSurrogateLength = 1;
        }
        nsFontGTK* currFont = nsnull;
        nsFontGTK** font = mLoadedFonts;
        nsFontGTK** end = &mLoadedFonts[mLoadedFontsCount];

        while (font < end) {
            if (SAFE_CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) {
                currFont = *font;
                goto FoundFont; // for speed -- avoid "if" statement
            }
            font++;
        }
        currFont = FindFont(c);

    FoundFont:
        // XXX avoid this test by duplicating code -- erik
        if (prevFont) {
            if (currFont != prevFont) {
                rawWidth += prevFont->GetWidth(&aString[start], i - start);
                if (rawAscent < prevFont->mMaxAscent)
                    rawAscent = prevFont->mMaxAscent;
                if (rawDescent < prevFont->mMaxDescent)
                    rawDescent = prevFont->mMaxDescent;
                prevFont = currFont;
                start = i;
            }
        }
        else {
            prevFont = currFont;
            start = i;
        }
    }

    if (prevFont) {
        rawWidth += prevFont->GetWidth(&aString[start], i - start);
        if (rawAscent < prevFont->mMaxAscent)
            rawAscent = prevFont->mMaxAscent;
        if (rawDescent < prevFont->mMaxDescent)
            rawDescent = prevFont->mMaxDescent;
    }

    float P2T;
    P2T = mDeviceContext->DevUnitsToAppUnits();

    aDimensions.width = NSToCoordRound(rawWidth * P2T);
    aDimensions.ascent = NSToCoordRound(rawAscent * P2T);
    aDimensions.descent = NSToCoordRound(rawDescent * P2T);

    if (nsnull != aFontID)
        *aFontID = 0;

    return NS_OK;
}

Here is the call graph for this function:

nsresult nsFontMetricsGTK::GetTextDimensions ( const char *  aString,
PRInt32  aLength,
PRInt32  aAvailWidth,
PRInt32 aBreaks,
PRInt32  aNumBreaks,
nsTextDimensions aDimensions,
PRInt32 aNumCharsFit,
nsTextDimensions aLastWordDimensions,
PRInt32 aFontID,
nsRenderingContextGTK aContext 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 4179 of file nsFontMetricsGTK.cpp.

{
    NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");

    // If we need to back up this state represents the last place
    // we could break. We can use this to avoid remeasuring text
    PRInt32 prevBreakState_BreakIndex = -1; // not known
                                            // (hasn't been computed)
    nscoord prevBreakState_Width = 0; // accumulated width to this point

    // Initialize OUT parameters
    GetMaxAscent(aLastWordDimensions.ascent);
    GetMaxDescent(aLastWordDimensions.descent);
    aLastWordDimensions.width = -1;
    aNumCharsFit = 0;

    // Iterate each character in the string and determine which font to use
    nscoord width = 0;
    PRInt32 start = 0;
    nscoord aveCharWidth;
    GetAveCharWidth(aveCharWidth);

    while (start < aLength) {
      // Estimate how many characters will fit. Do that by
      // diving the available space by the average character
      // width. Make sure the estimated number of characters is
      // at least 1
      PRInt32 estimatedNumChars = 0;

      if (aveCharWidth > 0)
        estimatedNumChars = (aAvailWidth - width) / aveCharWidth;

      if (estimatedNumChars < 1)
        estimatedNumChars = 1;

      // Find the nearest break offset
      PRInt32 estimatedBreakOffset = start + estimatedNumChars;
      PRInt32 breakIndex;
      nscoord numChars;

      // Find the nearest place to break that is less than or equal to
      // the estimated break offset
      if (aLength <= estimatedBreakOffset) {
        // All the characters should fit
        numChars = aLength - start;
        breakIndex = aNumBreaks - 1;
      } 
      else {
        breakIndex = prevBreakState_BreakIndex;
        while (((breakIndex + 1) < aNumBreaks) &&
               (aBreaks[breakIndex + 1] <= estimatedBreakOffset)) {
          ++breakIndex;
        }

        if (breakIndex == prevBreakState_BreakIndex) {
          ++breakIndex; // make sure we advanced past the
          // previous break index
        }

        numChars = aBreaks[breakIndex] - start;
      }

      // Measure the text
      nscoord twWidth = 0;
      if ((1 == numChars) && (aString[start] == ' '))
        GetSpaceWidth(twWidth);
      else if (numChars > 0)
        GetWidth(&aString[start], numChars, twWidth, aContext);

      // See if the text fits
      PRBool  textFits = (twWidth + width) <= aAvailWidth;

      // If the text fits then update the width and the number of
      // characters that fit
      if (textFits) {
        aNumCharsFit += numChars;
        width += twWidth;
        start += numChars;

        // This is a good spot to back up to if we need to so remember
        // this state
        prevBreakState_BreakIndex = breakIndex;
        prevBreakState_Width = width;
      }
      else {
        // See if we can just back up to the previous saved
        // state and not have to measure any text
        if (prevBreakState_BreakIndex > 0) {
          // If the previous break index is just before the
          // current break index then we can use it
          if (prevBreakState_BreakIndex == (breakIndex - 1)) {
            aNumCharsFit = aBreaks[prevBreakState_BreakIndex];
            width = prevBreakState_Width;
            break;
          }
        }

        // We can't just revert to the previous break state
        if (0 == breakIndex) {
          // There's no place to back up to, so even though
          // the text doesn't fit return it anyway
          aNumCharsFit += numChars;
          width += twWidth;
          break;
        }

        // Repeatedly back up until we get to where the text
        // fits or we're all the way back to the first word
        width += twWidth;
        while ((breakIndex >= 1) && (width > aAvailWidth)) {
          twWidth = 0;
          start = aBreaks[breakIndex - 1];
          numChars = aBreaks[breakIndex] - start;

          if ((1 == numChars) && (aString[start] == ' '))
            GetSpaceWidth(twWidth);
          else if (numChars > 0)
            GetWidth(&aString[start], numChars, twWidth,
                     aContext);
          width -= twWidth;
          aNumCharsFit = start;
          breakIndex--;
        }
        break;
      }
    }

    aDimensions.width = width;
    GetMaxAscent(aDimensions.ascent);
    GetMaxDescent(aDimensions.descent);

    return NS_OK;
}

Here is the call graph for this function:

nsresult nsFontMetricsGTK::GetTextDimensions ( const PRUnichar aString,
PRInt32  aLength,
PRInt32  aAvailWidth,
PRInt32 aBreaks,
PRInt32  aNumBreaks,
nsTextDimensions aDimensions,
PRInt32 aNumCharsFit,
nsTextDimensions aLastWordDimensions,
PRInt32 aFontID,
nsRenderingContextGTK aContext 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 4596 of file nsFontMetricsGTK.cpp.

{

    nscoord spaceWidth, aveCharWidth;
    GetSpaceWidth(spaceWidth);
    GetAveCharWidth(aveCharWidth);

    // Note: aBreaks[] is supplied to us so that the first word is
    // located at aString[0 .. aBreaks[0]-1] and more generally, the
    // k-th word is located at aString[aBreaks[k-1]
    // .. aBreaks[k]-1]. Whitespace can be included and each of them
    // counts as a word in its own right.

    // Upon completion of glyph resolution, characters that can be
    // represented with fonts[i] are at offsets[i] .. offsets[i+1]-1

    nsAutoVoidArray fonts, offsets;
    offsets.AppendElement((void*)aString);

    float f;
    f = mDeviceContext->DevUnitsToAppUnits();
    BreakGetTextDimensionsData data = { f, aAvailWidth,
                                        aBreaks, aNumBreaks,
                                        spaceWidth, aveCharWidth,
                                        0, 0, 0, -1, 0, &fonts, &offsets };

    ResolveForwards(aString, aLength, do_BreakGetTextDimensions,
                    &data);

    if (aFontID)
        *aFontID = 0;

    aNumCharsFit = data.mNumCharsFit;
    aDimensions.width = data.mWidth;

    // Post-processing for the ascent and descent:
    //
    // The width of the last word is included in the final width, but
    // its ascent and descent are kept aside for the moment. The
    // problem is that line-breaking may occur _before_ the last word,
    // and we don't want its ascent and descent to interfere. We can
    // re-measure the last word and substract its width
    // later. However, we need a special care for the ascent and
    // descent at the break-point. The idea is to keep the ascent and
    // descent of the last word separate, and let layout consider them
    // later when it has determined that line-breaking doesn't occur
    // before the last word.
    //
    // Therefore, there are two things to do:
    // 1. Determine the ascent and descent up to where line-breaking may occur.
    // 2. Determine the ascent and descent of the remainder.  For
    //   efficiency however, it is okay to bail out early if there is
    //   only one font (in this case, the height of the last word has no
    //   special effect on the total height).

    // aLastWordDimensions.width should be set to -1 to reply that we
    // don't know the width of the last word since we measure multiple
    // words
    aLastWordDimensions.Clear();
    aLastWordDimensions.width = -1;

    PRInt32 count = fonts.Count();
    if (!count)
        return NS_OK;

    nsFontGTK* fontGTK = (nsFontGTK*)fonts[0];
    NS_ASSERTION(fontGTK, "internal error in do_BreakGetTextDimensions");
    aDimensions.ascent = fontGTK->mMaxAscent;
    aDimensions.descent = fontGTK->mMaxDescent;

    // fast path - normal case, quick return if there is only one font
    if (count == 1)
        return NS_OK;

    // get the last break index.
    // If there is only one word, we end up with lastBreakIndex =
    // 0. We don't need to worry about aLastWordDimensions in this
    // case too. But if we didn't return earlier, it would mean that
    // the unique word needs several fonts and we will still have to
    // loop over the fonts to return the final height
    PRInt32 lastBreakIndex = 0;
    while (aBreaks[lastBreakIndex] < aNumCharsFit)
        ++lastBreakIndex;

    const PRUnichar* lastWord = (lastBreakIndex > 0) 
        ? aString + aBreaks[lastBreakIndex-1]
        : aString + aNumCharsFit; // let it point outside to play nice
                                  // with the loop

    // now get the desired ascent and descent information... this is
    // however a very fast loop of the order of the number of
    // additional fonts

    PRInt32 currFont = 0;
    const PRUnichar* pstr = aString;
    const PRUnichar* last = aString + aNumCharsFit;

    while (pstr < last) {
        fontGTK = (nsFontGTK*)fonts[currFont];
        PRUnichar* nextOffset = (PRUnichar*)offsets[++currFont]; 

        // For consistent word-wrapping, we are going to handle the
        // whitespace character with special care because a whitespace
        // character can come from a font different from that of the
        // previous word. If 'x', 'y', 'z', are Unicode points that
        // require different fonts, we want 'xyz <br>' and 'xyz<br>'
        // to have the same height because it gives a more stable
        // rendering, especially when the window is resized at the
        // edge of the word.
        // If we don't do this, a 'tall' trailing whitespace, i.e., if
        // the whitespace happens to come from a font with a bigger
        // ascent and/or descent than all current fonts on the line,
        // this can cause the next lines to be shifted down when the
        // window is slowly resized to fit that whitespace.
        if (*pstr == ' ') {
            // skip pass the whitespace to ignore the height that it
            // may contribute
            ++pstr;
            // get out if we reached the end
            if (pstr == last) {
                break;
            }
            // switch to the next font if we just passed the current font 
            if (pstr == nextOffset) {
                fontGTK = (nsFontGTK*)fonts[currFont];
                nextOffset = (PRUnichar*)offsets[++currFont];
            } 
        }

        // see if the last word intersects with the current font
        // (we are testing for 'nextOffset-1 >= lastWord' since the
        // current font ends at nextOffset-1)
        if (nextOffset > lastWord) {
            if (aLastWordDimensions.ascent < fontGTK->mMaxAscent) {
                aLastWordDimensions.ascent = fontGTK->mMaxAscent;
            }
            if (aLastWordDimensions.descent < fontGTK->mMaxDescent) {
                aLastWordDimensions.descent = fontGTK->mMaxDescent;
            }
        }

        // see if we have not reached the last word yet
        if (pstr < lastWord) {
            if (aDimensions.ascent < fontGTK->mMaxAscent) {
                aDimensions.ascent = fontGTK->mMaxAscent;
            }
            if (aDimensions.descent < fontGTK->mMaxDescent) {
                aDimensions.descent = fontGTK->mMaxDescent;
            }
        }

        // advance to where the next font starts
        pstr = nextOffset;
    }

    return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsFontMetricsGTK::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 1954 of file nsFontMetricsGTK.cpp.

{
  aOffset = mUnderlineOffset;
  aSize = mUnderlineSize;
  return NS_OK;
}
nsresult nsFontMetricsGTK::GetWidth ( const char *  aString,
PRUint32  aLength,
nscoord aWidth,
nsRenderingContextGTK aContext 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 3631 of file nsFontMetricsGTK.cpp.

{
    if (aLength == 0) {
        aWidth = 0;
        return NS_OK;
    }

    nsXFont *xFont = mCurrentFont->GetXFont();
    gint rawWidth;
    
    if (mCurrentFont->IsFreeTypeFont()) {
        // this function is only supposed to be called for ascii data
        rawWidth = mCurrentFont->
          GetWidth(NS_ConvertASCIItoUTF16(aString, aLength).get(), aLength);
    }
    else if (!mCurrentFont->GetXFontIs10646()) {
        NS_ASSERTION(xFont->IsSingleByte(),"wrong string/font size");
        // 8 bit data with an 8 bit font
        rawWidth = xFont->TextWidth8(aString, aLength);
    }
    else {
        NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size");
        // we have 8 bit data but a 16 bit font
        rawWidth = Widen8To16AndGetWidth (mCurrentFont->GetXFont(),
                                          aString, aLength);
    }

    float f;
    f = mDeviceContext->DevUnitsToAppUnits();
    aWidth = NSToCoordRound(rawWidth * f);

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFontMetricsGTK::GetWidth ( const PRUnichar aString,
PRUint32  aLength,
nscoord aWidth,
PRInt32 aFontID,
nsRenderingContextGTK aContext 
) [virtual]

Implements nsIFontMetricsGTK.

Definition at line 3668 of file nsFontMetricsGTK.cpp.

{
    if (aLength == 0) {
        aWidth = 0;
        return NS_OK;
    }

    nsFontGTK* prevFont = nsnull;
    gint rawWidth = 0;
    PRUint32 start = 0;
    PRUint32 i;

    PRUint32 extraSurrogateLength;
    for (i = 0; i < aLength; i+=1+extraSurrogateLength) {
        PRUint32 c = aString[i];
        extraSurrogateLength=0;

        if(i < aLength-1 && IS_HIGH_SURROGATE(c) && IS_LOW_SURROGATE(aString[i+1])) {
          // if surrogate, make UCS4 code point from high aString[i] and
          // low surrogate aString[i+1]
          c = SURROGATE_TO_UCS4(c, aString[i+1]);

          // skip aString[i+1], it is already used as low surrogate
          extraSurrogateLength = 1;
        }
        nsFontGTK* currFont = nsnull;
        nsFontGTK** font = mLoadedFonts;
        nsFontGTK** end = &mLoadedFonts[mLoadedFontsCount];
        while (font < end) {
            if (SAFE_CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) {
                currFont = *font;
                goto FoundFont; // for speed -- avoid "if" statement
            }
            font++;
        }
        currFont = FindFont(c);
    FoundFont:
        // XXX avoid this test by duplicating code -- erik
        if (prevFont) {
            if (currFont != prevFont) {
                rawWidth += prevFont->GetWidth(&aString[start], i - start);
                prevFont = currFont;
                start = i;
            }
        }
        else {
            prevFont = currFont;
            start = i;
        }
    }

    if (prevFont) {
        rawWidth += prevFont->GetWidth(&aString[start], i - start);
    }

    float f;
    f = mDeviceContext->DevUnitsToAppUnits();
    aWidth = NSToCoordRound(rawWidth * f);

    if (nsnull != aFontID)
        *aFontID = 0;

    return NS_OK;
}

Here is the call graph for this function:

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

Implements nsIFontMetrics.

Definition at line 1929 of file nsFontMetricsGTK.cpp.

{
  aResult = mXHeight;
  return NS_OK;
}
NS_IMETHODIMP nsFontMetricsGTK::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 1596 of file nsFontMetricsGTK.cpp.

{
  NS_ASSERTION(!(nsnull == aContext), "attempt to init fontmetrics with null device context");

  nsresult res = NS_OK;
  mDocConverterType = nsnull;

  if (!gInitialized) {
    res = InitGlobals(aContext);
    if (NS_FAILED(res))
      return res;
  }

  mFont = aFont;
  mLangGroup = aLangGroup;

  mDeviceContext = aContext;

  float app2dev;
  app2dev = mDeviceContext->AppUnitsToDevUnits();

  mPixelSize = NSToIntRound(app2dev * mFont.size);
  // Make sure to clamp the pixel size to something reasonable so we
  // don't make the X server blow up.
  mPixelSize = PR_MIN((gdk_screen_height() - 1) * FONT_MAX_FONT_SCALE, mPixelSize);
  mPixelSize = PR_MIN(2000, mPixelSize);

  mStretchIndex = 4; // normal
  mStyleIndex = mFont.style;

  mFont.EnumerateFamilies(FontEnumCallback, this);
  nsXPIDLCString value;
  const char* langGroup;
  mLangGroup->GetUTF8String(&langGroup);
  if (!mGeneric) {
    nsCAutoString name("font.default.");
    name.Append(langGroup);
    gPref->CopyCharPref(name.get(), getter_Copies(value));
    if (value.get()) {
      mDefaultFont = value.get();
    }
    else {
      mDefaultFont = "serif";
    }
    mGeneric = &mDefaultFont;
  }

  if (mLangGroup) {
    nsCAutoString name("font.min-size.");
    if (mGeneric->Equals("monospace")) {
      name.Append("fixed");
    }
    else {
      name.Append("variable");
    }
    name.Append(char('.'));
    name.Append(langGroup);
    PRInt32 minimum = 0;
    res = gPref->GetIntPref(name.get(), &minimum);
    if (NS_FAILED(res)) {
      gPref->GetDefaultIntPref(name.get(), &minimum);
    }
    if (minimum < 0) {
      minimum = 0;
    }
    if (mPixelSize < minimum) {
      mPixelSize = minimum;
    }
  }

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

    nsCAutoString name("font.name.");
    name.Append(*mGeneric);
    name.Append(char('.'));
    name.Append(USER_DEFINED);
    gPref->CopyCharPref(name.get(), getter_Copies(value));
    if (value.get()) {
      mUserDefined = value.get();
      mIsUserDefined = 1;
    }
  }

  mWesternFont = FindFont('a');
  if (!mWesternFont) {
    return NS_ERROR_FAILURE;
  }


  mCurrentFont = mWesternFont;

  RealizeFont();

  return NS_OK;
}

Here is the call graph for this function:

nsFontGTK * nsFontMetricsGTK::LocateFont ( PRUint32  aChar,
PRInt32 aCount 
) [protected]

Definition at line 2050 of file nsFontMetricsGTK.cpp.

{
  nsFontGTK *font;
  PRInt32 i;

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

  font = FindFont(aChar);
  aCount = mLoadedFontsCount; // update since FindFont() can change it

  return font;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontGTK * nsFontMetricsGTK::PickASizeAndLoad ( nsFontStretch aStretch,
nsFontCharSetInfo aCharSet,
PRUint32  aChar,
const char *  aName 
)

Definition at line 3426 of file nsFontMetricsGTK.cpp.

{

#ifdef MOZ_ENABLE_FREETYPE2
  if (aStretch->mFreeTypeFaceID) {
    //FREETYPE_FONT_PRINTF(("mFreeTypeFaceID = 0x%p", aStretch->mFreeTypeFaceID));
    nsFreeTypeFont *ftfont = nsFreeTypeFont::NewFont(aStretch->mFreeTypeFaceID,
                                                     mPixelSize,
                                                     aName);
    if (!ftfont) {
      FREETYPE_FONT_PRINTF(("failed to create font"));
      return nsnull;
    }
    //FREETYPE_FONT_PRINTF(("created ftfont"));
    /*
     * XXX Instead of passing pixel size, we ought to take underline
     * into account. (Extra space for underline for Asian fonts.)
     */
    ftfont->mName = PR_smprintf("%s", aName);
    if (!ftfont->mName) {
      FREETYPE_FONT_PRINTF(("failed to create mName"));
      delete ftfont;
      return nsnull;
    }
    SetCharsetLangGroup(aCharSet);
    ftfont->mSize = mPixelSize;
    ftfont->LoadFont();
    ftfont->mCharSetInfo = &ISO106461;
    //FREETYPE_FONT_PRINTF(("add the ftfont"));
    return AddToLoadedFontsList(ftfont);
  }

  if (!IS_IN_BMP(aChar)) {
    // Non-BMP is only supported by FreeType
    return nsnull;
  }
#endif

  PRBool use_scaled_font = PR_FALSE;
  PRBool have_nearly_rightsized_bitmap = PR_FALSE;
  nsFontGTK* base_aafont = nsnull;

  PRInt32 bitmap_size = NOT_FOUND_FONT_SIZE;
  PRInt32 scale_size = mPixelSize;
  nsFontGTK* font = FindNearestSize(aStretch, mPixelSize);
  if (font) {
    bitmap_size = font->mSize;
    if (   (bitmap_size >= mPixelSize-(mPixelSize/10))
        && (bitmap_size <= mPixelSize+(mPixelSize/10)))
      // When the size of a hand tuned font is close to the desired size
      // favor it over outline scaled font
      have_nearly_rightsized_bitmap = PR_TRUE;
  }

  //
  // If the user says always try to aasb (anti alias scaled bitmap) scale
  //
  if (gAABitmapScaleEnabled && aCharSet->mAABitmapScaleAlways) {
    base_aafont = GetAASBBaseFont(aStretch, aCharSet);
    if (base_aafont) {
      use_scaled_font = PR_TRUE;
      SIZE_FONT_PRINTF(("anti-aliased bitmap scaled font: %s\n"
            "                    desired=%d, aa-scaled=%d, bitmap=%d, "
            "aa_bitmap=%d",
            aName, mPixelSize, scale_size, bitmap_size, base_aafont->mSize));
    }
  }

  //
  // if not already aasb scaling and
  // if we do not have a bitmap that is nearly the correct size 
  //
  if (!use_scaled_font && !have_nearly_rightsized_bitmap) {
    // check if we can use an outline scaled font
    if (aStretch->mOutlineScaled) {
      scale_size = PR_MAX(mPixelSize, aCharSet->mOutlineScaleMin);

      if (PR_ABS(mPixelSize-scale_size) < PR_ABS(mPixelSize-bitmap_size)) {
        use_scaled_font = 1;
        SIZE_FONT_PRINTF(("outline font:______ %s\n"
                  "                    desired=%d, scaled=%d, bitmap=%d", 
                  aStretch->mScalable, mPixelSize, scale_size,
                  (bitmap_size=NOT_FOUND_FONT_SIZE?0:bitmap_size)));
      }
    }
    // see if we can aasb (anti alias scaled bitmap)
    if (!use_scaled_font 
        && (bitmap_size<NOT_FOUND_FONT_SIZE) && gAABitmapScaleEnabled) {
      // if we do not have a near-the-right-size font or scalable font
      // see if we can anti-alias bitmap scale one
      scale_size = PR_MAX(mPixelSize, aCharSet->mAABitmapScaleMin);
      double ratio = (bitmap_size / ((double) mPixelSize));
      if (   (ratio < aCharSet->mAABitmapUndersize)
          || (ratio > aCharSet->mAABitmapOversize)) {
        //
        // Try to get a size font to scale that is 2x larger 
        // (but at least 16 pixel)
        //
        base_aafont = GetAASBBaseFont(aStretch, aCharSet);
        if (base_aafont) {
          use_scaled_font = PR_TRUE;
          SIZE_FONT_PRINTF(("anti-aliased bitmap scaled font: %s\n"
              "                    desired=%d, aa-scaled=%d, bitmap=%d, "
              "aa_bitmap=%d",
              aName, mPixelSize, scale_size, bitmap_size, base_aafont->mSize));
        }
      }
    }
    // last resort: consider a bitmap scaled font (ugly!)
    if (!use_scaled_font && aStretch->mScalable) {
      scale_size = PR_MAX(mPixelSize, aCharSet->mBitmapScaleMin);
      double ratio = (bitmap_size / ((double) mPixelSize));
      if ((ratio < aCharSet->mBitmapUndersize)
        || (ratio > aCharSet->mBitmapOversize)) {
        if ((PR_ABS(mPixelSize-scale_size) < PR_ABS(mPixelSize-bitmap_size))) {
          use_scaled_font = 1;
          SIZE_FONT_PRINTF(("bitmap scaled font: %s\n"
                "                    desired=%d, scaled=%d, bitmap=%d", 
                aStretch->mScalable, mPixelSize, scale_size,
                (bitmap_size=NOT_FOUND_FONT_SIZE?0:bitmap_size)));
        }
      }
    }
  }

  NS_ASSERTION((bitmap_size<NOT_FOUND_FONT_SIZE)||use_scaled_font,
                "did not find font size");
  if (!use_scaled_font) {
    SIZE_FONT_PRINTF(("bitmap font:_______ %s\n" 
                      "                    desired=%d, scaled=%d, bitmap=%d", 
                      aName, mPixelSize, scale_size, bitmap_size));
  }

  if (use_scaled_font) {
   SIZE_FONT_PRINTF(("scaled font:_______ %s\n"
                     "                    desired=%d, scaled=%d, bitmap=%d",
                     aName, mPixelSize, scale_size, bitmap_size));

    PRInt32 i;
    PRInt32 n = aStretch->mScaledFonts.Count();
    nsFontGTK* p = nsnull;
    for (i = 0; i < n; i++) {
      p = (nsFontGTK*) aStretch->mScaledFonts.ElementAt(i);
      if (p->mSize == scale_size) {
        break;
      }
    }
    if (i == n) {
      if (base_aafont) {
        // setup the base font
        if (!SetFontCharsetInfo(base_aafont, aCharSet, aChar))
          return nsnull;
        if (mIsUserDefined) {
          base_aafont = SetupUserDefinedFont(base_aafont);
          if (!base_aafont)
            return nsnull;
        }
        font = new nsFontGTKNormal(base_aafont);
      }
      else
        font = new nsFontGTKNormal;
      if (font) {
        /*
         * XXX Instead of passing pixel size, we ought to take underline
         * into account. (Extra space for underline for Asian fonts.)
         */
        if (base_aafont) {
          font->mName = PR_smprintf("%s", base_aafont->mName);
          font->mAABaseSize = base_aafont->mSize;
        }
        else {
          font->mName = PR_smprintf(aStretch->mScalable, scale_size);
          font->mAABaseSize = 0;
        }
        if (!font->mName) {
          delete font;
          return nsnull;
        }
        font->mSize = scale_size;
        font->mCharSetInfo = aCharSet;
        aStretch->mScaledFonts.AppendElement(font);
      }
      else {
        return nsnull;
      }
    }
    else {
      font = p;
    }
  }

  if (!SetFontCharsetInfo(font, aCharSet, aChar))
    return nsnull;

  if (mIsUserDefined) {
    font = SetupUserDefinedFont(font);
    if (!font)
      return nsnull;
  }

  return AddToLoadedFontsList(font);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1715 of file nsFontMetricsGTK.cpp.

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

#ifdef MOZ_ENABLE_FREETYPE2
  if (mWesternFont->IsFreeTypeFont()) {
    nsFreeTypeFont *ft = (nsFreeTypeFont *)mWesternFont;
    if (!ft)
      return;
    // now that there are multiple font types (eg: core X fonts
    // and TrueType fonts) there should be a common set of methods 
    // to get the metrics info from the font object. These methods
    // probably should be virtual functions defined in nsFontGTK.
    int lineSpacing = ft->ascent() + ft->descent();
    if (lineSpacing > mWesternFont->mSize) {
      mLeading = nscoord((lineSpacing - mWesternFont->mSize) * f);
    }
    else {
      mLeading = 0;
    }
    mEmHeight = PR_MAX(1, nscoord(mWesternFont->mSize * f));
    mEmAscent = nscoord(ft->ascent() * mWesternFont->mSize * f / lineSpacing);
    mEmDescent = mEmHeight - mEmAscent;

    mMaxHeight  = nscoord((ft->max_ascent() + ft->max_descent()) * f);
    mMaxAscent  = nscoord(ft->max_ascent() * f) ;
    mMaxDescent = nscoord(ft->max_descent() * f);

    mMaxAdvance = nscoord(ft->max_width() * f);
    // X may screw up if we try to measure/draw more than 32767 pixels in
    // one operation
    mMaxStringLength = (PRInt32)floor(32767.0/ft->max_width());
    mMaxStringLength = PR_MAX(1, mMaxStringLength);

    // 56% of ascent, best guess for non-true type
    mXHeight = NSToCoordRound((float) ft->ascent()* f * 0.56f);

    PRUnichar space = (PRUnichar)' ';
    mSpaceWidth = NSToCoordRound(ft->GetWidth(&space, 1) * f);

    PRUnichar averageX = (PRUnichar)'x';
    mAveCharWidth = NSToCoordRound(ft->GetWidth(&averageX, 1) * f);

    unsigned long pr = 0;
    if (ft->getXHeight(pr)) {
      mXHeight = nscoord(pr * f);
    }

    float height;
    long val;
    if (ft->underlinePosition(val)) {
      /* this will only be provided from adobe .afm fonts and TrueType
       * fonts served by xfsft (not xfstt!) */
      mUnderlineOffset = -NSToIntRound(val * f);
    }
    else {
      height = ft->ascent() + ft->descent();
      mUnderlineOffset = -NSToIntRound(MAX (1, floor (0.1 * height + 0.5)) * f);
    }

    if (ft->underline_thickness(pr)) {
      /* this will only be provided from adobe .afm fonts */
      mUnderlineSize = nscoord(MAX(f, NSToIntRound(pr * f)));
    }
    else {
      height = ft->ascent() + ft->descent();
      mUnderlineSize = NSToIntRound(MAX(1, floor (0.05 * height + 0.5)) * f);
    }

    if (ft->superscript_y(val)) {
      mSuperscriptOffset = nscoord(MAX(f, NSToIntRound(val * f)));
    }
    else {
      mSuperscriptOffset = mXHeight;
    }

    if (ft->subscript_y(val)) {
      mSubscriptOffset = nscoord(MAX(f, NSToIntRound(val * f)));
    }
    else {
     mSubscriptOffset = mXHeight;
    }

    /* need better way to calculate this */
    mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0);
    mStrikeoutSize = mUnderlineSize;

    return;
  }
#endif
  nsXFont *xFont = mWesternFont->GetXFont();
  XFontStruct *fontInfo = xFont->GetXFontStruct();
  f = mDeviceContext->DevUnitsToAppUnits();

  nscoord lineSpacing = nscoord((fontInfo->ascent + fontInfo->descent) * f);
  mEmHeight = PR_MAX(1, nscoord(mWesternFont->mSize * f));
  if (lineSpacing > mEmHeight) {
    mLeading = lineSpacing - mEmHeight;
  }
  else {
    mLeading = 0;
  }
  mMaxHeight = nscoord((fontInfo->ascent + fontInfo->descent) * f);
  mMaxAscent = nscoord(fontInfo->ascent * f);
  mMaxDescent = nscoord(fontInfo->descent * f);

  if (lineSpacing == 0) {
    mEmAscent = mEmHeight;
  }
  else {
    mEmAscent = nscoord(mMaxAscent * mEmHeight / lineSpacing);
  }
  mEmDescent = mEmHeight - mEmAscent;

  mMaxAdvance = nscoord(fontInfo->max_bounds.width * f);
  // X may screw up if we try to measure/draw more than 32767 pixels in
  // one operation.
  mMaxStringLength = (PRInt32)floor(32767.0/fontInfo->max_bounds.width);
  mMaxStringLength = PR_MAX(1, mMaxStringLength);

  gint rawWidth, rawAverage;
  if ((fontInfo->min_byte1 == 0) && (fontInfo->max_byte1 == 0)) {
    rawWidth = xFont->TextWidth8(" ", 1);
    rawAverage = xFont->TextWidth8("x", 1);
  }
  else {
    XChar2b _16bit_space, _16bit_x;
    _16bit_space.byte1 = 0;
    _16bit_space.byte2 = ' ';
    _16bit_x.byte1 = 0;
    _16bit_x.byte2 = 'x';
    rawWidth = xFont->TextWidth16(&_16bit_space, sizeof(_16bit_space)/2);
    rawAverage = xFont->TextWidth16(&_16bit_x, sizeof( _16bit_x)/2);
  }
  mSpaceWidth = NSToCoordRound(rawWidth * f);
  mAveCharWidth = NSToCoordRound(rawAverage * f);

  unsigned long pr = 0;
  if (xFont->GetXFontProperty(XA_X_HEIGHT, &pr) && pr != 0 &&
      pr < 0x00ffffff)  // Bug 43214: arbitrary to exclude garbage values
  {
    mXHeight = nscoord(pr * f);
#ifdef REALLY_NOISY_FONTS
    printf("xHeight=%d\n", mXHeight);
#endif
  }
  else 
  {
    // 56% of ascent, best guess for non-true type
    mXHeight = NSToCoordRound((float) fontInfo->ascent* f * 0.56f);
  }

  if (xFont->GetXFontProperty(XA_UNDERLINE_POSITION, &pr))
  {
    /* this will only be provided from adobe .afm fonts and TrueType
     * fonts served by xfsft (not xfstt!) */
    mUnderlineOffset = -NSToIntRound(pr * f);
#ifdef REALLY_NOISY_FONTS
    printf("underlineOffset=%d\n", mUnderlineOffset);
#endif
  }
  else
  {
    /* this may need to be different than one for those weird asian fonts */
    float height;
    height = fontInfo->ascent + fontInfo->descent;
    mUnderlineOffset = -NSToIntRound(MAX (1, floor (0.1 * height + 0.5)) * f);
  }

  if (xFont->GetXFontProperty(XA_UNDERLINE_THICKNESS, &pr))
  {
    /* this will only be provided from adobe .afm fonts */
    mUnderlineSize = nscoord(MAX(f, NSToIntRound(pr * f)));
#ifdef REALLY_NOISY_FONTS
    printf("underlineSize=%d\n", mUnderlineSize);
#endif
  }
  else
  {
    float height;
    height = fontInfo->ascent + fontInfo->descent;
    mUnderlineSize = NSToIntRound(MAX(1, floor (0.05 * height + 0.5)) * f);
  }

  if (xFont->GetXFontProperty(XA_SUPERSCRIPT_Y, &pr))
  {
    mSuperscriptOffset = nscoord(MAX(f, NSToIntRound(pr * f)));
#ifdef REALLY_NOISY_FONTS
    printf("superscriptOffset=%d\n", mSuperscriptOffset);
#endif
  }
  else
  {
    mSuperscriptOffset = mXHeight;
  }

  if (xFont->GetXFontProperty(XA_SUBSCRIPT_Y, &pr))
  {
    mSubscriptOffset = nscoord(MAX(f, NSToIntRound(pr * f)));
#ifdef REALLY_NOISY_FONTS
    printf("subscriptOffset=%d\n", mSubscriptOffset);
#endif
  }
  else
  {
    mSubscriptOffset = mXHeight;
  }

  /* need better way to calculate this */
  mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0);
  mStrikeoutSize = mUnderlineSize;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsFontMetricsGTK::ResolveForwards ( const PRUnichar aString,
PRUint32  aLength,
nsFontSwitchCallbackGTK  aFunc,
void aData 
)

Definition at line 2069 of file nsFontMetricsGTK.cpp.

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

  if (firstChar == lastChar)
    return NS_OK;

  count = mLoadedFontsCount;

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

  //This if block is meant to speedup the process in normal situation, when
  //most characters can be found in first font
  if (currFont == mLoadedFonts[0]) {
    while (currChar < lastChar && SAFE_CCMAP_HAS_CHAR_EXT(currFont->mCCMap,*currChar))
      ++currChar;
    fontSwitch.mFontGTK = 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(SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count);
      currChar += 2;
    }
    else {
      currFont = LocateFont(*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(SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count);
      lastCharLen = 2;
    }
    else {
      nextFont = LocateFont(*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.mFontGTK = 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.mFontGTK = 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 5049 of file nsFontMetricsGTK.cpp.

{
  if (aNode->mDummy) {
    return nsnull;
  }

  nsFontCharSetInfo* charSetInfo = aNode->mCharSetInfo;

  /*
   * mCharSet is set if we know which glyphs will be found in these fonts.
   * If mCCMap has already been created for this charset, we compare it with
   * the mCCMaps of the previously loaded fonts. If it is the same as any of
   * the previous ones, we return nsnull because there is no point in
   * loading a font with the same map.
   */
  if (charSetInfo->mCharSet) {
    // if not BMP char, ignore charSetInfo->mCCMap checking
    // because the exact ccmap is never created before loading
    // NEED TO FIX: need better way
    if (!IS_IN_BMP(aChar) ) {
      goto check_done;
    }
    PRUint16* ccmap = charSetInfo->mCCMap;
    if (ccmap) {
      for (int i = 0; i < mLoadedFontsCount; i++) {
        if (mLoadedFonts[i]->mCCMap == ccmap) {
          return nsnull;
        }
      }
    }
    else {
      if (!SetUpFontCharSetInfo(charSetInfo))
        return nsnull;
    }
  }
  else {
    if ((!mIsUserDefined) && (charSetInfo == &Unknown)) {
      return nsnull;
    }
  }

check_done:

  aNode->FillStyleHoles();
  nsFontStyle* style = aNode->mStyles[mStyleIndex];

  nsFontWeight** weights = style->mWeights;
  int weight = mFont.weight;
  int steps = (weight % 100);
  int weightIndex;
  if (steps) {
    if (steps < 10) {
      int base = (weight - steps);
      GET_WEIGHT_INDEX(weightIndex, base);
      while (steps--) {
        nsFontWeight* prev = weights[weightIndex];
        for (weightIndex++; weightIndex < 9; weightIndex++) {
          if (weights[weightIndex] != prev) {
            break;
          }
        }
        if (weightIndex >= 9) {
          weightIndex = 8;
        }
      }
    }
    else if (steps > 90) {
      steps = (100 - steps);
      int base = (weight + steps);
      GET_WEIGHT_INDEX(weightIndex, base);
      while (steps--) {
        nsFontWeight* prev = weights[weightIndex];
        for (weightIndex--; weightIndex >= 0; weightIndex--) {
          if (weights[weightIndex] != prev) {
            break;
          }
        }
        if (weightIndex < 0) {
          weightIndex = 0;
        }
      }
    }
    else {
      GET_WEIGHT_INDEX(weightIndex, weight);
    }
  }
  else {
    GET_WEIGHT_INDEX(weightIndex, weight);
  }

  FIND_FONT_PRINTF(("        load font %s", aNode->mName.get()));
  return PickASizeAndLoad(weights[weightIndex]->mStretches[mStretchIndex],
    charSetInfo, aChar, aNode->mName.get());
}

Here is the call graph for this function:

Here is the caller graph for this function:

Implements nsIFontMetricsGTK.

Definition at line 4771 of file nsFontMetricsGTK.cpp.

{
    return NS_OK;
}

Definition at line 6072 of file nsFontMetricsGTK.cpp.

{
  nsCStringKey key(*aAlias);
  char* name = (char*) gAliases->Get(&key);
  if (name) {
    nsCAutoString str(name);
    return TryFamily(&str, aChar);
  }

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6038 of file nsFontMetricsGTK.cpp.

{
  //
  // check the patterh "*-familyname-registry-encoding" for language
  //
  nsFontFamily* family = FindFamily(aName);
  if (family) {
    // try family name of language group first
    nsCAutoString FFREName("*-");
    FFREName.Append(*aName);
    FFREName.Append("-*-*");
    FIND_FONT_PRINTF(("        TryFamily %s with lang group = %s", (*aName).get(),
                                                         atomToName(mLangGroup)));
    nsFontGTK* font = TryLangGroup(mLangGroup, &FFREName, aChar);
    if(font) {
      return font;
    }

    // then try family name regardless of language group
    nsFontNodeArray* nodes = &family->mNodes;
    PRInt32 n = nodes->Count();
    for (PRInt32 i = 0; i < n; i++) {
      FIND_FONT_PRINTF(("        TryFamily %s", nodes->GetElement(i)->mName.get()));
      nsFontGTK* font = SearchNode(nodes->GetElement(i), aChar);
      if (font && font->SupportsChar(aChar)) {
        return font;
      }
    }
  }

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontGTK * nsFontMetricsGTK::TryLangGroup ( nsIAtom aLangGroup,
nsCString aName,
PRUint32  aChar 
)

Definition at line 6023 of file nsFontMetricsGTK.cpp.

{
  //
  // for this family check related registry-encoding (for the language)
  //
  FIND_FONT_PRINTF(("      TryLangGroup lang group = %s, aName = %s", 
                            atomToName(aLangGroup), (*aName).get()));
  if (aName->IsEmpty()) {
    return nsnull;
  }
  nsFontGTK* font = FindLangGroupFont(aLangGroup, aChar, aName);
  return font;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5960 of file nsFontMetricsGTK.cpp.

{
  FIND_FONT_PRINTF(("        TryNode aName = %s", (*aName).get()));
  //
  // check the specified font (foundry-family-registry-encoding)
  //
  if (aName->IsEmpty()) {
    return nsnull;
  }
  nsFontGTK* font;
 
  nsCStringKey key(*aName);
  nsFontNode* node = (nsFontNode*) gFFRENodes->Get(&key);
  if (!node) {
    nsCAutoString pattern;
    FFREToXLFDPattern(*aName, pattern);
    nsFontNodeArray nodes;
    GetFontNames(pattern.get(), PR_FALSE, gForceOutlineScaledFonts, &nodes);
    // no need to call gFFRENodes->Put() since GetFontNames already did
    if (nodes.Count() > 0) {
      // This assertion is not spurious; when searching for an FFRE
      // like -*-courier-iso8859-1 TryNodes should be called not TryNode
      NS_ASSERTION((nodes.Count() == 1), "unexpected number of nodes");
      node = nodes.GetElement(0);
    }
    else {
      // add a dummy node to the hash table to avoid calling XListFonts again
      node = new nsFontNode();
      if (!node) {
        return nsnull;
      }
      gFFRENodes->Put(&key, node);
      node->mDummy = 1;
    }
  }

  if (node) {
    font = SearchNode(node, aChar);
    if (font && font->SupportsChar(aChar))
      return font;
  }

  //
  // do not check related sub-planes for UserDefined
  //
  if (mIsUserDefined) {
    return nsnull;
  }
  //
  // check related sub-planes (wild-card the encoding)
  //
  nsCAutoString ffreName(*aName);
  FFRESubstituteEncoding(ffreName, "*");
  FIND_FONT_PRINTF(("        TrySubplane: wild-card the encoding"));
  font = TryNodes(ffreName, aChar);
  if (font) {
    NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
    return font;
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsFontGTK * nsFontMetricsGTK::TryNodes ( nsACString &  aFFREName,
PRUint32  aChar 
)

Definition at line 5931 of file nsFontMetricsGTK.cpp.

{
  const nsPromiseFlatCString& FFREName = PromiseFlatCString(aFFREName);

  FIND_FONT_PRINTF(("        TryNodes aFFREName = %s", FFREName.get()));
  nsCStringKey key(FFREName);
  PRBool anyFoundry = (FFREName.First() == '*');
  nsFontNodeArray* nodes = (nsFontNodeArray*) gCachedFFRESearches->Get(&key);
  if (!nodes) {
    nsCAutoString pattern;
    FFREToXLFDPattern(aFFREName, pattern);
    nodes = new nsFontNodeArray;
    if (!nodes)
      return nsnull;
    GetFontNames(pattern.get(), anyFoundry, gForceOutlineScaledFonts, nodes);
    gCachedFFRESearches->Put(&key, nodes);
  }
  int i, cnt = nodes->Count();
  for (i=0; i<cnt; i++) {
    nsFontNode* node = nodes->GetElement(i);
    nsFontGTK * font;
    font = SearchNode(node, aChar);
    if (font && font->SupportsChar(aChar))
      return font;
  }
  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 420 of file nsFontMetricsGTK.h.

Definition at line 402 of file nsFontMetricsGTK.h.

Definition at line 388 of file nsFontMetricsGTK.h.

Definition at line 400 of file nsFontMetricsGTK.h.

Definition at line 426 of file nsFontMetricsGTK.h.

Definition at line 406 of file nsFontMetricsGTK.h.

Definition at line 407 of file nsFontMetricsGTK.h.

Definition at line 405 of file nsFontMetricsGTK.h.

nsFont nsIFontMetrics::mFont [protected, inherited]

Definition at line 238 of file nsIFontMetrics.h.

Definition at line 386 of file nsFontMetricsGTK.h.

nsCStringArray nsFontMetricsGTK::mFonts

Definition at line 384 of file nsFontMetricsGTK.h.

Definition at line 385 of file nsFontMetricsGTK.h.

Definition at line 389 of file nsFontMetricsGTK.h.

Definition at line 394 of file nsFontMetricsGTK.h.

Definition at line 390 of file nsFontMetricsGTK.h.

Definition at line 404 of file nsFontMetricsGTK.h.

Definition at line 378 of file nsFontMetricsGTK.h.

Definition at line 379 of file nsFontMetricsGTK.h.

Definition at line 380 of file nsFontMetricsGTK.h.

Definition at line 411 of file nsFontMetricsGTK.h.

Definition at line 409 of file nsFontMetricsGTK.h.

Definition at line 410 of file nsFontMetricsGTK.h.

Definition at line 408 of file nsFontMetricsGTK.h.

Definition at line 421 of file nsFontMetricsGTK.h.

Definition at line 423 of file nsFontMetricsGTK.h.

Definition at line 419 of file nsFontMetricsGTK.h.

Definition at line 424 of file nsFontMetricsGTK.h.

Definition at line 416 of file nsFontMetricsGTK.h.

Definition at line 415 of file nsFontMetricsGTK.h.

Definition at line 425 of file nsFontMetricsGTK.h.

Definition at line 414 of file nsFontMetricsGTK.h.

Definition at line 382 of file nsFontMetricsGTK.h.

Definition at line 413 of file nsFontMetricsGTK.h.

Definition at line 393 of file nsFontMetricsGTK.h.

Definition at line 418 of file nsFontMetricsGTK.h.

Definition at line 417 of file nsFontMetricsGTK.h.

Definition at line 391 of file nsFontMetricsGTK.h.

Definition at line 401 of file nsFontMetricsGTK.h.

Definition at line 412 of file nsFontMetricsGTK.h.


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