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()
: DeviceContextImpl()
{
mSurface = nsnull;
mSurface = NULL;
mPaletteInfo.isPaletteDevice = PR_FALSE;
mPaletteInfo.sizePalette = 0;
mPaletteInfo.numReserved = 0;
mPaletteInfo.palette = nsnull;
mDC = nsnull;
mPaletteInfo.palette = NULL;
mPrintDC = NULL;
mPixelScale = 1.0f;
mWidth = -1;
mHeight = -1;
@ -97,11 +97,11 @@ nsDeviceContextOS2 :: nsDeviceContextOS2()
nsDeviceContextOS2::~nsDeviceContextOS2()
{
if(mDC)
if(mPrintDC)
{
GpiAssociate(mPS, 0);
GpiDestroyPS(mPS);
PrnCloseDC(mDC);
GpiAssociate(mPrintPS, 0);
GpiDestroyPS(mPrintPS);
PrnCloseDC(mPrintDC);
}
if (!mPaletteInfo.isPaletteDevice) {
@ -131,7 +131,7 @@ nsresult nsDeviceContextOS2::Init( nsNativeDeviceContext aContext,
float origscale, newscale;
float t2d, a2d;
mDC = (HDC)aContext;
mPrintDC = (HDC)aContext;
#ifdef XP_OS2
// 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
// the DC (really?). And it would be slow :-)
SIZEL sizel = { 0 , 0 };
mPS = GpiCreatePS( 0/*hab*/, mDC, &sizel,
mPrintPS = GpiCreatePS( 0/*hab*/, mPrintDC, &sizel,
PU_PELS | GPIT_MICRO | GPIA_ASSOC);
#endif
CommonInit( mDC);
CommonInit( mPrintDC);
GetTwipsToDevUnits( newscale);
aOrigContext->GetTwipsToDevUnits( origscale);
@ -159,7 +159,7 @@ nsresult nsDeviceContextOS2::Init( nsNativeDeviceContext aContext,
#ifdef XP_OS2
HCINFO hcinfo;
PrnQueryHardcopyCaps( mDC, &hcinfo);
PrnQueryHardcopyCaps( mPrintDC, &hcinfo);
mWidth = hcinfo.xPels;
mHeight = hcinfo.yPels;
// 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
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;
if (!pContext)
@ -303,7 +303,7 @@ nsresult nsDeviceContextOS2::CreateRenderingContext( nsIRenderingContext *&aCont
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(surf);
surf->Init( mPS, mWidth, mHeight);
surf->Init( mPrintPS, mWidth, mHeight);
nsresult rc = pContext->Init( this, (void*)((nsDrawingSurfaceOS2 *) surf));
@ -320,7 +320,7 @@ nsresult nsDeviceContextOS2::CreateRenderingContext( nsIRenderingContext *&aCont
NS_IMETHODIMP nsDeviceContextOS2 :: SupportsNativeWidgets(PRBool &aSupportsWidgets)
{
if (nsnull == mDC)
if (nsnull == mPrintDC)
aSupportsWidgets = PR_TRUE;
else
aSupportsWidgets = PR_FALSE;
@ -811,6 +811,10 @@ NS_IMETHODIMP nsDeviceContextOS2 :: GetDeviceContextFor(nsIDeviceContextSpec *aD
HDC dc = PrnOpenDC(pq, "Mozilla");
if (!dc) {
PMERROR("DevOpenDC");
} /* endif */
return ((nsDeviceContextOS2 *)aContext)->Init((nsNativeDeviceContext)dc, this);
}
@ -853,10 +857,10 @@ nsresult nsDeviceContextOS2::CreateFontAliasTable()
// Printing ------------------------------------------------------------------
nsresult nsDeviceContextOS2::BeginDocument()
{
NS_ASSERTION(mDC, "BeginDocument for non-print DC");
NS_ASSERTION(mPrintDC, "BeginDocument for non-print DC");
if( mPrintState == nsPrintState_ePreBeginDoc)
{
PrnStartJob( mDC, "Warpzilla NGLayout job");
PrnStartJob( mPrintDC, "Warpzilla NGLayout job");
printf( "BeginDoc\n");
mPrintState = nsPrintState_eBegunDoc;
}
@ -865,7 +869,7 @@ nsresult nsDeviceContextOS2::BeginDocument()
nsresult nsDeviceContextOS2::EndDocument()
{
PrnEndJob( mDC);
PrnEndJob( mPrintDC);
mPrintState = nsPrintState_ePreBeginDoc;
printf("EndDoc\n");
return NS_OK;
@ -877,7 +881,7 @@ nsresult nsDeviceContextOS2::BeginPage()
mPrintState = nsPrintState_eBegunFirstPage;
else
{
PrnNewPage( mDC);
PrnNewPage( mPrintDC);
printf("NewPage");
}
return NS_OK;
@ -891,7 +895,7 @@ nsresult nsDeviceContextOS2::EndPage()
BOOL nsDeviceContextOS2::isPrintDC()
{
if ( mDC == nsnull )
if ( mPrintDC == nsnull )
return 0;
else

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

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

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

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

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

@ -79,7 +79,33 @@ struct nsFontHandleOS2
class nsFontOS2
{
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];
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 GetLangGroup(nsIAtom** aLangGroup);
NS_IMETHOD GetFontHandle( nsFontHandle &aHandle);
NS_IMETHOD GetAveCharWidth(nscoord &aAveCharWidth);
virtual nsresult GetSpaceWidth(nscoord &aSpaceWidth);
virtual nsFontOS2* FindGlobalFont(HPS aPS, PRUnichar aChar);
virtual nsFontOS2* FindGenericFont(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* LoadFont(HPS aPS, nsString* aName);
// for drawing text
PRUint32 GetDevMaxAscender() const { return mDevMaxAscent; }
nscoord GetSpaceWidth( nsIRenderingContext *aRContext);
static PLHashTable* gFontMaps;
static nsGlobalFont* gGlobalFonts;
static int gGlobalFontsCount;
@ -166,8 +190,7 @@ class nsFontMetricsOS2 : public nsIFontMetrics
nscoord mMaxAdvance;
nscoord mSpaceWidth;
nscoord mXHeight;
PRUint32 mDevMaxAscent;
nscoord mAveCharWidth;
nsFontHandleOS2 *mFontHandle;
nsDeviceContextOS2 *mDeviceContext;

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

@ -81,6 +81,9 @@ struct nsGfxModuleData
};
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();

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

@ -393,6 +393,52 @@ int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, c
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()
{
return bIsDBCS;

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

@ -221,6 +221,9 @@ nsresult nsImageOS2::Draw( nsIRenderingContext &aContext,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSW, PRInt32 aSH,
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.
nsRect trect( aDX, aDY, aDW, aDH);
RECTL rcl;
@ -365,9 +368,8 @@ void nsImageOS2::DrawBitmap( HPS hps, LONG lCount, PPOINTL pPoints,
void *pBits = bIsMask ? mAlphaBits : mImageBits;
if( GPI_ERROR == GpiDrawBits( hps, pBits, pBmp2,
lCount, pPoints, lRop, BBO_OR))
PMERROR( "GpiDrawBits");
if (GPI_ERROR == GpiDrawBits (hps, pBits, pBmp2, lCount, pPoints, lRop, BBO_OR))
PMERROR( "GpiDrawBits - DrawBitmap");
delete pMaskInfo;
}

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

@ -54,10 +54,9 @@
#include "prprf.h"
// helper clip region functions - defined at the bottom of this file.
LONG GpiCombineClipRegion( HPS hps, HRGN hrgnCombine, LONG lOp);
HRGN GpiCopyClipRegion( HPS hps);
#define GpiDestroyClipRegion(hps) GpiCombineClipRegion(hps, 0, CRGN_COPY)
#define GpiSetClipRegion2(hps,hrgn) GpiCombineClipRegion(hps, hrgn, CRGN_COPY)
LONG OS2_CombineClipRegion( HPS hps, HRGN hrgnCombine, LONG lMode);
HRGN OS2_CopyClipRegion( HPS hps);
#define OS2_SetClipRegion2(hps,hrgn) OS2_CombineClipRegion(hps, hrgn, CRGN_COPY)
// Use these instead of native GpiSave/RestorePS because: need to store ----
// more information, and need to be able to push from onscreen & pop onto
@ -510,7 +509,7 @@ nsresult nsRenderingContextOS2::PushState()
NS_IF_ADDREF( mFontMetrics);
// clip region: get current & copy it.
state->mClipRegion = GpiCopyClipRegion( mSurface->mPS);
state->mClipRegion = OS2_CopyClipRegion( mSurface->mPS);
// push state onto stack
state->mNext = mStateStack;
@ -540,7 +539,7 @@ nsresult nsRenderingContextOS2::PopState( PRBool &aClipEmpty)
state->mFontMetrics = nsnull;
// Clip region
GpiSetClipRegion2( mSurface->mPS, state->mClipRegion);
OS2_SetClipRegion2( mSurface->mPS, state->mClipRegion);
if( state->mClipRegion != 0)
{
state->mClipRegion = 0;
@ -649,9 +648,9 @@ nsresult nsRenderingContextOS2::SetClipRect( const nsRect& aRect, nsClipCombine
NS2PM_INEX( trect, rcl);
HRGN hrgn = GpiCreateRegion( mSurface->mPS, 1, &rcl);
if( hrgn && aCombine == nsClipCombine_kReplace)
lrc = GpiSetClipRegion2( mSurface->mPS, hrgn);
lrc = OS2_SetClipRegion2( mSurface->mPS, hrgn);
else if( hrgn)
lrc = GpiCombineClipRegion( mSurface->mPS, hrgn, CRGN_OR);
lrc = OS2_CombineClipRegion( mSurface->mPS, hrgn, CRGN_OR);
break;
}
default:
@ -718,7 +717,7 @@ nsresult nsRenderingContextOS2::SetClipRegion( const nsIRegion &aRegion, nsClipC
break;
}
long lrc = GpiCombineClipRegion( mSurface->mPS, hrgn, cmode);
long lrc = OS2_CombineClipRegion( mSurface->mPS, hrgn, cmode);
aClipEmpty = (lrc == RGN_NULL) ? PR_TRUE : PR_FALSE;
@ -764,7 +763,7 @@ nsresult nsRenderingContextOS2::GetClipRegion( nsIRegion **aRegion)
*/
nsresult nsRenderingContextOS2::CopyClipRegion(nsIRegion &aRegion)
{
HRGN hr = GpiCopyClipRegion(mSurface->mPS);
HRGN hr = OS2_CopyClipRegion(mSurface->mPS);
if (hr == HRGN_ERROR)
return NS_ERROR_FAILURE;
@ -883,7 +882,7 @@ void nsRenderingContextOS2::SetupDrawingColor( BOOL bForce)
areaBundle.lColor = lColor;
lineBundle.lColor = lColor;
if (((nsDeviceContextOS2 *) mContext)->mDC )
if (((nsDeviceContextOS2 *) mContext)->mPrintDC )
{
areaBundle.lBackColor = CLR_BACKGROUND;
@ -1160,8 +1159,7 @@ nsresult nsRenderingContextOS2::DrawArc( const nsRect& aRect,
float aStartAngle, float aEndAngle)
{
nsRect tRect( aRect);
PMDrawArc( tRect, PR_FALSE, PR_FALSE,
(PRInt32)aStartAngle, (PRInt32)aEndAngle);
PMDrawArc( tRect, PR_FALSE, PR_FALSE, aStartAngle, aEndAngle);
return NS_OK;
}
@ -1169,8 +1167,7 @@ nsresult nsRenderingContextOS2::DrawArc( nscoord aX, nscoord aY, nscoord aWidth,
float aStartAngle, float aEndAngle)
{
nsRect tRect( aX, aY, aWidth, aHeight);
PMDrawArc( tRect, PR_FALSE, PR_FALSE,
(PRInt32)aStartAngle, (PRInt32)aEndAngle);
PMDrawArc( tRect, PR_FALSE, PR_FALSE, aStartAngle, aEndAngle);
return NS_OK;
}
@ -1178,8 +1175,7 @@ nsresult nsRenderingContextOS2::FillArc( const nsRect& aRect,
float aStartAngle, float aEndAngle)
{
nsRect tRect( aRect);
PMDrawArc( tRect, PR_TRUE, PR_FALSE,
(PRInt32)aStartAngle, (PRInt32)aEndAngle);
PMDrawArc( tRect, PR_TRUE, PR_FALSE, aStartAngle, aEndAngle);
return NS_OK;
}
@ -1187,14 +1183,12 @@ nsresult nsRenderingContextOS2::FillArc( nscoord aX, nscoord aY, nscoord aWidth,
float aStartAngle, float aEndAngle)
{
nsRect tRect( aX, aY, aWidth, aHeight);
PMDrawArc( tRect, PR_TRUE, PR_FALSE,
(PRInt32)aStartAngle, (PRInt32)aEndAngle);
PMDrawArc( tRect, PR_TRUE, PR_FALSE, aStartAngle, aEndAngle);
return NS_OK;
}
void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled,
PRBool bFull,
PRInt32 start, PRInt32 end)
void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled, PRBool bFull,
float start, float end)
{
// convert coords
mTMatrix.TransformCoord( &rect.x, &rect.y, &rect.width, &rect.height);
@ -1204,10 +1198,6 @@ void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled,
SetupDrawingColor();
long lOps = DRO_OUTLINE;
if( bFilled)
lOps |= DRO_FILL;
// set arc params.
long lWidth = rect.width / 2;
long lHeight = rect.height / 2;
@ -1219,23 +1209,27 @@ void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled,
rcl.yBottom += lHeight;
GpiMove( mSurface->mPS, (PPOINTL)&rcl);
if( bFull)
{
long lOps = (bFilled) ? DRO_OUTLINEFILL : DRO_OUTLINE;
// draw ellipse
GpiFullArc( mSurface->mPS, lOps, MAKEFIXED(1,0));
}
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
if( bFilled)
{
GpiBeginArea( mSurface->mPS, BA_BOUNDARY);
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0),
MAKEFIXED(start,0), MAKEFIXED(Sweep,0));
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), StartAngle, SweepAngle);
GpiEndArea( mSurface->mPS);
}
else
@ -1243,12 +1237,10 @@ void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled,
// draw an invisible partialarc to get to the start of the arc.
long lLineType = GpiQueryLineType( mSurface->mPS);
GpiSetLineType( mSurface->mPS, LINETYPE_INVISIBLE);
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0),
MAKEFIXED(0,0), MAKEFIXED(start,0));
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), StartAngle, MAKEFIXED (0,0));
// now draw a real arc
GpiSetLineType( mSurface->mPS, lLineType);
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0),
MAKEFIXED(start,0), MAKEFIXED(Sweep,0));
GpiPartialArc( mSurface->mPS, (PPOINTL)&rcl, MAKEFIXED(1,0), StartAngle, SweepAngle);
}
}
}
@ -1262,142 +1254,212 @@ NS_IMETHODIMP nsRenderingContextOS2::GetHints(PRUint32& aResult)
return NS_OK;
}
nsresult nsRenderingContextOS2::DrawString( const char *aString,
PRUint32 aLength,
nscoord aX, nscoord aY,
const nscoord* aSpacing)
{
mTMatrix.TransformCoord( &aX, &aY);
POINTL ptl = { aX, aY };
NS2PM( &ptl, 1);
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,
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);
}
nsresult nsRenderingContextOS2::DrawString( const nsString& aString,
nscoord aX, nscoord aY,
PRInt32 aFontID,
const nscoord* aSpacing)
{
return DrawString( aString.GetUnicode(), aString.Length(),
aX, aY, aFontID, aSpacing);
}
// Width-getting methods for string-drawing. Finally in a sensible place!
NS_IMETHODIMP nsRenderingContextOS2 :: GetWidth(char ch, nscoord& aWidth)
{
// Optimize spaces; happens *very* often!
if( ch == ' ' && mFontMetrics)
{
aWidth = ((nsFontMetricsOS2*)mFontMetrics)->GetSpaceWidth(this);
return NS_OK;
}
char buf[1];
buf[0] = ch;
return GetWidth(buf, 1, aWidth);
}
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( PRUnichar ch, nscoord &aWidth,
PRInt32 */*aFontID*/)
NS_IMETHODIMP nsRenderingContextOS2 :: GetWidth(PRUnichar ch, nscoord &aWidth, PRInt32 *aFontID)
{
if( ch == 32 && mFontMetrics)
{
aWidth = ((nsFontMetricsOS2*)mFontMetrics)->GetSpaceWidth(this);
return NS_OK;
}
PRUnichar buf[1];
buf[0] = ch;
return GetWidth( buf, 1, aWidth);
return GetWidth(buf, 1, aWidth, aFontID);
}
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const char *aString,
nscoord &aWidth)
NS_IMETHODIMP nsRenderingContextOS2 :: GetWidth(const char* aString, nscoord& aWidth)
{
return GetWidth(aString, strlen(aString), aWidth);
}
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const nsString &aString,
nscoord &aWidth,
PRInt32 */*aFontID*/)
{
return GetWidth( aString.GetUnicode(), aString.Length(), aWidth);
}
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.
if (nsnull != mFontMetrics)
{
ULONG thislen = min( lLength, 512);
GpiQueryTextBox( mSurface->mPS, thislen, (PCH) aStringTemp, 5, ptls);
sum += ptls[ TXTBOX_CONCAT].x;
lLength -= thislen;
aStringTemp += thislen;
// Check for the very common case of trying to get the width of a single
// space.
if ((1 == aLength) && (aString[0] == ' '))
{
nsFontMetricsOS2* fontMetricsOS2 = (nsFontMetricsOS2*)mFontMetrics;
return fontMetricsOS2->GetSpaceWidth(aWidth);
}
aWidth = NSToCoordRound(float(sum) * mP2T);
SIZEL size;
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(const char *aString,
PRInt32 aLength,
PRInt32 aAvailWidth,
PRInt32* aBreaks,
PRInt32 aNumBreaks,
nscoord& aWidth,
PRInt32& aNumCharsFit,
PRInt32* aFontID = nsnull)
{
NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");
if (nsnull != mFontMetrics) {
// If we need to back up this state represents the last place we could
// 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 nsString &aString,
nscoord &aWidth,
PRInt32 *aFontID)
{
return GetWidth( aString.GetUnicode(), aString.Length(), aWidth, aFontID);
}
NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const PRUnichar *aString,
PRUint32 aLength,
@ -1412,6 +1474,67 @@ NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const PRUnichar *aString,
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.
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
// 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.
@ -1571,52 +1694,43 @@ nsresult nsRenderingContextOS2::RetrieveCurrentNativeGraphicData(PRUint32* ngd)
/* hrgnCombine becomes the clip region. Any current clip region is */
/* dealt with. hrgnCombine may be NULLHANDLE. */
/* Return value is lComplexity. */
/* lOp should be CRGN_* */
LONG GpiCombineClipRegion( HPS hps, HRGN hrgnCombine, LONG lOp)
/* lMode should be CRGN_* */
LONG OS2_CombineClipRegion( HPS hps, HRGN hrgnCombine, LONG lMode)
{
if (!hps) return RGN_ERROR;
/* Get current hps clip region */
HRGN hrgnClip = 0;
if( GpiQueryClipRegion( hps))
{
GpiSetClipRegion( hps, 0, &hrgnClip);
HRGN hrgnClip = NULL;
LONG rc;
GpiSetClipRegion (hps, NULL, &hrgnClip); // Get the current clip region and deselect it
if (hrgnClip && hrgnClip != HRGN_ERROR)
{
/* There is a clip region; combine it with new one if necessary */
if( lOp != CRGN_COPY)
GpiCombineRegion( hps, hrgnCombine, hrgnClip, hrgnCombine, lOp);
if (lMode != CRGN_COPY) // If necessarry combine with previous clip region
GpiCombineRegion (hps, hrgnCombine, hrgnClip, hrgnCombine, lMode);
if (!GpiDestroyRegion (hps, hrgnClip))
PMERROR( "GpiDestroyRegion");
}
PMERROR( "GpiDestroyRegion [Gpi_CombineClipRegion]");
}
/* hrgnCombine is the correct clip region, & hrgnClip is invalid */
hrgnClip = 0;
return GpiSetClipRegion( hps, hrgnCombine, &hrgnClip);
rc = GpiSetClipRegion (hps, hrgnCombine, NULL); // Set new clip region
return rc;
}
/* Return value is HRGN_ */
HRGN GpiCopyClipRegion( HPS hps)
HRGN OS2_CopyClipRegion( HPS hps)
{
if (!hps) return HRGN_ERROR;
HRGN hrgn = 0;
if( GpiQueryClipRegion( hps))
HRGN hrgn, hrgnClip;
GpiSetClipRegion (hps, 0, &hrgnClip); // Get current clip region
if (hrgnClip && hrgnClip != HRGN_ERROR)
{
HRGN hrgnClip = 0;
GpiSetClipRegion( hps, 0, &hrgnClip);
if( hrgnClip != HRGN_ERROR)
{
hrgn = GpiCreateRegion( hps, 0, 0);
hrgn = GpiCreateRegion (hps, 0, NULL); // Create empty region and combine with current
GpiCombineRegion (hps, hrgn, hrgnClip, 0, CRGN_COPY);
/* put the current clip back */
HRGN hrgnDummy = 0;
GpiSetClipRegion( hps, hrgnClip, &hrgnDummy);
}
else
hrgn = HRGN_ERROR;
GpiSetClipRegion (hps, hrgnClip, NULL); // restore current clip region
}
return hrgn;

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

@ -132,14 +132,22 @@ public:
NS_IMETHOD GetWidth(char aC, nscoord& aWidth);
NS_IMETHOD GetWidth(PRUnichar aC, nscoord& aWidth,
PRInt32 *aFontID = nsnull);
PRInt32 *aFontID);
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, PRUint32 aLength, nscoord& aWidth);
NS_IMETHOD GetWidth(const char *aString,
PRInt32 aLength,
PRInt32 aAvailWidth,
PRInt32* aBreaks,
PRInt32 aNumBreaks,
nscoord& aWidth,
PRInt32& aNumCharsFit,
PRInt32* aFontID);
NS_IMETHOD GetWidth(const PRUnichar* aString, PRUint32 aLength,
nscoord& aWidth, PRInt32 *aFontID = nsnull);
#if 0 // OS2TODO
nscoord& aWidth, PRInt32 *aFontID);
#ifndef XP_OS2
NS_IMETHOD GetWidth(const PRUnichar *aString,
PRInt32 aLength,
PRInt32 aAvailWidth,
@ -222,7 +230,7 @@ private:
// Primitive draw-ers
void PMDrawRect( nsRect &rect, BOOL fill);
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: