зеркало из https://github.com/mozilla/gecko-dev.git
fixing RTL text in windows cairo builds. bug 327229 r=vlad
This commit is contained in:
Родитель
c5c7541551
Коммит
b2388d1c15
|
@ -74,6 +74,7 @@ nsThebesFontMetrics::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
|||
mLangGroup = aLangGroup;
|
||||
mDeviceContext = (nsThebesDeviceContext*)aContext;
|
||||
mDev2App = aContext->DevUnitsToAppUnits();
|
||||
mIsRTL = PR_FALSE;
|
||||
|
||||
// work around layout giving us 0 sized fonts...
|
||||
double size = aFont.size * mDeviceContext->AppUnitsToDevUnits();
|
||||
|
@ -284,6 +285,8 @@ nsThebesFontMetrics::GetWidth(const PRUnichar* aString, PRUint32 aLength,
|
|||
{
|
||||
nsRefPtr<gfxTextRun> textrun = mFontGroup->MakeTextRun(nsDependentSubstring(aString, aString+aLength));
|
||||
|
||||
textrun->SetRightToLeft(mIsRTL);
|
||||
|
||||
aWidth = ROUND_TO_TWIPS(textrun->MeasureString(aContext->Thebes()));
|
||||
|
||||
return NS_OK;
|
||||
|
@ -350,6 +353,8 @@ nsThebesFontMetrics::DrawString(const PRUnichar* aString, PRUint32 aLength,
|
|||
|
||||
nsRefPtr<gfxTextRun> textrun = mFontGroup->MakeTextRun(nsDependentSubstring(aString, aString+aLength));
|
||||
|
||||
textrun->SetRightToLeft(mIsRTL);
|
||||
|
||||
textrun->DrawString(aContext->Thebes(), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev)));
|
||||
|
||||
return NS_OK;
|
||||
|
@ -384,8 +389,7 @@ nsThebesFontMetrics::GetBoundingMetrics(const PRUnichar *aString,
|
|||
nsresult
|
||||
nsThebesFontMetrics::SetRightToLeftText(PRBool aIsRTL)
|
||||
{
|
||||
// this doesn't seem to ever get called
|
||||
NS_WARNING("nsThebesFontMetrics::SetRightToLeftText called!");
|
||||
mIsRTL = aIsRTL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,6 +157,7 @@ private:
|
|||
nsThebesDeviceContext *mDeviceContext;
|
||||
nsCOMPtr<nsIAtom> mLangGroup;
|
||||
float mDev2App;
|
||||
PRBool mIsRTL;
|
||||
};
|
||||
|
||||
#endif /* NSTHEBESFONTMETRICS__H__ */
|
||||
|
|
|
@ -1108,6 +1108,11 @@ nsThebesRenderingContext::DrawTile(imgIContainer *aImage,
|
|||
//
|
||||
// text junk
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::SetRightToLeftText(PRBool aIsRTL)
|
||||
{
|
||||
return mFontMetrics->SetRightToLeftText(aIsRTL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::SetFont(const nsFont& aFont, nsIAtom* aLangGroup)
|
||||
|
|
|
@ -219,7 +219,7 @@ public:
|
|||
const nsRect &aDestRect);
|
||||
NS_IMETHOD DrawTile(imgIContainer *aImage, nscoord aXOffset, nscoord aYOffset,
|
||||
const nsRect * aTargetRect);
|
||||
NS_IMETHOD SetRightToLeftText(PRBool aIsRTL) { return NS_OK; }
|
||||
NS_IMETHOD SetRightToLeftText(PRBool aIsRTL);
|
||||
|
||||
NS_IMETHOD GetClusterInfo(const PRUnichar *aText,
|
||||
PRUint32 aLength,
|
||||
|
|
|
@ -181,10 +181,6 @@ protected:
|
|||
nsString mFamilies;
|
||||
gfxFontStyle mStyle;
|
||||
gfxFontVector mFonts;
|
||||
|
||||
PRBool mIsRTL;
|
||||
|
||||
void *mData; // XXXA
|
||||
};
|
||||
|
||||
|
||||
|
@ -198,6 +194,11 @@ public:
|
|||
|
||||
// returns length in pixels
|
||||
virtual gfxFloat MeasureString(gfxContext *aContext) = 0;
|
||||
|
||||
virtual void SetRightToLeft(PRBool aIsRTL) { mIsRTL = aIsRTL; }
|
||||
virtual PRBool IsRightToLeft() { return mIsRTL; }
|
||||
|
||||
private:
|
||||
PRBool mIsRTL;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
|
||||
protected:
|
||||
gfxPlatform() { }
|
||||
~gfxPlatform() { }
|
||||
virtual ~gfxPlatform() { }
|
||||
};
|
||||
|
||||
#endif /* GFX_PLATFORM_H */
|
||||
|
|
|
@ -44,8 +44,14 @@
|
|||
|
||||
#include <cairo-win32.h>
|
||||
|
||||
class gfxWindowsFont : public gfxFont {
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* class gfxWindowsFont
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
class gfxWindowsFont : public gfxFont {
|
||||
public:
|
||||
gfxWindowsFont(const nsAString &aName, const gfxFontGroup *aFontGroup, HDC aHWnd);
|
||||
virtual ~gfxWindowsFont();
|
||||
|
@ -62,17 +68,22 @@ protected:
|
|||
void FillLogFont();
|
||||
|
||||
private:
|
||||
void ComputeMetrics();
|
||||
void ComputeMetrics(HDC dc);
|
||||
|
||||
LOGFONTW mLogFont;
|
||||
|
||||
cairo_font_face_t *mFontFace;
|
||||
cairo_scaled_font_t *mScaledFont;
|
||||
HDC mDC;
|
||||
|
||||
gfxFont::Metrics mMetrics;
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* class gfxWindowsFontGroup
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
class NS_EXPORT gfxWindowsFontGroup : public gfxFontGroup {
|
||||
|
||||
|
@ -80,7 +91,6 @@ public:
|
|||
gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFontStyle* aStyle, HDC hwnd);
|
||||
virtual ~gfxWindowsFontGroup();
|
||||
|
||||
|
||||
virtual gfxTextRun *MakeTextRun(const nsAString& aString);
|
||||
|
||||
protected:
|
||||
|
@ -93,6 +103,12 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* class gfxWindowsTextRun
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
class NS_EXPORT gfxWindowsTextRun : public gfxTextRun {
|
||||
THEBES_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "nsCRT.h"
|
||||
|
||||
gfxFontGroup::gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle)
|
||||
: mFamilies(aFamilies), mStyle(*aStyle), mIsRTL(PR_FALSE)
|
||||
: mFamilies(aFamilies), mStyle(*aStyle)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
|
|
@ -50,28 +50,30 @@
|
|||
#define NSToCoordRound(x) (floor((x) + 0.5))
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* class gfxWindowsFont
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
gfxWindowsFont::gfxWindowsFont(const nsAString &aName, const gfxFontGroup *aFontGroup, HDC aDC)
|
||||
{
|
||||
mName = aName;
|
||||
mGroup = aFontGroup;
|
||||
mStyle = mGroup->GetStyle();
|
||||
|
||||
mDC = aDC;
|
||||
|
||||
if (!mDC)
|
||||
mDC = GetDC(nsnull);
|
||||
|
||||
mFontFace = MakeCairoFontFace();
|
||||
NS_ASSERTION(mFontFace, "Failed to make font face");
|
||||
|
||||
mScaledFont = MakeCairoScaledFont(nsnull);
|
||||
NS_ASSERTION(mScaledFont, "Failed to make scaled font");
|
||||
|
||||
ComputeMetrics();
|
||||
HDC dc = aDC ? aDC : GetDC((HWND)nsnull);
|
||||
|
||||
if (mDC != aDC) {
|
||||
ReleaseDC(nsnull, mDC);
|
||||
mDC = aDC;
|
||||
}
|
||||
ComputeMetrics(dc);
|
||||
|
||||
if (dc != aDC)
|
||||
ReleaseDC((HWND)nsnull, dc);
|
||||
}
|
||||
|
||||
gfxWindowsFont::~gfxWindowsFont()
|
||||
|
@ -126,11 +128,11 @@ gfxWindowsFont::MakeCairoScaledFont(cairo_t *cr)
|
|||
}
|
||||
|
||||
void
|
||||
gfxWindowsFont::ComputeMetrics()
|
||||
gfxWindowsFont::ComputeMetrics(HDC aDC)
|
||||
{
|
||||
SaveDC(mDC);
|
||||
SaveDC(aDC);
|
||||
|
||||
cairo_win32_scaled_font_select_font(mScaledFont, mDC);
|
||||
cairo_win32_scaled_font_select_font(mScaledFont, aDC);
|
||||
|
||||
double cairofontfactor = cairo_win32_scaled_font_get_metrics_factor(mScaledFont);
|
||||
double multiplier = cairofontfactor * mStyle->size;
|
||||
|
@ -141,7 +143,7 @@ gfxWindowsFont::ComputeMetrics()
|
|||
TEXTMETRIC& metrics = oMetrics.otmTextMetrics;
|
||||
gfxFloat descentPos = 0;
|
||||
|
||||
if (0 < ::GetOutlineTextMetrics(mDC, sizeof(oMetrics), &oMetrics)) {
|
||||
if (0 < ::GetOutlineTextMetrics(aDC, sizeof(oMetrics), &oMetrics)) {
|
||||
// mXHeight = NSToCoordRound(oMetrics.otmsXHeight * mDev2App); XXX not really supported on windows
|
||||
mMetrics.xHeight = NSToCoordRound((float)metrics.tmAscent * multiplier * 0.56f); // 50% of ascent, best guess for true type
|
||||
mMetrics.superscriptOffset = NSToCoordRound(oMetrics.otmptSuperscriptOffset.y * multiplier);
|
||||
|
@ -156,7 +158,7 @@ gfxWindowsFont::ComputeMetrics()
|
|||
// Begin -- section of code to get the real x-height with GetGlyphOutline()
|
||||
GLYPHMETRICS gm;
|
||||
MAT2 mMat = { 1, 0, 0, 1 }; // glyph transform matrix (always identity in our context)
|
||||
DWORD len = GetGlyphOutlineW(mDC, PRUnichar('x'), GGO_METRICS, &gm, 0, nsnull, &mMat);
|
||||
DWORD len = GetGlyphOutlineW(aDC, PRUnichar('x'), GGO_METRICS, &gm, 0, nsnull, &mMat);
|
||||
|
||||
if (GDI_ERROR != len && gm.gmptGlyphOrigin.y > 0) {
|
||||
mMetrics.xHeight = NSToCoordRound(gm.gmptGlyphOrigin.y * multiplier);
|
||||
|
@ -166,7 +168,7 @@ gfxWindowsFont::ComputeMetrics()
|
|||
else {
|
||||
// Make a best-effort guess at extended metrics
|
||||
// this is based on general typographic guidelines
|
||||
::GetTextMetrics(mDC, &metrics);
|
||||
::GetTextMetrics(aDC, &metrics);
|
||||
mMetrics.xHeight = NSToCoordRound((float)metrics.tmAscent * 0.56f); // 56% of ascent, best guess for non-true type
|
||||
mMetrics.superscriptOffset = mMetrics.xHeight; // XXX temporary code!
|
||||
mMetrics.subscriptOffset = mMetrics.xHeight; // XXX temporary code!
|
||||
|
@ -191,20 +193,20 @@ gfxWindowsFont::ComputeMetrics()
|
|||
|
||||
// Cache the width of a single space.
|
||||
SIZE size;
|
||||
::GetTextExtentPoint32(mDC, " ", 1, &size);
|
||||
::GetTextExtentPoint32(aDC, " ", 1, &size);
|
||||
//size.cx -= font->mOverhangCorrection;
|
||||
mMetrics.spaceWidth = NSToCoordRound(size.cx * multiplier);
|
||||
|
||||
cairo_win32_scaled_font_done_font(mScaledFont);
|
||||
|
||||
RestoreDC(mDC, -1);
|
||||
RestoreDC(aDC, -1);
|
||||
}
|
||||
|
||||
|
||||
#define CLIP_TURNOFF_FONTASSOCIATION 0x40
|
||||
void
|
||||
gfxWindowsFont::FillLogFont()
|
||||
{
|
||||
#define CLIP_TURNOFF_FONTASSOCIATION 0x40
|
||||
|
||||
mLogFont.lfHeight = -NSToCoordRound(mStyle->size);
|
||||
|
||||
if (mLogFont.lfHeight == 0)
|
||||
|
@ -226,7 +228,7 @@ gfxWindowsFont::FillLogFont()
|
|||
mLogFont.lfQuality = DEFAULT_QUALITY;
|
||||
mLogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||
mLogFont.lfWeight = mStyle->weight;
|
||||
mLogFont.lfItalic = (mStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) ? TRUE : FALSE; // XXX need better oblique support
|
||||
mLogFont.lfItalic = (mStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) ? TRUE : FALSE;
|
||||
|
||||
int len = PR_MIN(mName.Length(), LF_FACESIZE);
|
||||
memcpy(mLogFont.lfFaceName, mName.get(), len * 2);
|
||||
|
@ -234,21 +236,11 @@ gfxWindowsFont::FillLogFont()
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* class gfxWindowsFontGroup
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
PRBool
|
||||
gfxWindowsFontGroup::MakeFont(const nsAString& aName, const nsAString& aGenericName, void *closure)
|
||||
|
@ -276,8 +268,11 @@ gfxWindowsFontGroup::MakeTextRun(const nsAString& aString)
|
|||
return new gfxWindowsTextRun(aString, this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* class gfxWindowsTextRun
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
THEBES_IMPL_REFCOUNTING(gfxWindowsTextRun)
|
||||
|
||||
|
@ -323,12 +318,13 @@ gfxWindowsTextRun::MeasureOrDrawUniscribe(gfxContext *aContext,
|
|||
SCRIPT_CACHE sc = NULL;
|
||||
SCRIPT_CONTROL *control = nsnull;
|
||||
SCRIPT_STATE *state = nsnull;
|
||||
PRBool rtl = ((::GetTextAlign(aDC) & TA_RTLREADING) == TA_RTLREADING);
|
||||
|
||||
PRBool rtl = IsRightToLeft();
|
||||
if (rtl) {
|
||||
control = (SCRIPT_CONTROL *)malloc(sizeof(SCRIPT_CONTROL));
|
||||
state = (SCRIPT_STATE *)malloc(sizeof(SCRIPT_STATE));
|
||||
memset(control, 0, sizeof(control));
|
||||
memset(state, 0, sizeof(state));
|
||||
memset(control, 0, sizeof(SCRIPT_CONTROL));
|
||||
memset(state, 0, sizeof(SCRIPT_STATE));
|
||||
control->fNeutralOverride = 1;
|
||||
state->uBidiLevel = 1;
|
||||
}
|
||||
|
@ -348,7 +344,8 @@ gfxWindowsTextRun::MeasureOrDrawUniscribe(gfxContext *aContext,
|
|||
WORD *glyphs = (WORD *)malloc(maxGlyphs*sizeof(WORD));
|
||||
WORD *clusters = (WORD *)malloc(itemLength*sizeof(WORD));
|
||||
SCRIPT_VISATTR *attr = (SCRIPT_VISATTR *)malloc(maxGlyphs*sizeof(SCRIPT_VISATTR));
|
||||
items[i].a.fLogicalOrder = 1;
|
||||
// don't set this, we want things in visual order (default)
|
||||
// items[i].a.fLogicalOrder = 1;
|
||||
|
||||
cairo_font_face_t *fontFace = nsnull;
|
||||
cairo_scaled_font_t *scaledFont = nsnull;
|
||||
|
@ -541,6 +538,10 @@ TRY_AGAIN_SAME_SCRIPT:
|
|||
}
|
||||
|
||||
free(items);
|
||||
if (control)
|
||||
free(control);
|
||||
if (state)
|
||||
free(state);
|
||||
|
||||
// printf("loops: %d\n", loops - numItems);
|
||||
return length;
|
||||
|
|
Загрузка…
Ссылка в новой задаче