r=mkaply,jkobal a=blizzard
Various OS/2 cleanup - fonts, print, and arcs
This commit is contained in:
mkaply%us.ibm.com 2000-11-29 22:42:28 +00:00
Родитель 0c24351641
Коммит bc669c7450
9 изменённых файлов: 459 добавлений и 264 удалений

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

@ -51,12 +51,12 @@ static char* nav4rounding = "font.size.nav4rounding";
nsDeviceContextOS2 :: nsDeviceContextOS2() nsDeviceContextOS2 :: nsDeviceContextOS2()
: DeviceContextImpl() : DeviceContextImpl()
{ {
mSurface = nsnull; mSurface = NULL;
mPaletteInfo.isPaletteDevice = PR_FALSE; mPaletteInfo.isPaletteDevice = PR_FALSE;
mPaletteInfo.sizePalette = 0; mPaletteInfo.sizePalette = 0;
mPaletteInfo.numReserved = 0; mPaletteInfo.numReserved = 0;
mPaletteInfo.palette = nsnull; mPaletteInfo.palette = NULL;
mDC = nsnull; mPrintDC = NULL;
mPixelScale = 1.0f; mPixelScale = 1.0f;
mWidth = -1; mWidth = -1;
mHeight = -1; mHeight = -1;
@ -97,11 +97,11 @@ nsDeviceContextOS2 :: nsDeviceContextOS2()
nsDeviceContextOS2::~nsDeviceContextOS2() nsDeviceContextOS2::~nsDeviceContextOS2()
{ {
if(mDC) if(mPrintDC)
{ {
GpiAssociate(mPS, 0); GpiAssociate(mPrintPS, 0);
GpiDestroyPS(mPS); GpiDestroyPS(mPrintPS);
PrnCloseDC(mDC); PrnCloseDC(mPrintDC);
} }
if (!mPaletteInfo.isPaletteDevice) { if (!mPaletteInfo.isPaletteDevice) {
@ -131,7 +131,7 @@ nsresult nsDeviceContextOS2::Init( nsNativeDeviceContext aContext,
float origscale, newscale; float origscale, newscale;
float t2d, a2d; float t2d, a2d;
mDC = (HDC)aContext; mPrintDC = (HDC)aContext;
#ifdef XP_OS2 #ifdef XP_OS2
// Create a print PS now. This is necessary 'cos we need it from // Create a print PS now. This is necessary 'cos we need it from
@ -140,11 +140,11 @@ nsresult nsDeviceContextOS2::Init( nsNativeDeviceContext aContext,
// PS can be associated with a given DC, and we can't get that PS from // PS can be associated with a given DC, and we can't get that PS from
// the DC (really?). And it would be slow :-) // the DC (really?). And it would be slow :-)
SIZEL sizel = { 0 , 0 }; SIZEL sizel = { 0 , 0 };
mPS = GpiCreatePS( 0/*hab*/, mDC, &sizel, mPrintPS = GpiCreatePS( 0/*hab*/, mPrintDC, &sizel,
PU_PELS | GPIT_MICRO | GPIA_ASSOC); PU_PELS | GPIT_MICRO | GPIA_ASSOC);
#endif #endif
CommonInit( mDC); CommonInit( mPrintDC);
GetTwipsToDevUnits( newscale); GetTwipsToDevUnits( newscale);
aOrigContext->GetTwipsToDevUnits( origscale); aOrigContext->GetTwipsToDevUnits( origscale);
@ -159,7 +159,7 @@ nsresult nsDeviceContextOS2::Init( nsNativeDeviceContext aContext,
#ifdef XP_OS2 #ifdef XP_OS2
HCINFO hcinfo; HCINFO hcinfo;
PrnQueryHardcopyCaps( mDC, &hcinfo); PrnQueryHardcopyCaps( mPrintDC, &hcinfo);
mWidth = hcinfo.xPels; mWidth = hcinfo.xPels;
mHeight = hcinfo.yPels; mHeight = hcinfo.yPels;
// XXX hsb says there are margin problems, must be from here... // XXX hsb says there are margin problems, must be from here...
@ -291,7 +291,7 @@ nsDeviceContextOS2 :: FindScreen ( nsIScreen** outScreen )
// Create a rendering context against our hdc for a printer // Create a rendering context against our hdc for a printer
nsresult nsDeviceContextOS2::CreateRenderingContext( nsIRenderingContext *&aContext) nsresult nsDeviceContextOS2::CreateRenderingContext( nsIRenderingContext *&aContext)
{ {
NS_ASSERTION( mDC, "CreateRenderingContext for non-print DC"); NS_ASSERTION( mPrintDC, "CreateRenderingContext for non-print DC");
nsIRenderingContext *pContext = new nsRenderingContextOS2; nsIRenderingContext *pContext = new nsRenderingContextOS2;
if (!pContext) if (!pContext)
@ -303,7 +303,7 @@ nsresult nsDeviceContextOS2::CreateRenderingContext( nsIRenderingContext *&aCont
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(surf); NS_ADDREF(surf);
surf->Init( mPS, mWidth, mHeight); surf->Init( mPrintPS, mWidth, mHeight);
nsresult rc = pContext->Init( this, (void*)((nsDrawingSurfaceOS2 *) surf)); nsresult rc = pContext->Init( this, (void*)((nsDrawingSurfaceOS2 *) surf));
@ -320,7 +320,7 @@ nsresult nsDeviceContextOS2::CreateRenderingContext( nsIRenderingContext *&aCont
NS_IMETHODIMP nsDeviceContextOS2 :: SupportsNativeWidgets(PRBool &aSupportsWidgets) NS_IMETHODIMP nsDeviceContextOS2 :: SupportsNativeWidgets(PRBool &aSupportsWidgets)
{ {
if (nsnull == mDC) if (nsnull == mPrintDC)
aSupportsWidgets = PR_TRUE; aSupportsWidgets = PR_TRUE;
else else
aSupportsWidgets = PR_FALSE; aSupportsWidgets = PR_FALSE;
@ -811,6 +811,10 @@ NS_IMETHODIMP nsDeviceContextOS2 :: GetDeviceContextFor(nsIDeviceContextSpec *aD
HDC dc = PrnOpenDC(pq, "Mozilla"); HDC dc = PrnOpenDC(pq, "Mozilla");
if (!dc) {
PMERROR("DevOpenDC");
} /* endif */
return ((nsDeviceContextOS2 *)aContext)->Init((nsNativeDeviceContext)dc, this); return ((nsDeviceContextOS2 *)aContext)->Init((nsNativeDeviceContext)dc, this);
} }
@ -853,10 +857,10 @@ nsresult nsDeviceContextOS2::CreateFontAliasTable()
// Printing ------------------------------------------------------------------ // Printing ------------------------------------------------------------------
nsresult nsDeviceContextOS2::BeginDocument() nsresult nsDeviceContextOS2::BeginDocument()
{ {
NS_ASSERTION(mDC, "BeginDocument for non-print DC"); NS_ASSERTION(mPrintDC, "BeginDocument for non-print DC");
if( mPrintState == nsPrintState_ePreBeginDoc) if( mPrintState == nsPrintState_ePreBeginDoc)
{ {
PrnStartJob( mDC, "Warpzilla NGLayout job"); PrnStartJob( mPrintDC, "Warpzilla NGLayout job");
printf( "BeginDoc\n"); printf( "BeginDoc\n");
mPrintState = nsPrintState_eBegunDoc; mPrintState = nsPrintState_eBegunDoc;
} }
@ -865,7 +869,7 @@ nsresult nsDeviceContextOS2::BeginDocument()
nsresult nsDeviceContextOS2::EndDocument() nsresult nsDeviceContextOS2::EndDocument()
{ {
PrnEndJob( mDC); PrnEndJob( mPrintDC);
mPrintState = nsPrintState_ePreBeginDoc; mPrintState = nsPrintState_ePreBeginDoc;
printf("EndDoc\n"); printf("EndDoc\n");
return NS_OK; return NS_OK;
@ -877,7 +881,7 @@ nsresult nsDeviceContextOS2::BeginPage()
mPrintState = nsPrintState_eBegunFirstPage; mPrintState = nsPrintState_eBegunFirstPage;
else else
{ {
PrnNewPage( mDC); PrnNewPage( mPrintDC);
printf("NewPage"); printf("NewPage");
} }
return NS_OK; return NS_OK;
@ -891,7 +895,7 @@ nsresult nsDeviceContextOS2::EndPage()
BOOL nsDeviceContextOS2::isPrintDC() BOOL nsDeviceContextOS2::isPrintDC()
{ {
if ( mDC == nsnull ) if ( mPrintDC == nsnull )
return 0; return 0;
else else

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

@ -102,8 +102,8 @@ protected:
static PRUint32 sNumberOfScreens; static PRUint32 sNumberOfScreens;
public: public:
HDC mDC; HDC mPrintDC;
HPS mPS; HPS mPrintPS;
static PRBool gRound; static PRBool gRound;
static int PrefChanged(const char* aPref, void* aClosure); static int PrefChanged(const char* aPref, void* aClosure);

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

@ -181,10 +181,11 @@ InitGlobals(void)
nsFontMetricsOS2::nsFontMetricsOS2() nsFontMetricsOS2::nsFontMetricsOS2()
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mSpaceWidth = 0;
++gFontMetricsOS2Count; ++gFontMetricsOS2Count;
// members are zeroed by new operator (hmm) - yeah right // members are zeroed by new operator (hmm) - yeah right
mTriedAllGenerics = 0; mTriedAllGenerics = 0;
} }
nsFontMetricsOS2::~nsFontMetricsOS2() nsFontMetricsOS2::~nsFontMetricsOS2()
@ -287,7 +288,6 @@ static nsFontFamilyName gFamilyNameTable[] =
{ "times roman", "Times New Roman" }, { "times roman", "Times New Roman" },
{ "times new roman", "Times New Roman" }, { "times new roman", "Times New Roman" },
{ "arial", "Arial" }, { "arial", "Arial" },
{ "helvetica", "Helv" },
{ "courier", "Courier" }, { "courier", "Courier" },
{ "courier new", "Courier New" }, { "courier new", "Courier New" },
@ -304,7 +304,6 @@ static nsFontFamilyName gFamilyNameTableDBCS[] =
{ "times roman", "Times New Roman" }, { "times roman", "Times New Roman" },
{ "times new roman", "Times New Roman" }, { "times new roman", "Times New Roman" },
{ "arial", "Arial" }, { "arial", "Arial" },
{ "helvetica", "Helv Combined" },
{ "courier", "Courier" }, { "courier", "Courier" },
{ "courier new", "Courier New" }, { "courier new", "Courier New" },
@ -567,8 +566,8 @@ nsresult res;
HWND win = NULL; HWND win = NULL;
HDC ps = NULL; HDC ps = NULL;
if (NULL != mDeviceContext->mDC){ if (NULL != mDeviceContext->mPrintDC){
ps = mDeviceContext->mPS; ps = mDeviceContext->mPrintPS;
} else { } else {
win = (HWND)mDeviceContext->mWidget; win = (HWND)mDeviceContext->mWidget;
ps = ::WinGetPS(win); ps = ::WinGetPS(win);
@ -645,19 +644,10 @@ HDC ps = NULL;
if (!fh) if (!fh)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
// 2) Get a representative PS for doing font queries into
HPS hps;
if (NULL != mDeviceContext->mDC){
hps = mDeviceContext->mPS;
} else {
hps = WinGetPS((HWND)mDeviceContext->mWidget);
}
// 3) Work out what our options are wrt. image/outline, prefer image. // 3) Work out what our options are wrt. image/outline, prefer image.
BOOL bOutline = FALSE, bImage = FALSE; BOOL bOutline = FALSE, bImage = FALSE;
long lFonts = 0; int i; long lFonts = 0; int i;
PFONTMETRICS pMetrics = getMetrics( lFonts, szFamily, hps); PFONTMETRICS pMetrics = getMetrics( lFonts, szFamily, ps);
for( i = 0; i < lFonts && !(bImage && bOutline); i++) for( i = 0; i < lFonts && !(bImage && bOutline); i++)
if( pMetrics[ i].fsDefn & FM_DEFN_OUTLINE) bOutline = TRUE; if( pMetrics[ i].fsDefn & FM_DEFN_OUTLINE) bOutline = TRUE;
@ -676,7 +666,7 @@ HDC ps = NULL;
0, 0,
bItalic ? FTYPE_ITALIC : 0 }; bItalic ? FTYPE_ITALIC : 0 };
ULONG rc = GpiQueryFaceString( hps, szFamily, &fnd, ULONG rc = GpiQueryFaceString( ps, szFamily, &fnd,
FACESIZE, fh->fattrs.szFacename); FACESIZE, fh->fattrs.szFacename);
if( rc == GPI_ERROR) if( rc == GPI_ERROR)
{ // no real font, fake it { // no real font, fake it
@ -704,6 +694,7 @@ HDC ps = NULL;
if (!strcmp(name, gCharSetInfo[j].mLangGroup)) { if (!strcmp(name, gCharSetInfo[j].mLangGroup)) {
fh->fattrs.usCodePage = gCharSetInfo[j].mCodePage; fh->fattrs.usCodePage = gCharSetInfo[j].mCodePage;
mCodePage = gCharSetInfo[j].mCodePage; mCodePage = gCharSetInfo[j].mCodePage;
break;
} /* endif */ } /* endif */
} /* endif */ } /* endif */
} /* endfor */ } /* endfor */
@ -738,10 +729,10 @@ HDC ps = NULL;
// required, substituting an outline if necessary. // required, substituting an outline if necessary.
if( bImage) if( bImage)
{ {
HDC hdc = GpiQueryDevice( hps); HDC hdc = GpiQueryDevice( ps);
long res[ 2]; long res[ 2];
DevQueryCaps( hdc, CAPS_HORIZONTAL_FONT_RES, 2, res); DevQueryCaps( hdc, CAPS_HORIZONTAL_FONT_RES, 2, res);
pMetrics = getMetrics( lFonts, fh->fattrs.szFacename, hps); pMetrics = getMetrics( lFonts, fh->fattrs.szFacename, ps);
int curPoints = 0; int curPoints = 0;
@ -775,12 +766,12 @@ HDC ps = NULL;
// 9) Record font handle & record various font metrics to cache // 9) Record font handle & record various font metrics to cache
mFontHandle = fh; mFontHandle = fh;
if( GPI_ERROR == GpiCreateLogFont( hps, 0, 1, &fh->fattrs)) if( GPI_ERROR == GpiCreateLogFont( ps, 0, 1, &fh->fattrs))
PMERROR( "GpiCreateLogFont"); PMERROR( "GpiCreateLogFont");
fh->SelectIntoPS( hps, 1); fh->SelectIntoPS( ps, 1);
FONTMETRICS fm; FONTMETRICS fm;
GpiQueryFontMetrics( hps, sizeof fm, &fm); GpiQueryFontMetrics( ps, sizeof fm, &fm);
float dev2app; float dev2app;
mDeviceContext->GetDevUnitsToAppUnits( dev2app); mDeviceContext->GetDevUnitsToAppUnits( dev2app);
@ -814,29 +805,26 @@ HDC ps = NULL;
mUnderlinePosition = NSToCoordRound( -fm.lUnderscorePosition * dev2app); mUnderlinePosition = NSToCoordRound( -fm.lUnderscorePosition * dev2app);
mUnderlineSize = NSToCoordRound( fm.lUnderscoreSize * dev2app); mUnderlineSize = NSToCoordRound( fm.lUnderscoreSize * dev2app);
// OS/2 field (needs to be kept in sync with mMaxAscent) mAveCharWidth = NSToCoordRound( fm.lAveCharWidth * dev2app);
mDevMaxAscent = fm.lMaxAscender;
// Cache the width of a single space.
SIZEL size;
::GetTextExtentPoint32(ps, " ", 1, &size);
mSpaceWidth = NSToCoordRound(float(size.cx) * dev2app);
// 10) Clean up // 10) Clean up
GpiSetCharSet( hps, LCID_DEFAULT); GpiSetCharSet( ps, LCID_DEFAULT);
if( !GpiDeleteSetId( hps, 1)) if( !GpiDeleteSetId( ps, 1))
PMERROR( "GpiDeleteSetID (FM)"); PMERROR( "GpiDeleteSetID (FM)");
if (NULL == mDeviceContext->mDC) if (NULL == mDeviceContext->mPrintDC)
WinReleasePS(hps); WinReleasePS(ps);
return NS_OK; return NS_OK;
} }
nscoord nsFontMetricsOS2::GetSpaceWidth( nsIRenderingContext *aRContext) nsresult nsFontMetricsOS2 :: GetSpaceWidth(nscoord &aSpaceWidth)
{ {
if( !mSpaceWidth) aSpaceWidth = mSpaceWidth;
{
char buf[1];
buf[0] = ' ';
aRContext->GetWidth( buf, 1, mSpaceWidth);
}
return mSpaceWidth;
} }
// Other metrics // Other metrics
@ -961,6 +949,13 @@ nsFontMetricsOS2::GetMaxHeight(nscoord &aHeight)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsFontMetricsOS2::GetAveCharWidth(nscoord &aAveCharWidth)
{
aAveCharWidth = mAveCharWidth;
return NS_OK;
}
nsGlobalFont* nsGlobalFont*
nsFontMetricsOS2::InitializeGlobalFonts(HPS aPS) nsFontMetricsOS2::InitializeGlobalFonts(HPS aPS)
{ {

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

@ -79,7 +79,33 @@ struct nsFontHandleOS2
class nsFontOS2 class nsFontOS2
{ {
public: public:
// nsFontWin(FATTRS* aFattrs, nsFontHandleOS2* aFont, PRUint32* aMap);
// virtual ~nsFontWin();
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
// virtual PRInt32 GetWidth(HPS aPS, const PRUnichar* aString,
// PRUint32 aLength) = 0;
// XXX return width from DrawString
// virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
// const PRUnichar* aString, PRUint32 aLength) = 0;
#ifdef MOZ_MATHML
virtual nsresult
GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics) = 0;
#ifdef NS_DEBUG
// virtual void DumpFontInfo() = 0;
#endif // NS_DEBUG
#endif
char mName[FACESIZE]; char mName[FACESIZE];
nsFontHandleOS2* mFont;
// PRUint32* mMap;
#ifdef MOZ_MATHML
nsCharacterMap* mCMAP;
#endif
}; };
@ -125,7 +151,9 @@ class nsFontMetricsOS2 : public nsIFontMetrics
NS_IMETHOD GetFont( const nsFont *&aFont); NS_IMETHOD GetFont( const nsFont *&aFont);
NS_IMETHOD GetLangGroup(nsIAtom** aLangGroup); NS_IMETHOD GetLangGroup(nsIAtom** aLangGroup);
NS_IMETHOD GetFontHandle( nsFontHandle &aHandle); NS_IMETHOD GetFontHandle( nsFontHandle &aHandle);
NS_IMETHOD GetAveCharWidth(nscoord &aAveCharWidth);
virtual nsresult GetSpaceWidth(nscoord &aSpaceWidth);
virtual nsFontOS2* FindGlobalFont(HPS aPS, PRUnichar aChar); virtual nsFontOS2* FindGlobalFont(HPS aPS, PRUnichar aChar);
virtual nsFontOS2* FindGenericFont(HPS aPS, PRUnichar aChar); virtual nsFontOS2* FindGenericFont(HPS aPS, PRUnichar aChar);
virtual nsFontOS2* FindLocalFont(HPS aPS, PRUnichar aChar); virtual nsFontOS2* FindLocalFont(HPS aPS, PRUnichar aChar);
@ -134,10 +162,6 @@ class nsFontMetricsOS2 : public nsIFontMetrics
virtual nsFontOS2* LoadGenericFont(HPS aPS, PRUnichar aChar, char** aName); virtual nsFontOS2* LoadGenericFont(HPS aPS, PRUnichar aChar, char** aName);
virtual nsFontOS2* LoadFont(HPS aPS, nsString* aName); virtual nsFontOS2* LoadFont(HPS aPS, nsString* aName);
// for drawing text
PRUint32 GetDevMaxAscender() const { return mDevMaxAscent; }
nscoord GetSpaceWidth( nsIRenderingContext *aRContext);
static PLHashTable* gFontMaps; static PLHashTable* gFontMaps;
static nsGlobalFont* gGlobalFonts; static nsGlobalFont* gGlobalFonts;
static int gGlobalFontsCount; static int gGlobalFontsCount;
@ -166,8 +190,7 @@ class nsFontMetricsOS2 : public nsIFontMetrics
nscoord mMaxAdvance; nscoord mMaxAdvance;
nscoord mSpaceWidth; nscoord mSpaceWidth;
nscoord mXHeight; nscoord mXHeight;
nscoord mAveCharWidth;
PRUint32 mDevMaxAscent;
nsFontHandleOS2 *mFontHandle; nsFontHandleOS2 *mFontHandle;
nsDeviceContextOS2 *mDeviceContext; nsDeviceContextOS2 *mDeviceContext;

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

@ -81,6 +81,9 @@ struct nsGfxModuleData
}; };
int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, char* szBuffer, ULONG ulSize ); int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, char* szBuffer, ULONG ulSize );
BOOL GetTextExtentPoint32(HPS aPS, const char* aString, int aLength, PSIZEL aSizeL);
BOOL ExtTextOut(HPS aPS, int X, int Y, UINT fuOptions, const RECTL* lprc,
const char* aString, unsigned int aLength, const int* pDx);
BOOL IsDBCS(); BOOL IsDBCS();

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

@ -393,6 +393,52 @@ int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, c
return ulSize - cplen; return ulSize - cplen;
} }
BOOL GetTextExtentPoint32(HPS aPS, const char* aString, int aLength, PSIZEL aSizeL)
{
POINTL ptls[5];
PRUint32 tLength = aLength;
const char* tString = aString;
aSizeL->cx = 0;
while(tLength)
{
ULONG thislen = min(tLength, 512);
GpiQueryTextBox(aPS, thislen, (PCH) tString, 5, ptls);
aSizeL->cx += ptls[TXTBOX_CONCAT].x;
tLength -= thislen;
tString += thislen;
}
aSizeL->cy = ptls[TXTBOX_TOPLEFT].y - ptls[TXTBOX_BOTTOMLEFT].y;
return TRUE;
}
BOOL ExtTextOut(HPS aPS, int X, int Y, UINT fuOptions, const RECTL* lprc,
const char* aString, unsigned int aLength, const int* pDx)
{
POINTL ptl = {X, Y};
GpiMove( aPS, &ptl);
PRUint32 lLength = aLength;
const char *aStringTemp = aString;
// GpiCharString has a max length of 512 chars at a time...
while( lLength)
{
ULONG thislen = min( lLength, 512);
GpiCharStringPos( aPS, nsnull,
pDx == nsnull ? 0 : CHS_VECTOR,
thislen, (PCH)aStringTemp,
pDx == nsnull ? nsnull : (PLONG) pDx);
lLength -= thislen;
aStringTemp += thislen;
pDx += thislen;
}
return TRUE;
}
BOOL IsDBCS() BOOL IsDBCS()
{ {
return bIsDBCS; return bIsDBCS;

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

@ -221,6 +221,9 @@ nsresult nsImageOS2::Draw( nsIRenderingContext &aContext,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSW, PRInt32 aSH, PRInt32 aSX, PRInt32 aSY, PRInt32 aSW, PRInt32 aSH,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDW, PRInt32 aDH) PRInt32 aDX, PRInt32 aDY, PRInt32 aDW, PRInt32 aDH)
{ {
if (aDW == 0 || aDH == 0 || aSW == 0 || aSH == 0) // Nothing to draw
return NS_OK;
// Find target rect in OS/2 coords. // Find target rect in OS/2 coords.
nsRect trect( aDX, aDY, aDW, aDH); nsRect trect( aDX, aDY, aDW, aDH);
RECTL rcl; RECTL rcl;
@ -365,9 +368,8 @@ void nsImageOS2::DrawBitmap( HPS hps, LONG lCount, PPOINTL pPoints,
void *pBits = bIsMask ? mAlphaBits : mImageBits; void *pBits = bIsMask ? mAlphaBits : mImageBits;
if( GPI_ERROR == GpiDrawBits( hps, pBits, pBmp2, if (GPI_ERROR == GpiDrawBits (hps, pBits, pBmp2, lCount, pPoints, lRop, BBO_OR))
lCount, pPoints, lRop, BBO_OR)) PMERROR( "GpiDrawBits - DrawBitmap");
PMERROR( "GpiDrawBits");
delete pMaskInfo; delete pMaskInfo;
} }

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

@ -54,10 +54,9 @@
#include "prprf.h" #include "prprf.h"
// helper clip region functions - defined at the bottom of this file. // helper clip region functions - defined at the bottom of this file.
LONG GpiCombineClipRegion( HPS hps, HRGN hrgnCombine, LONG lOp); LONG OS2_CombineClipRegion( HPS hps, HRGN hrgnCombine, LONG lMode);
HRGN GpiCopyClipRegion( HPS hps); HRGN OS2_CopyClipRegion( HPS hps);
#define GpiDestroyClipRegion(hps) GpiCombineClipRegion(hps, 0, CRGN_COPY) #define OS2_SetClipRegion2(hps,hrgn) OS2_CombineClipRegion(hps, hrgn, CRGN_COPY)
#define GpiSetClipRegion2(hps,hrgn) GpiCombineClipRegion(hps, hrgn, CRGN_COPY)
// Use these instead of native GpiSave/RestorePS because: need to store ---- // Use these instead of native GpiSave/RestorePS because: need to store ----
// more information, and need to be able to push from onscreen & pop onto // more information, and need to be able to push from onscreen & pop onto
@ -510,7 +509,7 @@ nsresult nsRenderingContextOS2::PushState()
NS_IF_ADDREF( mFontMetrics); NS_IF_ADDREF( mFontMetrics);
// clip region: get current & copy it. // clip region: get current & copy it.
state->mClipRegion = GpiCopyClipRegion( mSurface->mPS); state->mClipRegion = OS2_CopyClipRegion( mSurface->mPS);
// push state onto stack // push state onto stack
state->mNext = mStateStack; state->mNext = mStateStack;
@ -540,7 +539,7 @@ nsresult nsRenderingContextOS2::PopState( PRBool &aClipEmpty)
state->mFontMetrics = nsnull; state->mFontMetrics = nsnull;
// Clip region // Clip region
GpiSetClipRegion2( mSurface->mPS, state->mClipRegion); OS2_SetClipRegion2( mSurface->mPS, state->mClipRegion);
if( state->mClipRegion != 0) if( state->mClipRegion != 0)
{ {
state->mClipRegion = 0; state->mClipRegion = 0;
@ -649,9 +648,9 @@ nsresult nsRenderingContextOS2::SetClipRect( const nsRect& aRect, nsClipCombine
NS2PM_INEX( trect, rcl); NS2PM_INEX( trect, rcl);
HRGN hrgn = GpiCreateRegion( mSurface->mPS, 1, &rcl); HRGN hrgn = GpiCreateRegion( mSurface->mPS, 1, &rcl);
if( hrgn && aCombine == nsClipCombine_kReplace) if( hrgn && aCombine == nsClipCombine_kReplace)
lrc = GpiSetClipRegion2( mSurface->mPS, hrgn); lrc = OS2_SetClipRegion2( mSurface->mPS, hrgn);
else if( hrgn) else if( hrgn)
lrc = GpiCombineClipRegion( mSurface->mPS, hrgn, CRGN_OR); lrc = OS2_CombineClipRegion( mSurface->mPS, hrgn, CRGN_OR);
break; break;
} }
default: default:
@ -718,7 +717,7 @@ nsresult nsRenderingContextOS2::SetClipRegion( const nsIRegion &aRegion, nsClipC
break; break;
} }
long lrc = GpiCombineClipRegion( mSurface->mPS, hrgn, cmode); long lrc = OS2_CombineClipRegion( mSurface->mPS, hrgn, cmode);
aClipEmpty = (lrc == RGN_NULL) ? PR_TRUE : PR_FALSE; aClipEmpty = (lrc == RGN_NULL) ? PR_TRUE : PR_FALSE;
@ -764,7 +763,7 @@ nsresult nsRenderingContextOS2::GetClipRegion( nsIRegion **aRegion)
*/ */
nsresult nsRenderingContextOS2::CopyClipRegion(nsIRegion &aRegion) nsresult nsRenderingContextOS2::CopyClipRegion(nsIRegion &aRegion)
{ {
HRGN hr = GpiCopyClipRegion(mSurface->mPS); HRGN hr = OS2_CopyClipRegion(mSurface->mPS);
if (hr == HRGN_ERROR) if (hr == HRGN_ERROR)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -883,7 +882,7 @@ void nsRenderingContextOS2::SetupDrawingColor( BOOL bForce)
areaBundle.lColor = lColor; areaBundle.lColor = lColor;
lineBundle.lColor = lColor; lineBundle.lColor = lColor;
if (((nsDeviceContextOS2 *) mContext)->mDC ) if (((nsDeviceContextOS2 *) mContext)->mPrintDC )
{ {
areaBundle.lBackColor = CLR_BACKGROUND; areaBundle.lBackColor = CLR_BACKGROUND;
@ -1160,8 +1159,7 @@ nsresult nsRenderingContextOS2::DrawArc( const nsRect& aRect,
float aStartAngle, float aEndAngle) float aStartAngle, float aEndAngle)
{ {
nsRect tRect( aRect); nsRect tRect( aRect);
PMDrawArc( tRect, PR_FALSE, PR_FALSE, PMDrawArc( tRect, PR_FALSE, PR_FALSE, aStartAngle, aEndAngle);
(PRInt32)aStartAngle, (PRInt32)aEndAngle);
return NS_OK; return NS_OK;
} }
@ -1169,8 +1167,7 @@ nsresult nsRenderingContextOS2::DrawArc( nscoord aX, nscoord aY, nscoord aWidth,
float aStartAngle, float aEndAngle) float aStartAngle, float aEndAngle)
{ {
nsRect tRect( aX, aY, aWidth, aHeight); nsRect tRect( aX, aY, aWidth, aHeight);
PMDrawArc( tRect, PR_FALSE, PR_FALSE, PMDrawArc( tRect, PR_FALSE, PR_FALSE, aStartAngle, aEndAngle);
(PRInt32)aStartAngle, (PRInt32)aEndAngle);
return NS_OK; return NS_OK;
} }
@ -1178,8 +1175,7 @@ nsresult nsRenderingContextOS2::FillArc( const nsRect& aRect,
float aStartAngle, float aEndAngle) float aStartAngle, float aEndAngle)
{ {
nsRect tRect( aRect); nsRect tRect( aRect);
PMDrawArc( tRect, PR_TRUE, PR_FALSE, PMDrawArc( tRect, PR_TRUE, PR_FALSE, aStartAngle, aEndAngle);
(PRInt32)aStartAngle, (PRInt32)aEndAngle);
return NS_OK; return NS_OK;
} }
@ -1187,14 +1183,12 @@ nsresult nsRenderingContextOS2::FillArc( nscoord aX, nscoord aY, nscoord aWidth,
float aStartAngle, float aEndAngle) float aStartAngle, float aEndAngle)
{ {
nsRect tRect( aX, aY, aWidth, aHeight); nsRect tRect( aX, aY, aWidth, aHeight);
PMDrawArc( tRect, PR_TRUE, PR_FALSE, PMDrawArc( tRect, PR_TRUE, PR_FALSE, aStartAngle, aEndAngle);
(PRInt32)aStartAngle, (PRInt32)aEndAngle);
return NS_OK; return NS_OK;
} }
void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled, void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled, PRBool bFull,
PRBool bFull, float start, float end)
PRInt32 start, PRInt32 end)
{ {
// convert coords // convert coords
mTMatrix.TransformCoord( &rect.x, &rect.y, &rect.width, &rect.height); mTMatrix.TransformCoord( &rect.x, &rect.y, &rect.width, &rect.height);
@ -1204,10 +1198,6 @@ void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled,
SetupDrawingColor(); SetupDrawingColor();
long lOps = DRO_OUTLINE;
if( bFilled)
lOps |= DRO_FILL;
// set arc params. // set arc params.
long lWidth = rect.width / 2; long lWidth = rect.width / 2;
long lHeight = rect.height / 2; long lHeight = rect.height / 2;
@ -1219,23 +1209,27 @@ void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled,
rcl.yBottom += lHeight; rcl.yBottom += lHeight;
GpiMove( mSurface->mPS, (PPOINTL)&rcl); GpiMove( mSurface->mPS, (PPOINTL)&rcl);
if( bFull) if( bFull)
{ {
long lOps = (bFilled) ? DRO_OUTLINEFILL : DRO_OUTLINE;
// draw ellipse // draw ellipse
GpiFullArc( mSurface->mPS, lOps, MAKEFIXED(1,0)); GpiFullArc( mSurface->mPS, lOps, MAKEFIXED(1,0));
} }
else else
{ {
PRInt32 Sweep = (end % 360) - (start % 360); FIXED StartAngle = (FIXED)(start * 65536.0) % MAKEFIXED (360, 0);
FIXED EndAngle = (FIXED)(end * 65536.0) % MAKEFIXED (360, 0);
FIXED SweepAngle = EndAngle - StartAngle;
if (Sweep < 0) Sweep += 360; if (SweepAngle < 0) SweepAngle += MAKEFIXED (360, 0);
// draw an arc or a pie // draw an arc or a pie
if( bFilled) if( bFilled)
{ {
GpiBeginArea( mSurface->mPS, BA_BOUNDARY); GpiBeginArea( mSurface->mPS, BA_BOUNDARY);
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), StartAngle, SweepAngle);
MAKEFIXED(start,0), MAKEFIXED(Sweep,0));
GpiEndArea( mSurface->mPS); GpiEndArea( mSurface->mPS);
} }
else else
@ -1243,12 +1237,10 @@ void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled,
// draw an invisible partialarc to get to the start of the arc. // draw an invisible partialarc to get to the start of the arc.
long lLineType = GpiQueryLineType( mSurface->mPS); long lLineType = GpiQueryLineType( mSurface->mPS);
GpiSetLineType( mSurface->mPS, LINETYPE_INVISIBLE); GpiSetLineType( mSurface->mPS, LINETYPE_INVISIBLE);
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), StartAngle, MAKEFIXED (0,0));
MAKEFIXED(0,0), MAKEFIXED(start,0));
// now draw a real arc // now draw a real arc
GpiSetLineType( mSurface->mPS, lLineType); GpiSetLineType( mSurface->mPS, lLineType);
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), StartAngle, SweepAngle);
MAKEFIXED(start,0), MAKEFIXED(Sweep,0));
} }
} }
} }
@ -1262,141 +1254,211 @@ NS_IMETHODIMP nsRenderingContextOS2::GetHints(PRUint32& aResult)
return NS_OK; return NS_OK;
} }
nsresult nsRenderingContextOS2::DrawString( const char *aString, NS_IMETHODIMP nsRenderingContextOS2 :: GetWidth(char ch, nscoord& aWidth)
PRUint32 aLength,
nscoord aX, nscoord aY,
const nscoord* aSpacing)
{ {
mTMatrix.TransformCoord( &aX, &aY); char buf[1];
POINTL ptl = { aX, aY }; buf[0] = ch;
NS2PM( &ptl, 1); return GetWidth(buf, 1, aWidth);
SetupFontAndColor();
// the pointl we are at is the top of the charbox. We need to find the
// baseline for output, so dec by the lMaxAscender.
ptl.y -= ((nsFontMetricsOS2*)mFontMetrics)->GetDevMaxAscender();
// there's clearly a conspiracy to make this method as slow as is
// humanly possible...
int dxMem[200];
int *dx0 = 0;
if( aSpacing)
{
dx0 = dxMem;
if( aLength > 500)
dx0 = new int[ aLength];
mTMatrix.ScaleXCoords( aSpacing, aLength, dx0);
}
GpiMove( mSurface->mPS, &ptl);
PRUint32 lLength = aLength;
const char *aStringTemp = aString;
// GpiCharString has a max length of 512 chars at a time...
while( lLength)
{
ULONG thislen = min( lLength, 512);
GpiCharStringPos( mSurface->mPS, nsnull,
aSpacing == nsnull ? 0 : CHS_VECTOR,
thislen, (PCH)aStringTemp,
aSpacing == nsnull ? nsnull : (PLONG) dx0);
lLength -= thislen;
aStringTemp += thislen;
dx0 += thislen;
}
return NS_OK;
} }
nsresult nsRenderingContextOS2::DrawString( const PRUnichar *aString, PRUint32 aLength, NS_IMETHODIMP nsRenderingContextOS2 :: GetWidth(PRUnichar ch, nscoord &aWidth, PRInt32 *aFontID)
nscoord aX, nscoord aY,
PRInt32 aFontID,
const nscoord* aSpacing)
{ {
char buf[1024]; PRUnichar buf[1];
buf[0] = ch;
int newLength = WideCharToMultiByte( ((nsFontMetricsOS2*)mFontMetrics)->mCodePage, aString, aLength, buf, sizeof(buf)); return GetWidth(buf, 1, aWidth, aFontID);
return DrawString( buf, newLength, aX, aY, aSpacing);
} }
nsresult nsRenderingContextOS2::DrawString( const nsString& aString, NS_IMETHODIMP nsRenderingContextOS2 :: GetWidth(const char* aString, nscoord& aWidth)
nscoord aX, nscoord aY,
PRInt32 aFontID,
const nscoord* aSpacing)
{ {
return DrawString( aString.GetUnicode(), aString.Length(), return GetWidth(aString, strlen(aString), aWidth);
aX, aY, aFontID, aSpacing);
} }
// Width-getting methods for string-drawing. Finally in a sensible place! NS_IMETHODIMP nsRenderingContextOS2 :: GetWidth(const char* aString,
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( char ch, nscoord &aWidth) PRUint32 aLength,
nscoord& aWidth)
{ {
// Optimize spaces; happens *very* often! if (nsnull != mFontMetrics)
if( ch == ' ' && mFontMetrics) {
{ // Check for the very common case of trying to get the width of a single
aWidth = ((nsFontMetricsOS2*)mFontMetrics)->GetSpaceWidth(this); // space.
return NS_OK; if ((1 == aLength) && (aString[0] == ' '))
} {
nsFontMetricsOS2* fontMetricsOS2 = (nsFontMetricsOS2*)mFontMetrics;
return fontMetricsOS2->GetSpaceWidth(aWidth);
}
char buf[1]; SIZEL size;
buf[0] = ch;
return GetWidth( buf, 1, aWidth); SetupFontAndColor();
::GetTextExtentPoint32(mSurface->mPS, aString, aLength, &size);
aWidth = NSToCoordRound(float(size.cx) * mP2T);
return NS_OK;
}
else
return NS_ERROR_FAILURE;
} }
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( PRUnichar ch, nscoord &aWidth, NS_IMETHODIMP
PRInt32 */*aFontID*/) nsRenderingContextOS2::GetWidth(const char *aString,
PRInt32 aLength,
PRInt32 aAvailWidth,
PRInt32* aBreaks,
PRInt32 aNumBreaks,
nscoord& aWidth,
PRInt32& aNumCharsFit,
PRInt32* aFontID = nsnull)
{ {
if( ch == 32 && mFontMetrics) NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");
{
aWidth = ((nsFontMetricsOS2*)mFontMetrics)->GetSpaceWidth(this);
return NS_OK;
}
PRUnichar buf[1]; if (nsnull != mFontMetrics) {
buf[0] = ch; // If we need to back up this state represents the last place we could
return GetWidth( buf, 1, aWidth); // break. We can use this to avoid remeasuring text
struct PrevBreakState {
PRInt32 mBreakIndex;
nscoord mWidth; // accumulated width to this point
PrevBreakState() {
mBreakIndex = -1; // not known (hasn't been computed)
mWidth = 0;
}
};
// Initialize OUT parameter
aNumCharsFit = 0;
// Setup the font and foreground color
SetupFontAndColor();
// Iterate each character in the string and determine which font to use
nsFontMetricsOS2* metrics = (nsFontMetricsOS2*)mFontMetrics;
PrevBreakState prevBreakState;
nscoord width = 0;
PRInt32 start = 0;
nscoord aveCharWidth;
metrics->GetAveCharWidth(aveCharWidth);
while (start < aLength) {
// Estimate how many characters will fit. Do that by diving the available
// space by the average character width. Make sure the estimated number
// of characters is at least 1
PRInt32 estimatedNumChars = 0;
if (aveCharWidth > 0) {
estimatedNumChars = (aAvailWidth - width) / aveCharWidth;
}
if (estimatedNumChars < 1) {
estimatedNumChars = 1;
}
// Find the nearest break offset
PRInt32 estimatedBreakOffset = start + estimatedNumChars;
PRInt32 breakIndex;
nscoord numChars;
// Find the nearest place to break that is less than or equal to
// the estimated break offset
if (aLength < estimatedBreakOffset) {
// All the characters should fit
numChars = aLength - start;
breakIndex = aNumBreaks - 1;
} else {
breakIndex = prevBreakState.mBreakIndex;
while (((breakIndex + 1) < aNumBreaks) &&
(aBreaks[breakIndex + 1] <= estimatedBreakOffset)) {
breakIndex++;
}
if (breakIndex == prevBreakState.mBreakIndex) {
breakIndex++; // make sure we advanced past the previous break index
}
numChars = aBreaks[breakIndex] - start;
}
// Measure the text
nscoord twWidth;
if ((1 == numChars) && (aString[start] == ' ')) {
metrics->GetSpaceWidth(twWidth);
} else {
SIZEL size;
::GetTextExtentPoint32(mSurface->mPS, &aString[start], numChars, &size);
twWidth = NSToCoordRound(float(size.cx) * mP2T);
}
// See if the text fits
PRBool textFits = (twWidth + width) <= aAvailWidth;
// If the text fits then update the width and the number of
// characters that fit
if (textFits) {
aNumCharsFit += numChars;
width += twWidth;
start += numChars;
// This is a good spot to back up to if we need to so remember
// this state
prevBreakState.mBreakIndex = breakIndex;
prevBreakState.mWidth = width;
} else {
// See if we can just back up to the previous saved state and not
// have to measure any text
if (prevBreakState.mBreakIndex > 0) {
// If the previous break index is just before the current break index
// then we can use it
if (prevBreakState.mBreakIndex == (breakIndex - 1)) {
aNumCharsFit = aBreaks[prevBreakState.mBreakIndex];
width = prevBreakState.mWidth;
break;
}
}
// We can't just revert to the previous break state
if (0 == breakIndex) {
// There's no place to back up to so even though the text doesn't fit
// return it anyway
aNumCharsFit += numChars;
width += twWidth;
break;
}
// Repeatedly back up until we get to where the text fits or we're all
// the way back to the first word
width += twWidth;
while ((breakIndex >= 1) && (width > aAvailWidth)) {
start = aBreaks[breakIndex - 1];
numChars = aBreaks[breakIndex] - start;
if ((1 == numChars) && (aString[start] == ' ')) {
metrics->GetSpaceWidth(twWidth);
} else {
SIZEL size;
::GetTextExtentPoint32(mSurface->mPS, &aString[start], numChars, &size);
twWidth = NSToCoordRound(float(size.cx) * mP2T);
}
width -= twWidth;
aNumCharsFit = start;
breakIndex--;
}
break;
}
}
aWidth = width;
return NS_OK;
}
return NS_ERROR_FAILURE;
} }
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const char *aString,
nscoord &aWidth)
{
return GetWidth( aString, strlen(aString), aWidth);
}
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const nsString &aString, NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const nsString &aString,
nscoord &aWidth, nscoord &aWidth,
PRInt32 */*aFontID*/) PRInt32 *aFontID)
{ {
return GetWidth( aString.GetUnicode(), aString.Length(), aWidth); return GetWidth( aString.GetUnicode(), aString.Length(), aWidth, aFontID);
}
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const char* aString,
PRUint32 aLength,
nscoord &aWidth)
{
PRUint32 sum = 0;
PRUint32 lLength = aLength;
SetupFontAndColor(); // select font
POINTL ptls[ 5];
const char* aStringTemp = aString;
while( lLength) // max data to gpi function is 512 chars.
{
ULONG thislen = min( lLength, 512);
GpiQueryTextBox( mSurface->mPS, thislen, (PCH) aStringTemp, 5, ptls);
sum += ptls[ TXTBOX_CONCAT].x;
lLength -= thislen;
aStringTemp += thislen;
}
aWidth = NSToCoordRound(float(sum) * mP2T);
return NS_OK;
} }
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const PRUnichar *aString, NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const PRUnichar *aString,
@ -1412,6 +1474,67 @@ NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const PRUnichar *aString,
return temp; return temp;
} }
NS_IMETHODIMP nsRenderingContextOS2 :: DrawString(const char *aString, PRUint32 aLength,
nscoord aX, nscoord aY,
const nscoord* aSpacing)
{
NS_PRECONDITION(mFontMetrics,"Something is wrong somewhere");
// Take care of ascent and specifies the drawing on the baseline
nscoord ascent;
mFontMetrics->GetMaxAscent(ascent);
aY += ascent;
PRInt32 x = aX;
PRInt32 y = aY;
SetupFontAndColor();
INT dxMem[500];
INT* dx0;
if (nsnull != aSpacing) {
dx0 = dxMem;
if (aLength > 500) {
dx0 = new INT[aLength];
}
mTMatrix.ScaleXCoords(aSpacing, aLength, dx0);
}
mTMatrix.TransformCoord(&x, &y);
POINTL ptl = { x, y };
NS2PM( &ptl, 1);
::ExtTextOut(mSurface->mPS, ptl.x, ptl.y, 0, NULL, aString, aLength, aSpacing ? dx0 : NULL);
if ((nsnull != aSpacing) && (dx0 != dxMem)) {
delete [] dx0;
}
return NS_OK;
}
NS_IMETHODIMP nsRenderingContextOS2 :: DrawString(const PRUnichar *aString, PRUint32 aLength,
nscoord aX, nscoord aY,
PRInt32 aFontID,
const nscoord* aSpacing)
{
char buf[1024];
int newLength = WideCharToMultiByte( ((nsFontMetricsOS2*)mFontMetrics)->mCodePage, aString, aLength, buf, sizeof(buf));
return DrawString( buf, newLength, aX, aY, aSpacing);
}
NS_IMETHODIMP nsRenderingContextOS2 :: DrawString(const nsString& aString,
nscoord aX, nscoord aY,
PRInt32 aFontID,
const nscoord* aSpacing)
{
return DrawString(aString.GetUnicode(), aString.Length(), aX, aY, aFontID, aSpacing);
}
// Image drawing: just proxy on to the image object, so no worries yet. // Image drawing: just proxy on to the image object, so no worries yet.
nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, nscoord aX, nscoord aY) nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, nscoord aX, nscoord aY)
{ {
@ -1521,7 +1644,7 @@ nsresult nsRenderingContextOS2::CopyOffScreenBits(
{ {
// Set clip region on dest surface to be that from the hps // Set clip region on dest surface to be that from the hps
// in the passed-in drawing surface. // in the passed-in drawing surface.
GpiSetClipRegion2( hpsTarget, GpiCopyClipRegion( theSurf->mPS)); OS2_SetClipRegion2( hpsTarget, OS2_CopyClipRegion( theSurf->mPS));
} }
// Windows wants to select palettes here. I don't think I do. // Windows wants to select palettes here. I don't think I do.
@ -1571,55 +1694,46 @@ nsresult nsRenderingContextOS2::RetrieveCurrentNativeGraphicData(PRUint32* ngd)
/* hrgnCombine becomes the clip region. Any current clip region is */ /* hrgnCombine becomes the clip region. Any current clip region is */
/* dealt with. hrgnCombine may be NULLHANDLE. */ /* dealt with. hrgnCombine may be NULLHANDLE. */
/* Return value is lComplexity. */ /* Return value is lComplexity. */
/* lOp should be CRGN_* */ /* lMode should be CRGN_* */
LONG GpiCombineClipRegion( HPS hps, HRGN hrgnCombine, LONG lOp) LONG OS2_CombineClipRegion( HPS hps, HRGN hrgnCombine, LONG lMode)
{ {
if( !hps) return RGN_ERROR; if (!hps) return RGN_ERROR;
/* Get current hps clip region */ HRGN hrgnClip = NULL;
HRGN hrgnClip = 0; LONG rc;
if( GpiQueryClipRegion( hps))
GpiSetClipRegion (hps, NULL, &hrgnClip); // Get the current clip region and deselect it
if (hrgnClip && hrgnClip != HRGN_ERROR)
{ {
GpiSetClipRegion( hps, 0, &hrgnClip); if (lMode != CRGN_COPY) // If necessarry combine with previous clip region
GpiCombineRegion (hps, hrgnCombine, hrgnClip, hrgnCombine, lMode);
if( hrgnClip && hrgnClip != HRGN_ERROR)
{ if (!GpiDestroyRegion (hps, hrgnClip))
/* There is a clip region; combine it with new one if necessary */ PMERROR( "GpiDestroyRegion [Gpi_CombineClipRegion]");
if( lOp != CRGN_COPY)
GpiCombineRegion( hps, hrgnCombine, hrgnClip, hrgnCombine, lOp);
if( !GpiDestroyRegion( hps, hrgnClip))
PMERROR( "GpiDestroyRegion");
}
} }
/* hrgnCombine is the correct clip region, & hrgnClip is invalid */ rc = GpiSetClipRegion (hps, hrgnCombine, NULL); // Set new clip region
hrgnClip = 0;
return GpiSetClipRegion( hps, hrgnCombine, &hrgnClip); return rc;
} }
/* Return value is HRGN_ */ /* Return value is HRGN_ */
HRGN GpiCopyClipRegion( HPS hps) HRGN OS2_CopyClipRegion( HPS hps)
{ {
if( !hps) return HRGN_ERROR; if (!hps) return HRGN_ERROR;
HRGN hrgn = 0; HRGN hrgn, hrgnClip;
if( GpiQueryClipRegion( hps))
{
HRGN hrgnClip = 0;
GpiSetClipRegion( hps, 0, &hrgnClip);
if( hrgnClip != HRGN_ERROR)
{
hrgn = GpiCreateRegion( hps, 0, 0);
GpiCombineRegion( hps, hrgn, hrgnClip, 0, CRGN_COPY);
/* put the current clip back */
HRGN hrgnDummy = 0;
GpiSetClipRegion( hps, hrgnClip, &hrgnDummy);
}
else
hrgn = HRGN_ERROR;
}
return hrgn; GpiSetClipRegion (hps, 0, &hrgnClip); // Get current clip region
if (hrgnClip && hrgnClip != HRGN_ERROR)
{
hrgn = GpiCreateRegion (hps, 0, NULL); // Create empty region and combine with current
GpiCombineRegion (hps, hrgn, hrgnClip, 0, CRGN_COPY);
GpiSetClipRegion (hps, hrgnClip, NULL); // restore current clip region
}
return hrgn;
} }
// Keep coordinate within 32-bit limits // Keep coordinate within 32-bit limits

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

@ -131,15 +131,23 @@ public:
float aStartAngle, float aEndAngle); float aStartAngle, float aEndAngle);
NS_IMETHOD GetWidth(char aC, nscoord& aWidth); NS_IMETHOD GetWidth(char aC, nscoord& aWidth);
NS_IMETHOD GetWidth( PRUnichar aC, nscoord& aWidth, NS_IMETHOD GetWidth(PRUnichar aC, nscoord& aWidth,
PRInt32 *aFontID = nsnull); PRInt32 *aFontID);
NS_IMETHOD GetWidth( const nsString& aString, nscoord& aWidth, NS_IMETHOD GetWidth(const nsString& aString, nscoord& aWidth,
PRInt32 *aFontID = nsnull); PRInt32 *aFontID);
NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth); NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth);
NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth); NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth);
NS_IMETHOD GetWidth( const PRUnichar* aString, PRUint32 aLength, NS_IMETHOD GetWidth(const char *aString,
nscoord& aWidth, PRInt32 *aFontID = nsnull); PRInt32 aLength,
#if 0 // OS2TODO PRInt32 aAvailWidth,
PRInt32* aBreaks,
PRInt32 aNumBreaks,
nscoord& aWidth,
PRInt32& aNumCharsFit,
PRInt32* aFontID);
NS_IMETHOD GetWidth(const PRUnichar* aString, PRUint32 aLength,
nscoord& aWidth, PRInt32 *aFontID);
#ifndef XP_OS2
NS_IMETHOD GetWidth(const PRUnichar *aString, NS_IMETHOD GetWidth(const PRUnichar *aString,
PRInt32 aLength, PRInt32 aLength,
PRInt32 aAvailWidth, PRInt32 aAvailWidth,
@ -222,7 +230,7 @@ private:
// Primitive draw-ers // Primitive draw-ers
void PMDrawRect( nsRect &rect, BOOL fill); void PMDrawRect( nsRect &rect, BOOL fill);
void PMDrawPoly( const nsPoint aPoints[], PRInt32 aNumPoints, PRBool bFilled); void PMDrawPoly( const nsPoint aPoints[], PRInt32 aNumPoints, PRBool bFilled);
void PMDrawArc( nsRect &rect, PRBool bFilled, PRBool bFull, PRInt32 start=0, PRInt32 end=0); void PMDrawArc( nsRect &rect, PRBool bFilled, PRBool bFull, float start=0, float end=0);
protected: protected: