1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
23
* Pierre Phaneuf <pp@ludusdesign.com>
24
* Peter Hartshorn <peter@igelaus.com.au>
25
* Ken Faulkner <faulkner@igelaus.com.au>
26
* Tony Tsui <tony@igelaus.com.au>
27
* Tim Copperfield <timecop@network.email.ne.jp>
28
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
31
* Alternatively, the contents of this file may be used under the terms of
32
* either the GNU General Public License Version 2 or later (the "GPL"), or
33
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
34
* in which case the provisions of the GPL or the LGPL are applicable instead
35
* of those above. If you wish to allow use of your version of this file only
36
* under the terms of either the GPL or the LGPL, and not to allow others to
37
* use your version of this file under the terms of the NPL, indicate your
38
* decision by deleting the provisions above and replace them with the notice
39
* and other provisions required by the GPL or the LGPL. If you do not delete
40
* the provisions above, a recipient may use your version of this file under
41
* the terms of any one of the NPL, the GPL or the LGPL.
43
* ***** END LICENSE BLOCK ***** */
45
#include "nsRenderingContextXlib.h"
46
#include "nsDrawingSurfaceXlib.h"
47
#include "nsDeviceContextXlib.h"
49
#include "nsIServiceManager.h"
50
#include "nsGfxCIID.h"
53
#include "nsFontMetricsXlib.h"
56
#include <X11/Xatom.h>
58
#include "nsDeviceContextSpecXlib.h"
61
#include "nsGfxPSCID.h"
62
#include "nsIDeviceContextPS.h"
63
#endif /* USE_POSTSCRIPT */
65
#include "nsGfxXPrintCID.h"
66
#include "nsIDeviceContextXPrint.h"
67
#endif /* USE_XPRINT */
69
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
71
#define XLIB_DEFAULT_FONT1 "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1"
72
#define XLIB_DEFAULT_FONT2 "-*-fixed-medium-r-*-*-*-120-*-*-*-*-*-*"
75
static PRLogModuleInfo *DeviceContextXlibLM = PR_NewLogModule("DeviceContextXlib");
76
#endif /* PR_LOGGING */
78
/* global default font handle */
79
static XFontStruct *mDefaultFont = nsnull;
81
nsDeviceContextXlib::nsDeviceContextXlib()
84
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::nsDeviceContextXlib()\n"));
98
mXlibRgbHandle = xxlib_find_handle(XXLIBRGB_DEFAULT_HANDLE);
105
nsDeviceContextXlib::~nsDeviceContextXlib()
107
nsIDrawingSurfaceXlib *surf = NS_STATIC_CAST(nsIDrawingSurfaceXlib *, mSurface);
113
if (mContextCounter == 0)
115
DeleteRenderingContextXlibContext(mRCContext);
116
DeleteFontMetricsXlibContext(mFontMetricsContext);
118
mFontMetricsContext = nsnull;
122
nsFontMetricsXlibContext *nsDeviceContextXlib::mFontMetricsContext = nsnull;
123
nsRenderingContextXlibContext *nsDeviceContextXlib::mRCContext = nsnull;
124
int nsDeviceContextXlib::mContextCounter = 0;
126
NS_IMETHODIMP nsDeviceContextXlib::Init(nsNativeWidget aNativeWidget)
128
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::Init()\n"));
130
mWidget = aNativeWidget;
132
mDisplay = xxlib_rgb_get_display(mXlibRgbHandle);
133
mScreen = xxlib_rgb_get_screen(mXlibRgbHandle);
134
mVisual = xxlib_rgb_get_visual(mXlibRgbHandle);
135
mDepth = xxlib_rgb_get_depth(mXlibRgbHandle);
138
mDefaultFont = XLoadQueryFont(mDisplay, XLIB_DEFAULT_FONT1);
141
mDefaultFont = XLoadQueryFont(mDisplay, XLIB_DEFAULT_FONT2);
144
static PRBool once = PR_TRUE;
150
printf("nsDeviceContextXlib::Init(dpy=%p screen=%p visual=%p depth=%d)\n",
162
nsDeviceContextXlib::CommonInit(void)
164
nsresult rv = NS_OK;;
167
// This was set to 100 dpi, then later on in the function is was changed
168
// to a default of 96dpi IF we had a preference component. We need to
169
// find a way to get the actual server dpi for a comparison ala GTK.
170
static nscoord dpi = 96;
171
static int initialized = 0;
176
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefCID, &res));
177
if (NS_SUCCEEDED(res) && prefs) {
179
res = prefs->GetIntPref("browser.display.screen_resolution", &intVal);
180
if (NS_SUCCEEDED(res)) {
185
// Compute dpi of display
186
float screenWidth = float(XWidthOfScreen(mScreen));
187
float screenWidthIn = float(XWidthMMOfScreen(mScreen)) / 25.4f;
188
dpi = nscoord(screenWidth / screenWidthIn);
194
// Do extra rounding (based on GTK). KenF
195
mPixelsToTwips = float(NSToIntRound(float(NSIntPointsToTwips(72)) / float(dpi)));
196
mTwipsToPixels = 1.0f / mPixelsToTwips;
198
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("GFX: dpi=%d t2p=%g p2t=%g\n", dpi, mTwipsToPixels, mPixelsToTwips));
200
mWidthFloat = (float) XWidthOfScreen(mScreen);
201
mHeightFloat = (float) XHeightOfScreen(mScreen);
203
DeviceContextImpl::CommonInit();
205
if (!mFontMetricsContext)
207
rv = CreateFontMetricsXlibContext(this, PR_FALSE, &mFontMetricsContext);
214
rv = CreateRenderingContextXlibContext(this, &mRCContext);
222
NS_IMETHODIMP nsDeviceContextXlib::CreateRenderingContext(nsIRenderingContext *&aContext)
224
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::CreateRenderingContext()\n"));
226
#ifdef NS_PRINT_PREVIEW
227
/* Defer to Alt when there is one */
228
if (mAltDC && ((mUseAltDC & kUseAltDCFor_CREATERC_PAINT) || (mUseAltDC & kUseAltDCFor_CREATERC_REFLOW))) {
229
return mAltDC->CreateRenderingContext(aContext);
231
#endif /* NS_PRINT_PREVIEW */
233
nsIRenderingContext *context;
234
nsDrawingSurfaceXlibImpl *surface = nsnull;
237
context = new nsRenderingContextXlib();
239
if (nsnull != context) {
241
surface = new nsDrawingSurfaceXlibImpl();
242
if (nsnull != surface) {
243
xGC *gc = new xGC(mDisplay, (Drawable)mWidget, 0, nsnull);
244
rv = surface->Init(mXlibRgbHandle,
248
if (NS_SUCCEEDED(rv)) {
249
rv = context->Init(this, surface);
253
rv = NS_ERROR_OUT_OF_MEMORY;
257
rv = NS_ERROR_OUT_OF_MEMORY;
261
NS_IF_RELEASE(context);
268
NS_IMETHODIMP nsDeviceContextXlib::CreateRenderingContextInstance(nsIRenderingContext *&aContext)
270
nsCOMPtr<nsIRenderingContext> renderingContext = new nsRenderingContextXlib();
271
if (!renderingContext)
272
return NS_ERROR_OUT_OF_MEMORY;
274
aContext = renderingContext;
280
NS_IMETHODIMP nsDeviceContextXlib::SupportsNativeWidgets(PRBool &aSupportsWidgets)
282
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::SupportsNativeWidgets()\n"));
283
aSupportsWidgets = PR_TRUE;
287
NS_IMETHODIMP nsDeviceContextXlib::GetScrollBarDimensions(float &aWidth, float &aHeight) const
289
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::GetScrollBarDimensions()\n"));
291
GetCanonicalPixelScale(scale);
292
// XXX Oh, yeah. These are hard coded.
293
aWidth = 15 * mPixelsToTwips * scale;
294
aHeight = 15 * mPixelsToTwips * scale;
299
NS_IMETHODIMP nsDeviceContextXlib::GetSystemFont(nsSystemFontID anID, nsFont *aFont) const
301
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::GetSystemFont()\n"));
304
case eSystemFont_Caption: // css2
305
case eSystemFont_Icon:
306
case eSystemFont_Menu:
307
case eSystemFont_MessageBox:
308
case eSystemFont_SmallCaption:
309
case eSystemFont_StatusBar:
310
case eSystemFont_Window: // css3
311
case eSystemFont_Document:
312
case eSystemFont_Workspace:
313
case eSystemFont_Desktop:
314
case eSystemFont_Info:
315
case eSystemFont_Dialog:
316
case eSystemFont_Button:
317
case eSystemFont_PullDownMenu:
318
case eSystemFont_List:
319
case eSystemFont_Field:
320
case eSystemFont_Tooltips: // moz
321
case eSystemFont_Widget:
322
aFont->style = NS_FONT_STYLE_NORMAL;
323
aFont->weight = NS_FONT_WEIGHT_NORMAL;
324
aFont->decorations = NS_FONT_DECORATION_NONE;
327
return NS_ERROR_FAILURE;
330
char *fontName = nsnull;
331
unsigned long pr = 0;
333
::XGetFontProperty(mDefaultFont, XA_FULL_NAME, &pr);
336
fontName = XGetAtomName(mDisplay, pr);
337
aFont->name.AssignWithConversion(fontName);
342
::XGetFontProperty(mDefaultFont, XA_WEIGHT, &pr);
344
aFont->weight = NS_FONT_WEIGHT_BOLD;
347
Atom pixelSizeAtom = ::XInternAtom(mDisplay, "PIXEL_SIZE", 0);
348
::XGetFontProperty(mDefaultFont, pixelSizeAtom, &pr);
350
aFont->size = NSIntPixelsToTwips(pr, mPixelsToTwips);
353
::XGetFontProperty(mDefaultFont, XA_ITALIC_ANGLE, &pr );
355
aFont->style = NS_FONT_STYLE_ITALIC;
358
::XGetFontProperty(mDefaultFont, XA_UNDERLINE_THICKNESS, &pr);
360
aFont->decorations = NS_FONT_DECORATION_UNDERLINE;
365
aFont->systemFont = PR_TRUE;
370
NS_IMETHODIMP nsDeviceContextXlib::CheckFontExistence(const nsString& aFontName)
372
return nsFontMetricsXlib::FamilyExists(mFontMetricsContext, aFontName);
375
NS_IMETHODIMP nsDeviceContextXlib::GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight)
377
#ifdef NS_PRINT_PREVIEW
378
/* Defer to Alt when there is one */
379
if (mAltDC && (mUseAltDC & kUseAltDCFor_SURFACE_DIM)) {
380
return mAltDC->GetDeviceSurfaceDimensions(aWidth, aHeight);
382
#endif /* NS_PRINT_PREVIEW */
385
mWidth = NSToIntRound(mWidthFloat * mDevUnitsToAppUnits);
388
mHeight = NSToIntRound(mHeightFloat * mDevUnitsToAppUnits);
396
NS_IMETHODIMP nsDeviceContextXlib::GetRect(nsRect &aRect)
398
PRInt32 width, height;
400
rv = GetDeviceSurfaceDimensions(width, height);
404
aRect.height = height;
408
NS_IMETHODIMP nsDeviceContextXlib::GetClientRect(nsRect &aRect)
410
PRInt32 width, height;
412
rv = GetDeviceSurfaceDimensions(width, height);
416
aRect.height = height;
420
NS_IMETHODIMP nsDeviceContextXlib::GetDeviceContextFor(nsIDeviceContextSpec *aDevice,
421
nsIDeviceContext *&aContext)
425
nsDeviceContextSpecXlib *spec = NS_STATIC_CAST(nsDeviceContextSpecXlib *, aDevice);
427
rv = spec->GetPrintMethod(method);
432
if (method == pmXprint) { // XPRINT
433
static NS_DEFINE_CID(kCDeviceContextXp, NS_DEVICECONTEXTXP_CID);
434
nsCOMPtr<nsIDeviceContextXp> dcxp(do_CreateInstance(kCDeviceContextXp, &rv));
435
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create Xp Device context.");
437
return NS_ERROR_GFX_COULD_NOT_LOAD_PRINT_MODULE;
439
rv = dcxp->SetSpec(aDevice);
443
rv = dcxp->InitDeviceContextXP((nsIDeviceContext*)aContext,
444
(nsIDeviceContext*)this);
448
rv = dcxp->QueryInterface(NS_GET_IID(nsIDeviceContext),
453
#endif /* USE_XPRINT */
454
#ifdef USE_POSTSCRIPT
455
if (method == pmPostScript) { // PostScript
457
static NS_DEFINE_CID(kCDeviceContextPS, NS_DEVICECONTEXTPS_CID);
459
// Create a Postscript device context
460
nsCOMPtr<nsIDeviceContextPS> dcps(do_CreateInstance(kCDeviceContextPS, &rv));
461
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create PS Device context.");
463
return NS_ERROR_GFX_COULD_NOT_LOAD_PRINT_MODULE;
465
rv = dcps->SetSpec(aDevice);
469
rv = dcps->InitDeviceContextPS((nsIDeviceContext*)aContext,
470
(nsIDeviceContext*)this);
474
rv = dcps->QueryInterface(NS_GET_IID(nsIDeviceContext),
478
#endif /* USE_POSTSCRIPT */
480
NS_WARNING("no print module created.");
481
return NS_ERROR_UNEXPECTED;
484
NS_IMETHODIMP nsDeviceContextXlib::BeginDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage)
486
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::BeginDocument()\n"));
490
NS_IMETHODIMP nsDeviceContextXlib::EndDocument(void)
492
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::EndDocument()\n"));
496
NS_IMETHODIMP nsDeviceContextXlib::AbortDocument(void)
498
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::EndDocument()\n"));
502
NS_IMETHODIMP nsDeviceContextXlib::BeginPage(void)
504
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::BeginPage()\n"));
508
NS_IMETHODIMP nsDeviceContextXlib::EndPage(void)
510
PR_LOG(DeviceContextXlibLM, PR_LOG_DEBUG, ("nsDeviceContextXlib::EndPage()\n"));
514
class nsFontCacheXlib : public nsFontCache
517
/* override DeviceContextImpl::CreateFontCache() */
518
virtual nsresult CreateFontMetricsInstance(nsIFontMetrics** aResult);
522
nsresult nsFontCacheXlib::CreateFontMetricsInstance(nsIFontMetrics** aResult)
524
NS_PRECONDITION(aResult, "null out param");
525
nsIFontMetrics *fm = new nsFontMetricsXlib();
527
return NS_ERROR_OUT_OF_MEMORY;
533
/* override DeviceContextImpl::CreateFontCache() */
534
NS_IMETHODIMP nsDeviceContextXlib::CreateFontCache()
536
mFontCache = new nsFontCacheXlib();
537
if (nsnull == mFontCache) {
538
return NS_ERROR_OUT_OF_MEMORY;
540
return mFontCache->Init(this);