bug 75068; author=simon@softel.co.il; r=kmcclusk, ftang; sr=erik; patches

from IBM bidi project (e.g. Arabic, Hebrew)
This commit is contained in:
erik%netscape.com 2001-04-11 23:02:32 +00:00
Родитель 68efd66d1e
Коммит 8d42ec8e4b
6 изменённых файлов: 208 добавлений и 0 удалений

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

@ -765,6 +765,15 @@ public:
#endif
#ifdef IBMBIDI
/**
* Let the device context know whether we want text reordered with
* right-to-left base direction
*/
NS_IMETHOD SetRightToLeftText(PRBool aIsRTL) = 0;
#endif // IBMBIDI
#ifdef USE_IMG2
/* [noscript] void drawImage (in imgIContainer aImage, [const] in nsRect aSrcRect, [const] in nsPoint aDestPoint); */
NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint) = 0;
@ -803,6 +812,18 @@ public:
*/
#define NS_RENDERING_HINT_REMOTE_RENDERING 0x2
/**
* This bit, when set, indicates that the system provides support for
* the reordering of bidirectional text
*/
#define NS_RENDERING_HINT_BIDI_REORDERING 0x4
/**
* This bit, when set, indicates that the system provides support for
* Arabic shaping
*/
#define NS_RENDERING_HINT_ARABIC_SHAPING 0x8
//flags for copy CopyOffScreenBits
//when performing the blit, use the region, if any,

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

@ -91,6 +91,14 @@ public:
*/
NS_IMETHOD FillStdPolygon(const nsPoint aPoints[], PRInt32 aNumPoints) { return NS_OK; }
#ifdef IBMBIDI
/**
* Let the device context know whether we want text reordered with
* right-to-left base direction
*/
NS_IMETHOD SetRightToLeftText(PRBool aIsRTL);
#endif // IBMBIDI
#ifdef USE_IMG2
NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint);
NS_IMETHOD DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect);

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

@ -427,6 +427,18 @@ PRInt32 flag = NS_COPYBITS_TO_BACK_BUFFER | NS_COPYBITS_XFORM_DEST_VALUES;
}
}
#ifdef IBMBIDI
/**
* Let the device context know whether we want text reordered with
* right-to-left base direction
*/
NS_IMETHODIMP
nsRenderingContextImpl::SetRightToLeftText(PRBool aIsRTL)
{
return NS_OK;
}
#endif // IBMBIDI
/** ---------------------------------------------------
* See documentation in nsRenderingContextImpl.h
* @update 3/29/00 dwc

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

@ -427,6 +427,18 @@ PRInt32 flag = NS_COPYBITS_TO_BACK_BUFFER | NS_COPYBITS_XFORM_DEST_VALUES;
}
}
#ifdef IBMBIDI
/**
* Let the device context know whether we want text reordered with
* right-to-left base direction
*/
NS_IMETHODIMP
nsRenderingContextImpl::SetRightToLeftText(PRBool aIsRTL)
{
return NS_OK;
}
#endif // IBMBIDI
/** ---------------------------------------------------
* See documentation in nsRenderingContextImpl.h
* @update 3/29/00 dwc

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

@ -151,6 +151,11 @@ GraphicsState :: ~GraphicsState()
#define NOT_SETUP 0x33
static PRBool gIsWIN95 = NOT_SETUP;
#ifdef IBMBIDI
#define DONT_INIT 0
static DWORD gBidiInfo = NOT_SETUP;
#endif // IBMBIDI
// A few of the stock objects are needed all the time, so we just get them
// once
static HFONT gStockSystemFont = (HFONT)::GetStockObject(SYSTEM_FONT);
@ -173,6 +178,24 @@ nsRenderingContextWin :: nsRenderingContextWin()
}
else {
gIsWIN95 = PR_TRUE;
#ifdef IBMBIDI
if ( (os.dwMajorVersion < 4)
|| ( (os.dwMajorVersion == 4) && (os.dwMinorVersion == 0) ) ) {
// Windows 95 or earlier: assume it's not Bidi
gBidiInfo = DONT_INIT;
}
else if (os.dwMajorVersion >= 4) {
// Windows 98 or later
UINT cp = ::GetACP();
if (1256 == cp) {
gBidiInfo = GCP_REORDER | GCP_GLYPHSHAPE;
}
else if (1255 == cp) {
gBidiInfo = GCP_REORDER;
}
}
#endif // IBMBIDI
}
}
@ -197,6 +220,9 @@ nsRenderingContextWin :: nsRenderingContextWin()
mMainSurface = nsnull;
mStateCache = new nsVoidArray();
#ifdef IBMBIDI
mRightToLeftText = PR_FALSE;
#endif
//create an initial GraphicsState
@ -597,6 +623,16 @@ nsRenderingContextWin :: GetHints(PRUint32& aResult)
if (gIsWIN95)
result |= NS_RENDERING_HINT_FAST_8BIT_TEXT;
#ifdef IBMBIDI
if (NOT_SETUP == gBidiInfo) {
InitBidiInfo();
}
if (GCP_REORDER == (gBidiInfo & GCP_REORDER) )
result |= NS_RENDERING_HINT_BIDI_REORDERING;
if (GCP_GLYPHSHAPE == (gBidiInfo & GCP_GLYPHSHAPE) )
result |= NS_RENDERING_HINT_ARABIC_SHAPING;
#endif // IBMBIDI
aResult = result;
return NS_OK;
@ -1501,6 +1537,16 @@ NS_IMETHODIMP nsRenderingContextWin :: GetWidth(PRUnichar ch, nscoord &aWidth, P
{
PRUnichar buf[1];
buf[0] = ch;
#ifdef IBMBIDI
WORD charType;
::GetStringTypeW(CT_CTYPE3, &ch, 1, &charType);
if ((charType & C3_DIACRITIC) && !(charType & C3_ALPHA)) {
// aWidth = 0;
GetWidth(buf, 1, aWidth, aFontID);
aWidth *=-1;
return NS_OK;
}
#endif
return GetWidth(buf, 1, aWidth, aFontID);
}
@ -2149,6 +2195,13 @@ NS_IMETHODIMP nsRenderingContextWin :: DrawString(const PRUnichar *aString, PRUi
PRUint32 start = 0;
for (PRUint32 i = 0; i < aLength; i++) {
PRUnichar c = pstr[i];
#ifdef IBMBIDI
if (mRightToLeftText) {
c = pstr[aLength - i - 1];
}
#endif // IBMBIDI
nsFontWin* currFont = nsnull;
nsFontWin** font = metrics->mLoadedFonts;
nsFontWin** end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
@ -2187,6 +2240,13 @@ FoundFont:
}
}
else {
#ifdef IBMBIDI
if (mRightToLeftText) {
prevFont->DrawString(mDC, x, y, &pstr[aLength - i], i - start);
x += prevFont->GetWidth(mDC, &pstr[aLength - i], i - start);
}
else
#endif // IBMBIDI
{
prevFont->DrawString(mDC, x, y, &pstr[start], i - start);
x += prevFont->GetWidth(mDC, &pstr[start], i - start);
@ -2227,6 +2287,12 @@ FoundFont:
}
}
else {
#ifdef IBMBIDI
if (mRightToLeftText) {
prevFont->DrawString(mDC, x, y, &pstr[aLength - i], i - start);
}
else
#endif // IBMBIDI
{
prevFont->DrawString(mDC, x, y, &pstr[start], i - start);
}
@ -3461,5 +3527,84 @@ nsRenderingContextWin::ConditionRect(nsRect& aSrcRect, RECT& aDestRect)
: (aSrcRect.x+aSrcRect.width);
}
#ifdef IBMBIDI
/**
* Let the device context know whether we want text reordered with
* right-to-left base direction. The Windows implementation does this
* by setting the fuOptions parameter to ETO_RTLREADING in calls to
* ExtTextOut()
*/
NS_IMETHODIMP
nsRenderingContextWin::SetRightToLeftText(PRBool aIsRTL)
{
// Only call SetTextAlign if the new value is different from the
// current value
if (aIsRTL != mRightToLeftText) {
UINT flags = ::GetTextAlign(mDC);
if (aIsRTL) {
flags |= TA_RTLREADING;
}
else {
flags &= (~TA_RTLREADING);
}
::SetTextAlign(mDC, flags);
}
mRightToLeftText = aIsRTL;
return NS_OK;
}
/**
* Init <code>gBidiInfo</code> with reordering and shaping
* capabilities of the system
*/
void
nsRenderingContextWin::InitBidiInfo()
{
if (NOT_SETUP == gBidiInfo) {
gBidiInfo = DONT_INIT;
const PRUnichar araAin = 0x0639;
const PRUnichar one = 0x0031;
int distanceArray[2];
PRUnichar glyphArray[2];
PRUnichar outStr[] = {0, 0};
GCP_RESULTSW gcpResult;
gcpResult.lStructSize = sizeof(GCP_RESULTS);
gcpResult.lpOutString = outStr; // Output string
gcpResult.lpOrder = nsnull; // Ordering indices
gcpResult.lpDx = distanceArray; // Distances between character cells
gcpResult.lpCaretPos = nsnull; // Caret positions
gcpResult.lpClass = nsnull; // Character classifications
gcpResult.lpGlyphs = glyphArray; // Character glyphs
gcpResult.nGlyphs = 2; // Array size
PRUnichar inStr[] = {araAin, one};
if (::GetCharacterPlacementW(mDC, inStr, 2, 0, &gcpResult, GCP_REORDER)
&& (inStr[0] == outStr[1]) ) {
gBidiInfo = GCP_REORDER | GCP_GLYPHSHAPE;
#ifdef NS_DEBUG
printf("System has shaping\n");
#endif
}
else {
const PRUnichar hebAlef = 0x05D0;
inStr[0] = hebAlef;
inStr[1] = one;
if (::GetCharacterPlacementW(mDC, inStr, 2, 0, &gcpResult, GCP_REORDER)
&& (inStr[0] == outStr[1]) ) {
gBidiInfo = GCP_REORDER;
#ifdef NS_DEBUG
printf("System has Bidi\n");
#endif
}
}
}
}
#endif // IBMBIDI

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

@ -199,6 +199,10 @@ public:
PRInt32* aFontID);
#endif
#ifdef IBMBIDI
NS_IMETHOD SetRightToLeftText(PRBool aIsRTL);
#endif // IBMBIDI
protected:
void SetupFontAndColor(void);
@ -224,6 +228,9 @@ private:
HPEN SetupDashedPen(void);
HPEN SetupDottedPen(void);
void PushClipState(void);
#ifdef IBMBIDI
void InitBidiInfo(void);
#endif // IBMBIDI
protected:
nscolor mCurrentColor;
@ -260,6 +267,9 @@ protected:
#ifdef NS_DEBUG
PRBool mInitialized;
#endif
#ifdef IBMBIDI
PRBool mRightToLeftText;
#endif // IBMBIDI
};