Bug 310708, implementing char width cache. r=thesuckiestemail@yahoo.se, no sr required

This commit is contained in:
sergei_d%fi.tartu.ee 2005-10-02 17:21:08 +00:00
Родитель 55e79c645e
Коммит 0c007ab396
3 изменённых файлов: 58 добавлений и 18 удалений

Просмотреть файл

@ -50,7 +50,6 @@
#include "nsIPrefBranch.h"
#include "nsCOMPtr.h"
#include "nspr.h"
#include "nsHashtable.h"
#include "nsReadableUtils.h"
#include <UnicodeBlockObjects.h>
@ -168,9 +167,9 @@ NS_IMETHODIMP nsFontMetricsBeOS::Init(const nsFont& aFont, nsIAtom* aLangGroup,
}
// not successful. use system font.
if (isfixed)
mFontHandle = be_fixed_font;
mFontHandle = BFont(be_fixed_font);
else
mFontHandle = be_plain_font;
mFontHandle = BFont(be_plain_font);
fontfound = PR_TRUE;
break;
}
@ -180,9 +179,9 @@ NS_IMETHODIMP nsFontMetricsBeOS::Init(const nsFont& aFont, nsIAtom* aLangGroup,
if (!fontfound)
{
if (isfixed)
mFontHandle = be_fixed_font;
mFontHandle = BFont(be_fixed_font);
else
mFontHandle = be_plain_font;
mFontHandle = BFont(be_plain_font);
}
if (aFont.style == NS_FONT_STYLE_ITALIC)
@ -206,12 +205,16 @@ NS_IMETHODIMP nsFontMetricsBeOS::Init(const nsFont& aFont, nsIAtom* aLangGroup,
mFontHandle.SetShear(105.0);
mFontHandle.SetSize(mFont.size/app2twip);
mFontHandle.SetSpacing(B_FIXED_SPACING);
#ifdef NOISY_FONTS
#ifdef DEBUG
fprintf(stderr, "looking for font %s (%d)", wildstring, aFont.size / app2twip);
#endif
#endif
//UTF8 charspace in BeOS is 0xFFFF, 256 is by "pighole rule" sqrt(0xFFFF),
// actually rare font contains more glyphs
mFontWidthCache.Init(256);
RealizeFont(aContext);
return NS_OK;
@ -274,7 +277,6 @@ void nsFontMetricsBeOS::RealizeFont(nsIDeviceContext* aContext)
/* need better way to calculate this */
mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0);
mStrikeoutSize = mUnderlineSize;
}
NS_IMETHODIMP nsFontMetricsBeOS::GetXHeight(nscoord& aResult)
@ -409,6 +411,45 @@ nsFontMetricsBeOS::FamilyExists(const nsString& aName)
printf("exists? %s", (font_family)family.get());
return (count_font_styles((font_family)family.get()) > 0) ? NS_OK : NS_ERROR_FAILURE;
}
// useful UTF-8 utility
inline uint32 utf8_char_len(uchar byte)
{
return (((0xE5000000 >> ((byte >> 3) & 0x1E)) & 3) + 1);
}
// nsHashKeys has trouble with char* substring conversion
// it likes 0-terminated, plus conversion to nsACString overhead.
// So KISS
inline PRUint32 utf8_to_index(char *utf8char)
{
PRUint32 ch = 0;
switch (utf8_char_len(*utf8char) - 1)
{
case 3: ch += *utf8char++; ch <<= 6;
case 2: ch += *utf8char++; ch <<= 6;
case 1: ch += *utf8char++; ch <<= 6;
case 0: ch += *utf8char++;
}
return ch;
}
// Using cached widths
float nsFontMetricsBeOS::GetStringWidth(char *utf8str, uint32 len)
{
//At moment only for most annoying case - permanent calls for single char widths
// calculating StringWidth as sum of chars width produces sometimes weird results
if (utf8_char_len(*utf8str) != len)
return mFontHandle.StringWidth(utf8str, len);
// converting multibyte sequence to index
PRUint32 index = utf8_to_index(utf8str);
float width;
if (!mFontWidthCache.Get(index, &width))
{
width = mFontHandle.StringWidth(utf8str, len);
mFontWidthCache.Put(index, width);
}
return width;
}
// The Font Enumerator
@ -562,7 +603,7 @@ static nsresult EnumFonts(const char * aLangGroup, const char* aGeneric, PRUint3
{
if(FontMatchesGenericType(family, flags, aGeneric, aLangGroup))
{
if (!(array[j] = ToNewUnicode(NS_ConvertUTF8toUTF16((const char*)family))))
if (!(array[j] = UTF8ToNewUnicode(nsDependentCString(family))))
break;
++j;
}

Просмотреть файл

@ -51,6 +51,7 @@
#include "nsCOMPtr.h"
#include "nsRenderingContextBeOS.h"
#include "nsICharRepresentable.h"
#include "nsDataHashtable.h"
#include <Font.h>
@ -94,6 +95,8 @@ public:
static int FontMatchesGenericType(font_family family, uint32 flags, const char* aGeneric, const char* aLangGroup);
nsCOMPtr<nsIAtom> mLangGroup;
static int MatchesLangGroup(font_family family, const char* aLangGroup);
float GetStringWidth(char *string, uint32 len);
protected:
void RealizeFont(nsIDeviceContext* aContext);
@ -120,7 +123,8 @@ protected:
PRUint16 mPixelSize;
PRUint8 mStretchIndex;
PRUint8 mStyleIndex;
PRUint8 mStyleIndex;
nsDataHashtable<nsUint32HashKey, float> mFontWidthCache;
};
class nsFontEnumeratorBeOS : public nsIFontEnumerator

Просмотреть файл

@ -1017,12 +1017,8 @@ inline uint32 utf8_str_len(const char* ustring)
NS_IMETHODIMP nsRenderingContextBeOS::GetWidth(char aC, nscoord &aWidth)
{
// Check for the very common case of trying to get the width of a single space
if ((aC == ' ') && (nsnull != mFontMetrics))
return mFontMetrics->GetSpaceWidth(aWidth);
else
return GetWidth(&aC, 1, aWidth);
}
return GetWidth(&aC, 1, aWidth);
}
NS_IMETHODIMP nsRenderingContextBeOS::GetWidth(PRUnichar aC, nscoord &aWidth, PRInt32 *aFontID)
{
@ -1041,7 +1037,6 @@ NS_IMETHODIMP nsRenderingContextBeOS::GetWidth(const char *aString, nscoord &aWi
NS_IMETHODIMP nsRenderingContextBeOS::GetWidth(const char *aString, PRUint32 aLength, nscoord &aWidth)
{
if (0 == aLength)
{
aWidth = 0;
@ -1050,8 +1045,8 @@ NS_IMETHODIMP nsRenderingContextBeOS::GetWidth(const char *aString, PRUint32 aLe
{
if (aString == nsnull)
return NS_ERROR_FAILURE;
PRUint32 rawWidth = (PRUint32)mCurrentFont->StringWidth(aString, aLength);
aWidth = NSToCoordRound(rawWidth * mP2T);
// Using cached width if possible
aWidth = (nscoord)((nsFontMetricsBeOS *)mFontMetrics)->GetStringWidth((char *)aString, aLength) * mP2T;
}
return NS_OK;
}