/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Mozilla OS/2 libraries. * * The Initial Developer of the Original Code is * John Fairhurst, . * Portions created by the Initial Developer are Copyright (C) 1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Henry Sobotka 2OOO/O2 update * IBM Corp. * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsDeviceContextOS2.h" #include "nsRenderingContextOS2.h" #include "nsDeviceContextSpecOS2.h" #include "nsIServiceManager.h" #include "nsCOMPtr.h" #include "nsIScreenManager.h" #include "nsIScreen.h" #include "nsHashTable.h" // For CreateFontAliasTable() #include "nsGfxDefs.h" #include "nsIPref.h" #include "nsOS2Uni.h" #include "nsPaletteOS2.h" #define NOT_SETUP 0x33 static PRBool gIsWarp4 = NOT_SETUP; PRUint32 nsDeviceContextOS2::sNumberOfScreens = 0; nscoord nsDeviceContextOS2::mDpi = 120; nsDeviceContextOS2 :: nsDeviceContextOS2() : DeviceContextImpl() { mSurface = NULL; mIsPaletteDevice = PR_FALSE; mPrintDC = NULL; mWidth = -1; mHeight = -1; mSpec = nsnull; mCachedClientRect = PR_FALSE; mCachedFullRect = PR_FALSE; mSupportsRasterFonts = PR_FALSE; mPrintingStarted = PR_FALSE; #ifdef XP_OS2 mPrintState = nsPrintState_ePreBeginDoc; #endif // The first time in we initialize gIsWarp4 flag if (NOT_SETUP == gIsWarp4) { unsigned long ulValues[2]; DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MINOR, ulValues, sizeof(ulValues)); gIsWarp4 = (ulValues[0] >= 20) && (ulValues[1] >= 40); } } nsDeviceContextOS2::~nsDeviceContextOS2() { if(mPrintDC) { GFX (::GpiDestroyPS (mPrintPS), FALSE); ::DevCloseDC(mPrintDC); } else { nsresult rv; nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { prefs->UnregisterCallback("layout.css.dpi", prefChanged, (void *)this); } } NS_IF_RELEASE(mSpec); } nsresult nsDeviceContextOS2::Init( nsNativeWidget aWidget) { mWidget = aWidget; CommonInit(::WinOpenWindowDC((HWND)aWidget)); static int initialized = 0; PRInt32 prefVal = -1; if (!initialized) { initialized = 1; // Set prefVal the value of the preference // "layout.css.dpi" // or -1 if we can't get it. // If it's negative, we pretend it's not set. // If it's 0, it means force use of the operating system's logical // resolution. // If it's positive, we use it as the logical resolution nsresult res; nsCOMPtr prefs(do_GetService(NS_PREF_CONTRACTID, &res)); if (NS_SUCCEEDED(res) && prefs) { res = prefs->GetIntPref("layout.css.dpi", &prefVal); if (NS_FAILED(res)) { prefVal = -1; } prefs->RegisterCallback("layout.css.dpi", prefChanged, (void *)this); } SetDPI(prefVal); } else { SetDPI(mDpi); // to setup p2t and t2p } return NS_OK; } // This version of Init() is called when creating a print DC nsresult nsDeviceContextOS2::Init( nsNativeDeviceContext aContext, nsIDeviceContext *aOrigContext) { float origscale, newscale; float t2d, a2d; mPrintDC = (HDC)aContext; NS_ASSERTION( mPrintDC, "!ERROR! - Received empty DC for printer"); #ifdef XP_OS2 // Create a print PS now. This is necessary 'cos we need it from // odd places to do font-y things, where the only common reference // point is this DC. We can't just create a new PS because only one // 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 }; mPrintPS = GFX (::GpiCreatePS ( 0/*hab*/, mPrintDC, &sizel, PU_PELS | GPIT_MICRO | GPIA_ASSOC), GPI_ERROR); #endif CommonInit( mPrintDC); long dpi; GFX (::DevQueryCaps(mPrintDC, CAPS_VERTICAL_FONT_RES, 1, &dpi), FALSE); mPixelsToTwips = ((float)NSIntPointsToTwips(72)) / ((float)dpi); mTwipsToPixels = 1.0 / mPixelsToTwips; newscale = TwipsToDevUnits(); // On OS/2, origscale can be different based on the video resolution. // On 640x480, it's 1/15, on everything else it is 1/12. // For consistent printing, 1/15 is the correct value to use. // It is the closest to 4.x and to Windows. // origscale = aOrigContext->TwipsToDevUnits(); origscale = 1.0/15.0; mCPixelScale = newscale / origscale; t2d = aOrigContext->TwipsToDevUnits(); a2d = aOrigContext->AppUnitsToDevUnits(); mAppUnitsToDevUnits = (a2d / t2d) * mTwipsToPixels; mDevUnitsToAppUnits = 1.0f / mAppUnitsToDevUnits; #ifdef XP_OS2 HCINFO hcinfo; PrnQueryHardcopyCaps( mPrintDC, &hcinfo); mWidth = hcinfo.xPels; mHeight = hcinfo.yPels; // XXX hsb says there are margin problems, must be from here... #ifdef DEBUG printf( "Got surface of size %d x %d pixels (%d Kb)\n", mWidth, mHeight, mWidth * mHeight * mDepth / 8 / 1024); printf( "mCPixelScale = %f\n", mCPixelScale); #endif #endif return NS_OK; } void nsDeviceContextOS2 :: CommonInit(HDC aDC) { LONG alArray[CAPS_DEVICE_POLYSET_POINTS]; GFX (::DevQueryCaps(aDC, CAPS_FAMILY, CAPS_DEVICE_POLYSET_POINTS, alArray), FALSE); mDepth = alArray[CAPS_COLOR_BITCOUNT]; mIsPaletteDevice = ((alArray[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER) == CAPS_PALETTE_MANAGER); mWidth = alArray[CAPS_WIDTH]; mHeight = alArray[CAPS_HEIGHT]; if (alArray[CAPS_TECHNOLOGY] == CAPS_TECH_RASTER_DISPLAY) { // init the screen manager and compute our client rect based on the // screen objects. We'll save the result nsresult ignore; mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1", &ignore); if ( !sNumberOfScreens ) mScreenManager->GetNumberOfScreens(&sNumberOfScreens); mSupportsRasterFonts = !!(alArray[CAPS_RASTER_CAPS] & CAPS_RASTER_FONTS); } // if this dc is not a print device DeviceContextImpl::CommonInit(); } void nsDeviceContextOS2 :: ComputeClientRectUsingScreen ( nsRect* outRect ) { if ( !mCachedClientRect ) { nsCOMPtr screen; FindScreen ( getter_AddRefs(screen) ); if ( screen ) { PRInt32 x, y, width, height; screen->GetAvailRect ( &x, &y, &width, &height ); // convert to device units outRect->y = NSToIntRound(y * mDevUnitsToAppUnits); outRect->x = NSToIntRound(x * mDevUnitsToAppUnits); outRect->width = NSToIntRound(width * mDevUnitsToAppUnits); outRect->height = NSToIntRound(height * mDevUnitsToAppUnits); mCachedClientRect = PR_TRUE; mClientRect = *outRect; } } else *outRect = mClientRect; } // ComputeClientRectUsingScreen void nsDeviceContextOS2 :: ComputeFullAreaUsingScreen ( nsRect* outRect ) { if ( !mCachedFullRect ) { nsCOMPtr screen; FindScreen ( getter_AddRefs(screen) ); if ( screen ) { PRInt32 x, y, width, height; screen->GetRect ( &x, &y, &width, &height ); // convert to device units outRect->y = NSToIntRound(y * mDevUnitsToAppUnits); outRect->x = NSToIntRound(x * mDevUnitsToAppUnits); outRect->width = NSToIntRound(width * mDevUnitsToAppUnits); outRect->height = NSToIntRound(height * mDevUnitsToAppUnits); mWidth = width; mHeight = height; mCachedFullRect = PR_TRUE; } } else { outRect->y = 0; outRect->x = 0; outRect->width = NSToIntRound(mWidth * mDevUnitsToAppUnits); outRect->height = NSToIntRound(mHeight * mDevUnitsToAppUnits); } } // ComputeFullRectUsingScreen // // FindScreen // // Determines which screen intersects the largest area of the given surface. // void nsDeviceContextOS2 :: FindScreen ( nsIScreen** outScreen ) { // optimize for the case where we only have one monitor. static nsCOMPtr sPrimaryScreen; if ( !sPrimaryScreen && mScreenManager ) mScreenManager->GetPrimaryScreen ( getter_AddRefs(sPrimaryScreen) ); NS_IF_ADDREF(*outScreen = sPrimaryScreen.get()); return; } // FindScreen /* OS2TODO - NOT PORTED */ // Create a rendering context against our hdc for a printer nsresult nsDeviceContextOS2::CreateRenderingContext( nsIRenderingContext *&aContext) { #ifdef NS_PRINT_PREVIEW // Defer to Alt when there is one if (mAltDC && ((mUseAltDC & kUseAltDCFor_CREATERC_PAINT) || (mUseAltDC & kUseAltDCFor_CREATERC_REFLOW))) { return mAltDC->CreateRenderingContext(aContext); } #endif NS_ASSERTION( mPrintDC, "CreateRenderingContext for non-print DC"); nsIRenderingContext *pContext = new nsRenderingContextOS2; if (!pContext) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(pContext); nsPrintSurface *surf = new nsPrintSurface; if (!surf) return NS_ERROR_OUT_OF_MEMORY; surf->Init( mPrintPS, mWidth, mHeight, 0); nsresult rc = pContext->Init(this, surf); if( NS_OK != rc) { delete surf; NS_IF_RELEASE(pContext); } aContext = pContext; return rc; } NS_IMETHODIMP nsDeviceContextOS2 :: SupportsNativeWidgets(PRBool &aSupportsWidgets) { if (nsnull == mPrintDC) aSupportsWidgets = PR_TRUE; else aSupportsWidgets = PR_FALSE; return NS_OK; } NS_IMETHODIMP nsDeviceContextOS2 :: GetScrollBarDimensions(float &aWidth, float &aHeight) const { float scale = mCPixelScale; aWidth = ::WinQuerySysValue( HWND_DESKTOP, SV_CXVSCROLL) * mDevUnitsToAppUnits * scale; aHeight = ::WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL) * mDevUnitsToAppUnits * scale; return NS_OK; } nscolor GetSysColorInfo(int iSysColor) { long lColor = ::WinQuerySysColor( HWND_DESKTOP, iSysColor, 0); RGB2 *pRGB2 = (RGB2*) &lColor; return NS_RGB( pRGB2->bRed, pRGB2->bGreen, pRGB2->bBlue); } /* Helper function to query font from INI file */ void QueryFontFromINI(char* fontType, char* fontName, ULONG ulLength) { ULONG ulMaxNameL = ulLength; /* We had to switch to using PrfQueryProfileData because */ /* some users have binary font data in their INI files */ BOOL rc = PrfQueryProfileData(HINI_USER, "PM_SystemFonts", fontType, fontName, &ulMaxNameL); /* If there was no entry in the INI, default to something */ if (rc == FALSE) { /* Different values for DBCS vs. SBCS */ if (!IsDBCS()) { /* WarpSans is only available on Warp 4 and above */ if (gIsWarp4) strcpy(fontName, "9.WarpSans"); else strcpy(fontName, "8.Helv"); } else { /* WarpSans is only available on Warp 4 and above */ if (gIsWarp4) strcpy(fontName, "9.WarpSans Combined"); else strcpy(fontName, "10.Helv Combined"); } } else { /* null terminate fontname */ fontName[ulMaxNameL] = '\0'; } } nsresult GetSysFontInfo(nsSystemFontID aID, nsFont* aFont) { char szFontNameSize[MAXNAMEL]; switch (aID) { case eSystemFont_Icon: QueryFontFromINI("IconText", szFontNameSize, MAXNAMEL); break; case eSystemFont_Menu: QueryFontFromINI("Menus", szFontNameSize, MAXNAMEL); break; case eSystemFont_Caption: case eSystemFont_MessageBox: case eSystemFont_SmallCaption: case eSystemFont_StatusBar: case eSystemFont_Tooltips: case eSystemFont_Widget: case eSystemFont_Window: // css3 case eSystemFont_Document: case eSystemFont_Workspace: case eSystemFont_Desktop: case eSystemFont_Info: case eSystemFont_Dialog: case eSystemFont_Button: case eSystemFont_PullDownMenu: case eSystemFont_List: case eSystemFont_Field: QueryFontFromINI("WindowText", szFontNameSize, MAXNAMEL); break; } // switch int pointSize; char *szFacename; pointSize = atoi(szFontNameSize); szFacename = strchr(szFontNameSize, '.'); if ((pointSize == 0) || (!szFacename) || (*(szFacename++) == '\0')) { return NS_ERROR_FAILURE; } #ifdef OLDCODE PRUnichar name[FACESIZE]; name[0] = 0; MultiByteToWideChar(0, szFacename, strlen(szFacename) + 1, name, sizeof(name)/sizeof(name[0])); #endif aFont->name.AssignWithConversion(szFacename); // Do Style aFont->style = NS_FONT_STYLE_NORMAL; #if 0 if (ptrLogFont->lfItalic) { aFont->style = NS_FONT_STYLE_ITALIC; } #endif // XXX What about oblique? aFont->variant = NS_FONT_VARIANT_NORMAL; // Do Weight #if 0 aFont->weight = (ptrLogFont->lfWeight == FW_BOLD ? NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL); #else aFont->weight = NS_FONT_WEIGHT_NORMAL; #endif // Do decorations aFont->decorations = NS_FONT_DECORATION_NONE; #if 0 if (ptrLogFont->lfUnderline) { aFont->decorations |= NS_FONT_DECORATION_UNDERLINE; } if (ptrLogFont->lfStrikeOut) { aFont->decorations |= NS_FONT_DECORATION_LINE_THROUGH; } #endif // Do Size aFont->size = NSIntPointsToTwips(pointSize); aFont->systemFont = PR_TRUE; return NS_OK; } NS_IMETHODIMP nsDeviceContextOS2 :: GetSystemFont(nsSystemFontID aID, nsFont *aFont) const { nsresult status = NS_OK; switch (aID) { case eSystemFont_Caption: case eSystemFont_Icon: case eSystemFont_Menu: case eSystemFont_MessageBox: case eSystemFont_SmallCaption: case eSystemFont_StatusBar: case eSystemFont_Tooltips: case eSystemFont_Widget: case eSystemFont_Window: // css3 case eSystemFont_Document: case eSystemFont_Workspace: case eSystemFont_Desktop: case eSystemFont_Info: case eSystemFont_Dialog: case eSystemFont_Button: case eSystemFont_PullDownMenu: case eSystemFont_List: case eSystemFont_Field: { status = GetSysFontInfo(aID, aFont); break; } } return status; } NS_IMETHODIMP nsDeviceContextOS2 :: CheckFontExistence(const nsString& aFontName) { HPS hps = NULL; if (NULL != mPrintDC){ hps = mPrintPS; } else { hps = ::WinGetPS((HWND)mWidget); } nsAutoCharBuffer fontName; PRInt32 fontNameLength; WideCharToMultiByte(0, aFontName.get(), aFontName.Length(), fontName, fontNameLength); long lWant = 0; long lFonts = GFX (::GpiQueryFonts(hps, QF_PUBLIC | QF_PRIVATE, fontName.get(), &lWant, 0, 0), GPI_ALTERROR); if (NULL == mPrintDC) ::WinReleasePS(hps); if (lFonts > 0) return NS_OK; else return NS_ERROR_FAILURE; } NS_IMETHODIMP nsDeviceContextOS2::GetDepth(PRUint32& aDepth) { aDepth = mDepth; return NS_OK; } nsresult nsDeviceContextOS2::SetDPI(PRInt32 aPrefDPI) { // Set OSVal to what the operating system thinks the logical resolution is. long OSVal; HPS ps = ::WinGetScreenPS(HWND_DESKTOP); HDC hdc = GFX (::GpiQueryDevice (ps), HDC_ERROR); GFX (::DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 1, &OSVal), FALSE); ::WinReleasePS(ps); if (aPrefDPI > 0) { // If there's a valid pref value for the logical resolution, // use it. mDpi = aPrefDPI; } else if ((aPrefDPI == 0) || (OSVal > 96)) { // Either if the pref is 0 (force use of OS value) or the OS // value is bigger than 96, use the OS value. mDpi = OSVal; } else { // if we couldn't get the pref or it's negative, and the OS // value is under 96ppi, then use 96. mDpi = 96; } int pt2t = 72; // make p2t a nice round number - this prevents rounding problems mPixelsToTwips = float(NSToIntRound(float(NSIntPointsToTwips(pt2t)) / float(mDpi))); mTwipsToPixels = 1.0f / mPixelsToTwips; // XXX need to reflow all documents return NS_OK; } int prefChanged(const char *aPref, void *aClosure) { nsDeviceContextOS2 *context = (nsDeviceContextOS2*)aClosure; nsresult rv; if (nsCRT::strcmp(aPref, "layout.css.dpi")==0) { PRInt32 dpi; nsCOMPtr prefs(do_GetService(NS_PREF_CONTRACTID, &rv)); rv = prefs->GetIntPref(aPref, &dpi); if (NS_SUCCEEDED(rv)) context->SetDPI(dpi); } return 0; } NS_IMETHODIMP nsDeviceContextOS2 :: GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight) { #ifdef NS_PRINT_PREVIEW // Defer to Alt when there is one if (mAltDC && (mUseAltDC & kUseAltDCFor_SURFACE_DIM)) return mAltDC->GetDeviceSurfaceDimensions(aWidth, aHeight); #endif if ( mSpec ) { // we have a printer device aWidth = NSToIntRound(mWidth * mDevUnitsToAppUnits); aHeight = NSToIntRound(mHeight * mDevUnitsToAppUnits); } else { nsRect area; ComputeFullAreaUsingScreen ( &area ); aWidth = area.width; aHeight = area.height; } return NS_OK; } NS_IMETHODIMP nsDeviceContextOS2 :: GetRect(nsRect &aRect) { if ( mSpec ) { // we have a printer device aRect.x = 0; aRect.y = 0; aRect.width = NSToIntRound(mWidth * mDevUnitsToAppUnits); aRect.height = NSToIntRound(mHeight * mDevUnitsToAppUnits); } else ComputeFullAreaUsingScreen ( &aRect ); return NS_OK; } NS_IMETHODIMP nsDeviceContextOS2 :: GetClientRect(nsRect &aRect) { if ( mSpec ) { // we have a printer device aRect.x = 0; aRect.y = 0; aRect.width = NSToIntRound(mWidth * mDevUnitsToAppUnits); aRect.height = NSToIntRound(mHeight * mDevUnitsToAppUnits); } else ComputeClientRectUsingScreen ( &aRect ); return NS_OK; } NS_IMETHODIMP nsDeviceContextOS2 :: GetDeviceContextFor(nsIDeviceContextSpec *aDevice, nsIDeviceContext *&aContext) { PRTQUEUE *pq; aContext = new nsDeviceContextOS2(); if(nsnull != aContext){ NS_ADDREF(aContext); } else { return NS_ERROR_OUT_OF_MEMORY; } ((nsDeviceContextOS2 *)aContext)->mSpec = aDevice; NS_ADDREF(aDevice); int numCopies = 0; int printerDest = 0; char *file = nsnull; ((nsDeviceContextSpecOS2 *)aDevice)->GetPRTQUEUE(pq); ((nsDeviceContextSpecOS2 *)aDevice)->GetCopies(numCopies); ((nsDeviceContextSpecOS2 *)aDevice)->GetDestination(printerDest); if (!printerDest) ((nsDeviceContextSpecOS2 *)aDevice)->GetPath(&file); HDC dc = PrnOpenDC(pq, "Mozilla", numCopies, printerDest, file); if (!dc) { return NS_ERROR_FAILURE; //PMERROR("DevOpenDC"); } /* endif */ return ((nsDeviceContextOS2 *)aContext)->Init((nsNativeDeviceContext)dc, this); } nsresult nsDeviceContextOS2::CreateFontAliasTable() { nsresult result = NS_OK; if( !mFontAliasTable) { mFontAliasTable = new nsHashtable; nsAutoString times; times.AssignLiteral("Times"); nsAutoString timesNewRoman; timesNewRoman.AssignLiteral("Times New Roman"); nsAutoString timesRoman; timesRoman.AssignLiteral("Tms Rmn"); nsAutoString arial; arial.AssignLiteral("Arial"); nsAutoString helv; helv.AssignLiteral("Helv"); nsAutoString helvetica; helvetica.AssignLiteral("Helvetica"); nsAutoString courier; courier.AssignLiteral("Courier"); nsAutoString courierNew; courierNew.AssignLiteral("Courier New"); nsAutoString sans; sans.AssignLiteral("Sans"); nsAutoString unicode; unicode.AssignLiteral("Unicode"); nsAutoString timesNewRomanMT30; timesNewRomanMT30.AssignLiteral("Times New Roman MT 30"); nsAutoString nullStr; AliasFont(times, timesNewRoman, timesRoman, PR_FALSE); AliasFont(timesRoman, timesNewRoman, times, PR_FALSE); AliasFont(timesNewRoman, timesRoman, times, PR_FALSE); AliasFont(arial, helv, helvetica, PR_FALSE); AliasFont(helvetica, helv, arial, PR_FALSE); AliasFont(courier, courierNew, nullStr, PR_TRUE); AliasFont(courierNew, courier, nullStr, PR_FALSE); AliasFont(sans, helv, arial, PR_FALSE); // Is this right? AliasFont(unicode, timesNewRomanMT30, nullStr, PR_FALSE); } return result; } // Printing ------------------------------------------------------------------ nsresult nsDeviceContextOS2::PrepareDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName) { nsresult rv = NS_OK; if (NULL != mPrintDC){ nsString titleStr; titleStr = aTitle; char *title = GetACPString(titleStr); PSZ pszDocName; const PSZ pszGenericDocName = "MozillaDocument"; if (title) { pszDocName = title; } else { pszDocName = pszGenericDocName; } long lDummy = 0; long lResult = ::DevEscape(mPrintDC, DEVESC_STARTDOC, strlen(pszDocName) + 1, pszDocName, &lDummy, NULL); mPrintingStarted = PR_TRUE; if (lResult == DEV_OK) rv = NS_OK; else rv = NS_ERROR_GFX_PRINTER_STARTDOC; if (title != nsnull) { nsMemory::Free(title); } } return rv; } nsresult nsDeviceContextOS2::BeginDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage) { // Everything is done in PrepareDocument return NS_OK; } nsresult nsDeviceContextOS2::EndDocument() { if (NULL != mPrintDC) { long lOutCount = 2; USHORT usJobID = 0; long lResult = ::DevEscape(mPrintDC, DEVESC_ENDDOC, 0, NULL, &lOutCount, (PBYTE)&usJobID); if (lResult == DEV_OK) return NS_OK; else return NS_ERROR_GFX_PRINTER_ENDDOC; } return NS_OK; } nsresult nsDeviceContextOS2::AbortDocument() { if (NULL != mPrintDC) { long ldummy = 0; long lResult = ::DevEscape(mPrintDC, DEVESC_ABORTDOC, 0, NULL, &ldummy, NULL); if (lResult == DEV_OK) return NS_OK; else return NS_ERROR_ABORT; } return NS_OK; } nsresult nsDeviceContextOS2::BeginPage() { if (mPrintingStarted) { mPrintingStarted = PR_FALSE; return NS_OK; } if (NULL != mPrintDC) { long lDummy = 0; long lResult = ::DevEscape(mPrintDC, DEVESC_NEWFRAME, 0, NULL, &lDummy, NULL); if (lResult == DEV_OK) return NS_OK; else return NS_ERROR_GFX_PRINTER_STARTPAGE; } return NS_OK; } nsresult nsDeviceContextOS2::EndPage() { return NS_OK; } char* nsDeviceContextOS2::GetACPString(const nsString& aStr) { if (aStr.Length() == 0) { return nsnull; } nsAutoCharBuffer acp; PRInt32 acpLength; WideCharToMultiByte(0, aStr.get(), aStr.Length(), acp, acpLength); return ToNewCString(nsDependentCString(acp.get())); } BOOL nsDeviceContextOS2::isPrintDC() { if ( mPrintDC == nsnull ) return 0; else return 1; } PRBool nsDeviceContextOS2::SupportsRasterFonts() { return mSupportsRasterFonts; }