458 lines
12 KiB
C++
458 lines
12 KiB
C++
/* -*- 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 <pp@ludusdesign.com>
|
|
* Sergei Dolgov <sergei_d@fi.tartu.ee>
|
|
*
|
|
* 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 <math.h>
|
|
#include <Menu.h>
|
|
#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 <ScrollBar.h>
|
|
#include <Screen.h>
|
|
|
|
#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<nsIPref> 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<nsIScreenManager> sm ( do_GetService("@mozilla.org/gfx/screenmanager;1", &ignore) );
|
|
if (sm)
|
|
{
|
|
nsCOMPtr<nsIScreen> 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<PRUint32>(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<nsIPref> 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<nsIPref> 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);
|
|
}
|