зеркало из https://github.com/mozilla/gecko-dev.git
Bug 310708, implementing char width cache. r=thesuckiestemail@yahoo.se, no sr required
This commit is contained in:
Родитель
55e79c645e
Коммит
0c007ab396
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче