mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-15 19:20:13 +00:00
(bstell speaking, (415) 845-7800)
bug 46974 - display of ascii (8 bit) data incorrect with 10646 (16 bit) font a=erik r=blizzard, approved for trunk checkin by jar
This commit is contained in:
parent
33f2200058
commit
d0d4c2fc1c
@ -728,7 +728,6 @@ nsFontMetricsGTK::~nsFontMetricsGTK()
|
||||
}
|
||||
|
||||
mWesternFont = nsnull;
|
||||
mFontHandle = nsnull;
|
||||
|
||||
if (!--gFontMetricsGTKCount) {
|
||||
FreeGlobals();
|
||||
@ -893,7 +892,6 @@ NS_IMETHODIMP nsFontMetricsGTK::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||
if (!mWesternFont) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mFontHandle = mWesternFont->mFont;
|
||||
|
||||
RealizeFont();
|
||||
|
||||
@ -910,7 +908,7 @@ void nsFontMetricsGTK::RealizeFont()
|
||||
{
|
||||
XFontStruct *fontInfo;
|
||||
|
||||
fontInfo = (XFontStruct *)GDK_FONT_XFONT(mFontHandle);
|
||||
fontInfo = (XFontStruct *)GDK_FONT_XFONT(mWesternFont->GetGDKFont());
|
||||
|
||||
float f;
|
||||
mDeviceContext->GetDevUnitsToAppUnits(f);
|
||||
@ -936,7 +934,7 @@ void nsFontMetricsGTK::RealizeFont()
|
||||
// 56% of ascent, best guess for non-true type
|
||||
mXHeight = NSToCoordRound((float) fontInfo->ascent* f * 0.56f);
|
||||
|
||||
gint rawWidth = gdk_text_width(mFontHandle, " ", 1);
|
||||
gint rawWidth = gdk_text_width(mWesternFont->GetGDKFont(), " ", 1);
|
||||
mSpaceWidth = NSToCoordRound(rawWidth * f);
|
||||
|
||||
unsigned long pr = 0;
|
||||
@ -1135,7 +1133,7 @@ NS_IMETHODIMP nsFontMetricsGTK::GetLangGroup(nsIAtom** aLangGroup)
|
||||
|
||||
NS_IMETHODIMP nsFontMetricsGTK::GetFontHandle(nsFontHandle &aHandle)
|
||||
{
|
||||
aHandle = (nsFontHandle)mFontHandle;
|
||||
aHandle = (nsFontHandle)mWesternFont;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1672,6 +1670,18 @@ nsFontGTK::LoadFont(void)
|
||||
|
||||
}
|
||||
|
||||
GdkFont*
|
||||
nsFontGTK::GetGDKFont(void)
|
||||
{
|
||||
return mFont;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsFontGTK::GetGDKFontIs10646(void)
|
||||
{
|
||||
return ((PRBool) (mCharSetInfo == &ISO106461));
|
||||
}
|
||||
|
||||
MOZ_DECL_CTOR_COUNTER(nsFontGTK);
|
||||
|
||||
nsFontGTK::nsFontGTK()
|
||||
@ -1806,6 +1816,8 @@ public:
|
||||
nsFontGTKSubstitute(nsFontGTK* aFont);
|
||||
virtual ~nsFontGTKSubstitute();
|
||||
|
||||
virtual GdkFont* GetGDKFont(void);
|
||||
virtual PRBool GetGDKFontIs10646(void);
|
||||
virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength);
|
||||
virtual gint DrawString(nsRenderingContextGTK* aContext,
|
||||
nsDrawingSurfaceGTK* aSurface, nscoord aX,
|
||||
@ -1926,6 +1938,18 @@ nsFontGTKSubstitute::GetBoundingMetrics(const PRUnichar* aString,
|
||||
}
|
||||
#endif
|
||||
|
||||
GdkFont*
|
||||
nsFontGTKSubstitute::GetGDKFont(void)
|
||||
{
|
||||
return mSubstituteFont->GetGDKFont();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsFontGTKSubstitute::GetGDKFontIs10646(void)
|
||||
{
|
||||
return mSubstituteFont->GetGDKFontIs10646();
|
||||
}
|
||||
|
||||
class nsFontGTKUserDefined : public nsFontGTK
|
||||
{
|
||||
public:
|
||||
@ -1959,13 +1983,13 @@ nsFontGTKUserDefined::~nsFontGTKUserDefined()
|
||||
PRBool
|
||||
nsFontGTKUserDefined::Init(nsFontGTK* aFont)
|
||||
{
|
||||
if (!aFont->mFont) {
|
||||
if (!aFont->GetGDKFont()) {
|
||||
aFont->LoadFont();
|
||||
if (!aFont->mFont) {
|
||||
if (!aFont->GetGDKFont()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
mFont = aFont->mFont;
|
||||
mFont = aFont->GetGDKFont();
|
||||
mMap = gUserDefinedMap;
|
||||
mName = aFont->mName;
|
||||
|
||||
@ -2121,7 +2145,7 @@ nsFontMetricsGTK::PickASizeAndLoad(nsFontStretch* aStretch,
|
||||
font->mMap = aCharSet->mMap;
|
||||
if (FONT_HAS_GLYPH(font->mMap, aChar)) {
|
||||
font->LoadFont();
|
||||
if (!font->mFont) {
|
||||
if (!font->GetGDKFont()) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
@ -2129,7 +2153,7 @@ nsFontMetricsGTK::PickASizeAndLoad(nsFontStretch* aStretch,
|
||||
else {
|
||||
if (aCharSet == &ISO106461) {
|
||||
font->LoadFont();
|
||||
if (!font->mFont) {
|
||||
if (!font->GetGDKFont()) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
@ -2748,7 +2772,7 @@ GetFontNames(char* aPattern, nsFontNodeArray* aNodes)
|
||||
}
|
||||
stretch->mSizes[stretch->mSizesCount++] = size;
|
||||
size->mName = copy;
|
||||
size->mFont = nsnull;
|
||||
// size->mFont is initialized in the constructor
|
||||
size->mSize = pixels;
|
||||
size->mBaselineAdjust = 0;
|
||||
size->mMap = nsnull;
|
||||
|
@ -67,6 +67,8 @@ public:
|
||||
inline int SupportsChar(PRUnichar aChar)
|
||||
{ return mFont && FONT_HAS_GLYPH(mMap, aChar); };
|
||||
|
||||
virtual GdkFont* GetGDKFont(void);
|
||||
virtual PRBool GetGDKFontIs10646(void);
|
||||
virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength) = 0;
|
||||
virtual gint DrawString(nsRenderingContextGTK* aContext,
|
||||
nsDrawingSurfaceGTK* aSurface, nscoord aX,
|
||||
@ -82,13 +84,15 @@ public:
|
||||
nsBoundingMetrics& aBoundingMetrics) = 0;
|
||||
#endif
|
||||
|
||||
GdkFont* mFont;
|
||||
PRUint32* mMap;
|
||||
nsFontCharSetInfo* mCharSetInfo;
|
||||
char* mName;
|
||||
nsFontGTKUserDefined* mUserDefinedFont;
|
||||
PRUint16 mSize;
|
||||
PRInt16 mBaselineAdjust;
|
||||
|
||||
protected:
|
||||
GdkFont* mFont;
|
||||
};
|
||||
|
||||
class nsFontMetricsGTK : public nsIFontMetrics
|
||||
@ -170,7 +174,6 @@ protected:
|
||||
nsIDeviceContext *mDeviceContext;
|
||||
nsFont *mFont;
|
||||
nsFontGTK *mWesternFont;
|
||||
GdkFont *mFontHandle;
|
||||
|
||||
nscoord mLeading;
|
||||
nscoord mEmHeight;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <math.h>
|
||||
#include "nsGCCache.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include "prmem.h"
|
||||
|
||||
#define NS_TO_GDK_RGB(ns) (ns & 0xff) << 16 | (ns & 0xff00) | ((ns >> 16) & 0xff)
|
||||
|
||||
@ -499,13 +500,12 @@ void nsRenderingContextGTK::UpdateGC()
|
||||
|
||||
memset(&values, 0, sizeof(GdkGCValues));
|
||||
|
||||
values.font = mCurrentFont;
|
||||
values.foreground.pixel = gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(mCurrentColor));
|
||||
valuesMask = GDK_GC_FOREGROUND;
|
||||
|
||||
if (mCurrentFont) {
|
||||
if ((mCurrentFont) && (mCurrentFont->GetGDKFont())) {
|
||||
valuesMask = GdkGCValuesMask(valuesMask | GDK_GC_FONT);
|
||||
values.font = mCurrentFont;
|
||||
values.font = mCurrentFont->GetGDKFont();
|
||||
}
|
||||
|
||||
valuesMask = GdkGCValuesMask(valuesMask | GDK_GC_LINE_STYLE);
|
||||
@ -645,7 +645,7 @@ NS_IMETHODIMP nsRenderingContextGTK::SetFont(nsIFontMetrics *aFontMetrics)
|
||||
{
|
||||
nsFontHandle fontHandle;
|
||||
mFontMetrics->GetFontHandle(fontHandle);
|
||||
mCurrentFont = (GdkFont *)fontHandle;
|
||||
mCurrentFont = (nsFontGTK*) fontHandle;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1144,6 +1144,74 @@ NS_IMETHODIMP nsRenderingContextGTK::FillArc(nscoord aX, nscoord aY,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// do the 8 to 16 bit conversion on the stack
|
||||
// if the data is less than this size
|
||||
#define WIDEN_8_TO_16_BUF_SIZE 1024
|
||||
|
||||
// handle 8 bit data with a 16 bit font
|
||||
gint
|
||||
Widen8To16AndMove(const gchar *char_p,
|
||||
gint char_len,
|
||||
XChar2b *xchar2b_p)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<char_len; i++) {
|
||||
(xchar2b_p)->byte1 = 0;
|
||||
(xchar2b_p++)->byte2 = *char_p++;
|
||||
}
|
||||
return(char_len*2);
|
||||
}
|
||||
|
||||
// handle 8 bit data with a 16 bit font
|
||||
gint
|
||||
Widen8To16AndGetWidth (GdkFont *font,
|
||||
const gchar *text,
|
||||
gint text_length)
|
||||
{
|
||||
XChar2b buf[WIDEN_8_TO_16_BUF_SIZE];
|
||||
XChar2b *p = buf;
|
||||
int uchar_size;
|
||||
gint rawWidth;
|
||||
|
||||
if (text_length > WIDEN_8_TO_16_BUF_SIZE) {
|
||||
p = (XChar2b*)PR_Malloc(text_length*sizeof(XChar2b));
|
||||
if (!p) return(0); // handle malloc failure
|
||||
}
|
||||
|
||||
uchar_size = Widen8To16AndMove(text, text_length, p);
|
||||
rawWidth = gdk_text_width(font, (const gchar *)p, uchar_size);
|
||||
|
||||
if (text_length > WIDEN_8_TO_16_BUF_SIZE) {
|
||||
PR_Free((char*)p);
|
||||
}
|
||||
return(rawWidth);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsRenderingContextGTK::Widen8To16AndDraw (GdkDrawable *drawable,
|
||||
GdkFont *font,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
const gchar *text,
|
||||
gint text_length)
|
||||
{
|
||||
XChar2b buf[WIDEN_8_TO_16_BUF_SIZE];
|
||||
XChar2b *p = buf;
|
||||
int uchar_size;
|
||||
|
||||
if (text_length > WIDEN_8_TO_16_BUF_SIZE) {
|
||||
p = (XChar2b*)PR_Malloc(text_length*sizeof(XChar2b));
|
||||
if (!p) return; // handle malloc failure
|
||||
}
|
||||
|
||||
uchar_size = Widen8To16AndMove(text, text_length, p);
|
||||
my_gdk_draw_text(drawable, font, gc, x, y, (const gchar *)p, uchar_size);
|
||||
|
||||
if (text_length > WIDEN_8_TO_16_BUF_SIZE) {
|
||||
PR_Free((char*)p);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRenderingContextGTK::GetWidth(char aC, nscoord &aWidth)
|
||||
@ -1186,7 +1254,16 @@ nsRenderingContextGTK::GetWidth(const char* aString, PRUint32 aLength,
|
||||
}
|
||||
else {
|
||||
g_return_val_if_fail(aString != NULL, NS_ERROR_FAILURE);
|
||||
gint rawWidth = gdk_text_width (mCurrentFont, aString, aLength);
|
||||
g_return_val_if_fail(mCurrentFont != NULL, NS_ERROR_FAILURE);
|
||||
gint rawWidth;
|
||||
if (!mCurrentFont->GetGDKFontIs10646()) {
|
||||
// 8 bit data with an 8 bit font
|
||||
rawWidth = gdk_text_width (mCurrentFont->GetGDKFont(), aString, aLength);
|
||||
}
|
||||
else {
|
||||
// we have 8 bit data but a 16 bit font
|
||||
rawWidth = Widen8To16AndGetWidth (mCurrentFont->GetGDKFont(), aString, aLength);
|
||||
}
|
||||
aWidth = NSToCoordRound(rawWidth * mP2T);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -1256,6 +1333,7 @@ nsRenderingContextGTK::DrawString(const char *aString, PRUint32 aLength,
|
||||
g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE);
|
||||
g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE);
|
||||
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;
|
||||
@ -1276,17 +1354,33 @@ nsRenderingContextGTK::DrawString(const char *aString, PRUint32 aLength,
|
||||
nscoord xx = x;
|
||||
nscoord yy = y;
|
||||
mTranMatrix->TransformCoord(&xx, &yy);
|
||||
nsRenderingContextGTK::my_gdk_draw_text(mSurface->GetDrawable(), mCurrentFont,
|
||||
mGC,
|
||||
if (!mCurrentFont->GetGDKFontIs10646()) {
|
||||
// 8 bit data with an 8 bit font
|
||||
nsRenderingContextGTK::my_gdk_draw_text(mSurface->GetDrawable(),
|
||||
mCurrentFont->GetGDKFont(), mGC,
|
||||
xx, yy, &ch, 1);
|
||||
}
|
||||
else {
|
||||
// we have 8 bit data but a 16 bit font
|
||||
Widen8To16AndDraw(mSurface->GetDrawable(), mCurrentFont->GetGDKFont(), mGC,
|
||||
xx, yy, &ch, 1);
|
||||
}
|
||||
x += *aSpacing++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mTranMatrix->TransformCoord(&x, &y);
|
||||
nsRenderingContextGTK::my_gdk_draw_text (mSurface->GetDrawable(), mCurrentFont,
|
||||
mGC,
|
||||
if (!mCurrentFont->GetGDKFontIs10646()) { // keep 8 bit path fast
|
||||
// 8 bit data with an 8 bit font
|
||||
nsRenderingContextGTK::my_gdk_draw_text (mSurface->GetDrawable(),
|
||||
mCurrentFont->GetGDKFont(), mGC,
|
||||
x, y, aString, aLength);
|
||||
}
|
||||
else {
|
||||
// we have 8 bit data but a 16 bit font
|
||||
Widen8To16AndDraw(mSurface->GetDrawable(), mCurrentFont->GetGDKFont(), mGC,
|
||||
x, y, aString, aLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1374,8 +1468,8 @@ FoundFont:
|
||||
const PRUnichar* end = &aString[i];
|
||||
|
||||
// save off mCurrentFont and set it so that we cache the GC's font correctly
|
||||
GdkFont *oldFont = mCurrentFont;
|
||||
mCurrentFont = prevFont->mFont;
|
||||
nsFontGTK *oldFont = mCurrentFont;
|
||||
mCurrentFont = prevFont;
|
||||
UpdateGC();
|
||||
|
||||
while (str < end) {
|
||||
@ -1389,8 +1483,8 @@ FoundFont:
|
||||
mCurrentFont = oldFont;
|
||||
}
|
||||
else {
|
||||
GdkFont *oldFont = mCurrentFont;
|
||||
mCurrentFont = prevFont->mFont;
|
||||
nsFontGTK *oldFont = mCurrentFont;
|
||||
mCurrentFont = prevFont;
|
||||
UpdateGC();
|
||||
x += prevFont->DrawString(this, mSurface, x, y, &aString[start],
|
||||
i - start);
|
||||
@ -1408,8 +1502,8 @@ FoundFont:
|
||||
|
||||
if (prevFont) {
|
||||
|
||||
GdkFont *oldFont = mCurrentFont;
|
||||
mCurrentFont = prevFont->mFont;
|
||||
nsFontGTK *oldFont = mCurrentFont;
|
||||
mCurrentFont = prevFont;
|
||||
UpdateGC();
|
||||
|
||||
if (aSpacing) {
|
||||
@ -1666,6 +1760,49 @@ NS_IMETHODIMP nsRenderingContextGTK::RetrieveCurrentNativeGraphicData(PRUint32 *
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
|
||||
// bstell Sept. 22, 2000:
|
||||
// added code to handle displaying 8 bit data using a 16 bit font.
|
||||
// have not tested the MOZ_MATHML code path
|
||||
|
||||
void
|
||||
Widen8To16AndGetTextExtents (GdkFont *font,
|
||||
const gchar *text,
|
||||
gint text_length,
|
||||
gint *lbearing,
|
||||
gint *rbearing,
|
||||
gint *width,
|
||||
gint *ascent,
|
||||
gint *descent)
|
||||
{
|
||||
XChar2b buf[WIDEN_8_TO_16_BUF_SIZE];
|
||||
XChar2b *p = buf;
|
||||
int uchar_size;
|
||||
|
||||
if (text_length > WIDEN_8_TO_16_BUF_SIZE) {
|
||||
p = (XChar2b*)PR_Malloc(text_length*sizeof(XChar2b));
|
||||
if (!p) { // handle malloc failure
|
||||
*lbearing = 0;
|
||||
*rbearing = 0;
|
||||
*width = 0;
|
||||
*ascent = 0;
|
||||
*descent = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uchar_size = Widen8To16AndMove(text, text_length, p);
|
||||
gdk_text_extents (font, (const char*)p, uchar_size,
|
||||
lbearing,
|
||||
rbearing,
|
||||
width,
|
||||
ascent,
|
||||
descent);
|
||||
|
||||
if (text_length > WIDEN_8_TO_16_BUF_SIZE) {
|
||||
PR_Free((char*)p);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRenderingContextGTK::GetBoundingMetrics(const char* aString,
|
||||
PRUint32 aLength,
|
||||
@ -1674,12 +1811,25 @@ nsRenderingContextGTK::GetBoundingMetrics(const char* aString,
|
||||
aBoundingMetrics.Clear();
|
||||
if (aString && 0 < aLength) {
|
||||
g_return_val_if_fail(aString != NULL, NS_ERROR_FAILURE);
|
||||
gdk_text_extents (mCurrentFont, aString, aLength,
|
||||
&aBoundingMetrics.leftBearing,
|
||||
&aBoundingMetrics.rightBearing,
|
||||
&aBoundingMetrics.width,
|
||||
&aBoundingMetrics.ascent,
|
||||
&aBoundingMetrics.descent);
|
||||
g_return_val_if_fail(mCurrentFont != NULL, NS_ERROR_FAILURE);
|
||||
if (!mCurrentFont->GetGDKFontIs10646()) {
|
||||
// 8 bit data with an 8 bit font
|
||||
gdk_text_extents (mCurrentFont->GetGDKFont(), aString, aLength,
|
||||
&aBoundingMetrics.leftBearing,
|
||||
&aBoundingMetrics.rightBearing,
|
||||
&aBoundingMetrics.width,
|
||||
&aBoundingMetrics.ascent,
|
||||
&aBoundingMetrics.descent);
|
||||
}
|
||||
else {
|
||||
// we have 8 bit data but a 16 bit font
|
||||
Widen8To16AndGetTextExtents (mCurrentFont->GetGDKFont(), aString, aLength,
|
||||
&aBoundingMetrics.leftBearing,
|
||||
&aBoundingMetrics.rightBearing,
|
||||
&aBoundingMetrics.width,
|
||||
&aBoundingMetrics.ascent,
|
||||
&aBoundingMetrics.descent);
|
||||
}
|
||||
|
||||
aBoundingMetrics.leftBearing = NSToCoordRound(aBoundingMetrics.leftBearing * mP2T);
|
||||
aBoundingMetrics.rightBearing = NSToCoordRound(aBoundingMetrics.rightBearing * mP2T);
|
||||
@ -1769,7 +1919,6 @@ nsRenderingContextGTK::GetBoundingMetrics(const PRUnichar* aString,
|
||||
#endif /* MOZ_MATHML */
|
||||
|
||||
|
||||
|
||||
/* static */ void
|
||||
nsRenderingContextGTK::my_gdk_draw_text (GdkDrawable *drawable,
|
||||
GdkFont *font,
|
||||
|
@ -44,6 +44,8 @@
|
||||
|
||||
#define USE_NATIVE_TILING 1
|
||||
|
||||
class nsFontGTK;
|
||||
|
||||
class nsRenderingContextGTK : public nsRenderingContextImpl
|
||||
{
|
||||
public:
|
||||
@ -205,6 +207,15 @@ public:
|
||||
|
||||
GdkGC *GetGC() { return gdk_gc_ref(mGC); }
|
||||
|
||||
// handle drawing 8 bit data with a 16 bit font
|
||||
static void Widen8To16AndDraw(GdkDrawable *drawable,
|
||||
GdkFont *font,
|
||||
GdkGC *gc,
|
||||
gint x,
|
||||
gint y,
|
||||
const gchar *text,
|
||||
gint text_length);
|
||||
|
||||
// replacment for gdk_draw_text that doesn't do XSetFont
|
||||
static void my_gdk_draw_text(GdkDrawable *drawable,
|
||||
GdkFont *font,
|
||||
@ -233,7 +244,7 @@ private:
|
||||
gchar *mDashList;
|
||||
gint mDashes;
|
||||
nscolor mCurrentColor;
|
||||
GdkFont *mCurrentFont;
|
||||
nsFontGTK *mCurrentFont;
|
||||
nsLineStyle mCurrentLineStyle;
|
||||
|
||||
void UpdateGC();
|
||||
|
Loading…
Reference in New Issue
Block a user