/* -*- 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 mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Pierre Phaneuf * Sergei Dolgov * * 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 #include #include "nspr.h" #include "nsIPref.h" #include "nsIServiceManager.h" #include "nsCRT.h" #include "nsReadableUtils.h" #include "nsDeviceContextBeOS.h" #include "nsFontMetricsBeOS.h" #include "nsGfxCIID.h" #include #include #include "nsIScreenManager.h" nscoord nsDeviceContextBeOS::mDpi = 96; nsDeviceContextBeOS::nsDeviceContextBeOS() : DeviceContextImpl() { mTwipsToPixels = 1.0; mPixelsToTwips = 1.0; mDepth = 0 ; mNumCells = 0; mWidthFloat = 0.0f; mHeightFloat = 0.0f; mWidth = -1; mHeight = -1; } nsDeviceContextBeOS::~nsDeviceContextBeOS() { nsresult rv; nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) prefs->UnregisterCallback("layout.css.dpi", prefChanged, (void *)this); } NS_IMETHODIMP nsDeviceContextBeOS::Init(nsNativeWidget aNativeWidget) { // get the screen object and its width/height // XXXRight now this will only get the primary monitor. nsresult ignore; mWidget = aNativeWidget; nsCOMPtr sm ( do_GetService("@mozilla.org/gfx/screenmanager;1", &ignore) ); if (sm) { nsCOMPtr screen; sm->GetPrimaryScreen(getter_AddRefs(screen)); if (screen) { PRInt32 x, y, width, height, depth; screen->GetAvailRect ( &x, &y, &width, &height ); screen->GetPixelDepth ( &depth ); mWidthFloat = float(width); mHeightFloat = float(height); mDepth = static_cast(depth); } } static int initialized = 0; 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 PRInt32 prefVal = -1; nsresult res; nsCOMPtr prefs(do_GetService(NS_PREF_CONTRACTID, &res)); if (NS_SUCCEEDED(res) && prefs) { res = prefs->GetIntPref("layout.css.dpi", &prefVal); if (! NS_SUCCEEDED(res)) { prefVal = -1; } prefs->RegisterCallback("layout.css.dpi", prefChanged, (void *)this); } // Set OSVal to what the operating system thinks the logical resolution is. // BeOS lacks monitor info, so we use fixed value for now PRInt32 OSVal = 85; if (prefVal > 0) { // If there's a valid pref value for the logical resolution, // use it. mDpi = prefVal; } else if ((prefVal == 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; } } SetDPI(mDpi); menu_info info; get_menu_info(&info); mMenuFont.SetFamilyAndStyle(info.f_family,info.f_style); mMenuFont.SetSize(info.font_size); #ifdef DEBUG static PRBool once = PR_TRUE; if (once) { printf("GFX: dpi=%d t2p=%g p2t=%g depth=%d\n", mDpi, mTwipsToPixels, mPixelsToTwips,mDepth); once = PR_FALSE; } #endif DeviceContextImpl::CommonInit(); return NS_OK; } NS_IMETHODIMP nsDeviceContextBeOS::CreateRenderingContext(nsIRenderingContext *&aContext) { nsIRenderingContext *pContext; nsresult rv; nsDrawingSurfaceBeOS *surf; BView *w; w = (BView*)mWidget; // to call init for this, we need to have a valid nsDrawingSurfaceBeOS created pContext = new nsRenderingContextBeOS(); if (nsnull != pContext) { NS_ADDREF(pContext); // create the nsDrawingSurfaceBeOS surf = new nsDrawingSurfaceBeOS(); if (surf && w) { // init the nsDrawingSurfaceBeOS rv = surf->Init(w); if (NS_OK == rv) // Init the nsRenderingContextBeOS rv = pContext->Init(this, surf); } else { rv = NS_ERROR_OUT_OF_MEMORY; } } else { rv = NS_ERROR_OUT_OF_MEMORY; } if (NS_OK != rv) NS_IF_RELEASE(pContext); aContext = pContext; return rv; } NS_IMETHODIMP nsDeviceContextBeOS::SupportsNativeWidgets(PRBool &aSupportsWidgets) { //XXX it is very critical that this not lie!! MMP // read the comments in the mac code for this aSupportsWidgets = PR_TRUE; return NS_OK; } NS_IMETHODIMP nsDeviceContextBeOS::GetSystemFont(nsSystemFontID aID, nsFont *aFont) const { nsresult status = NS_OK; switch (aID) { case eSystemFont_PullDownMenu: case eSystemFont_Menu: status = GetSystemFontInfo(&mMenuFont, aID, aFont); break; case eSystemFont_Caption: // css2 bold status = GetSystemFontInfo(be_bold_font, aID, aFont); break; case eSystemFont_List: case eSystemFont_Field: case eSystemFont_Icon : case eSystemFont_MessageBox : case eSystemFont_SmallCaption : case eSystemFont_StatusBar : case eSystemFont_Window: // css3 case eSystemFont_Document: case eSystemFont_Workspace: case eSystemFont_Desktop: case eSystemFont_Info: case eSystemFont_Dialog: case eSystemFont_Button: case eSystemFont_Tooltips: // moz case eSystemFont_Widget: default: status = GetSystemFontInfo(be_plain_font, aID, aFont); } return status; } NS_IMETHODIMP nsDeviceContextBeOS::CheckFontExistence(const nsString& aFontName) { return nsFontMetricsBeOS::FamilyExists(aFontName); } /* NS_IMETHODIMP nsDeviceContextBeOS::CheckFontExistence(const nsString& aFontName) { PRBool isthere = PR_FALSE; char* cStr = ToNewCString(aFontName); int32 numFamilies = count_font_families(); for(int32 i = 0; i < numFamilies; i++) { font_family family; uint32 flags; if(get_font_family(i, &family, &flags) == B_OK) { if(strcmp(family, cStr) == 0) { isthere = PR_TRUE; break; } } } //printf("%s there? %s\n", cStr, isthere?"Yes":"No" ); delete[] cStr; if (PR_TRUE == isthere) return NS_OK; else return NS_ERROR_FAILURE; } */ NS_IMETHODIMP nsDeviceContextBeOS::GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight) { if (mWidth == -1) mWidth = NSToIntRound(mWidthFloat * mDevUnitsToAppUnits); if (mHeight == -1) mHeight = NSToIntRound(mHeightFloat * mDevUnitsToAppUnits); aWidth = mWidth; aHeight = mHeight; return NS_OK; } NS_IMETHODIMP nsDeviceContextBeOS::GetRect(nsRect &aRect) { PRInt32 width, height; nsresult rv; rv = GetDeviceSurfaceDimensions(width, height); aRect.x = 0; aRect.y = 0; aRect.width = width; aRect.height = height; return rv; } NS_IMETHODIMP nsDeviceContextBeOS::GetClientRect(nsRect &aRect) { //XXX do we know if the client rect should ever differ from the screen rect? return GetRect(aRect); } NS_IMETHODIMP nsDeviceContextBeOS::GetDeviceContextFor(nsIDeviceContextSpec *aDevice, nsIDeviceContext *&aContext) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP nsDeviceContextBeOS::BeginDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage) { return NS_OK; } NS_IMETHODIMP nsDeviceContextBeOS::EndDocument(void) { return NS_OK; } NS_IMETHODIMP nsDeviceContextBeOS::BeginPage(void) { return NS_OK; } NS_IMETHODIMP nsDeviceContextBeOS::EndPage(void) { return NS_OK; } NS_IMETHODIMP nsDeviceContextBeOS::GetDepth(PRUint32& aDepth) { aDepth = mDepth; return NS_OK; } nsresult nsDeviceContextBeOS::SetDPI(PRInt32 aDpi) { mDpi = aDpi; int pt2t = 72; mPixelsToTwips = float(NSToIntRound(float(NSIntPointsToTwips(pt2t)) / float(aDpi))); mTwipsToPixels = 1.0f / mPixelsToTwips; // XXX need to reflow all documents return NS_OK; } int nsDeviceContextBeOS::prefChanged(const char *aPref, void *aClosure) { nsDeviceContextBeOS *context = (nsDeviceContextBeOS*)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; } nsresult nsDeviceContextBeOS::GetSystemFontInfo(const BFont *theFont, nsSystemFontID anID, nsFont* aFont) const { nsresult status = NS_OK; aFont->style = NS_FONT_STYLE_NORMAL; aFont->weight = NS_FONT_WEIGHT_NORMAL; aFont->decorations = NS_FONT_DECORATION_NONE; // do we have the default_font defined by BeOS, if not then // we error out. if (!theFont) { switch (anID) { case eSystemFont_Menu: status = GetSystemFontInfo(&mMenuFont, anID, aFont); break; case eSystemFont_List: case eSystemFont_Field: theFont = be_plain_font; break; case eSystemFont_Caption: theFont = be_bold_font; break; default: theFont = be_plain_font; // BeOS default font } } if (!theFont) { status = NS_ERROR_FAILURE; } else { font_family family; font_style style; font_height height; uint16 face; theFont->GetFamilyAndStyle(&family, &style); face = theFont->Face(); aFont->name.Assign(NS_ConvertUTF8toUTF16(family)); aFont->size = NSIntPixelsToTwips(uint32(theFont->Size()), mPixelsToTwips); if(face & B_ITALIC_FACE) aFont->style = NS_FONT_STYLE_ITALIC; if(face & B_BOLD_FACE) aFont->weight = NS_FONT_WEIGHT_BOLD; if(face & B_UNDERSCORE_FACE) aFont->decorations |= NS_FONT_DECORATION_UNDERLINE; if(face & B_STRIKEOUT_FACE) aFont->decorations |= NS_FONT_DECORATION_LINE_THROUGH; aFont->systemFont = PR_TRUE; status = NS_OK; } return (status); }