[OS/2] Bug 333235: initial checkin of new files for Thebes on OS/2, this should fix the cairo-os2 build break. sr=pavlov

This commit is contained in:
mozilla%weilbacher.org 2007-02-24 10:58:48 +00:00
parent 1e5bc6c693
commit 4c1e8df200
8 changed files with 1654 additions and 0 deletions

View File

@ -0,0 +1,200 @@
/* vim: set sw=4 sts=4 et cin: */
/* ***** 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 OS/2 system font code in Thebes.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Developers of code taken from nsDeviceContextOS2:
* John Fairhurst, <john_fairhurst@iname.com>
* Henry Sobotka <sobotka@axess.com>
* IBM Corp.
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 "nsIDeviceContext.h"
#include "nsUnitConversion.h"
#include "nsSystemFontsOS2.h"
#include <stdlib.h>
/************************
* Helper functions *
************************/
static BOOL bIsDBCS;
static BOOL bIsDBCSSet = FALSE;
/* Helper function to determine if we are running on DBCS */
BOOL IsDBCS()
{
if (!bIsDBCSSet) {
// the following lines of code determine whether the system is a DBCS country
APIRET rc;
COUNTRYCODE ctrycodeInfo = {0};
CHAR achDBCSInfo[12] = {0}; // DBCS environmental vector
ctrycodeInfo.country = 0; // current country
ctrycodeInfo.codepage = 0; // current codepage
rc = DosQueryDBCSEnv(sizeof(achDBCSInfo), &ctrycodeInfo, achDBCSInfo);
if (rc == NO_ERROR) {
// Non-DBCS countries will have four bytes in the first four bytes of the
// DBCS environmental vector
if (achDBCSInfo[0] != 0 || achDBCSInfo[1] != 0 ||
achDBCSInfo[2] != 0 || achDBCSInfo[3] != 0)
{
bIsDBCS = TRUE;
} else {
bIsDBCS = FALSE;
}
} else {
bIsDBCS = FALSE;
} /* endif */
bIsDBCSSet = TRUE;
} /* endif */
return bIsDBCS;
}
/* 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 */
/* WarpSans is only available on Warp 4, we exclude Warp 3 now */
if (!IsDBCS()) {
strcpy(fontName, "9.WarpSans");
} else {
strcpy(fontName, "9.WarpSans Combined");
}
} else {
/* null terminate fontname */
fontName[ulMaxNameL] = '\0';
}
}
/************************/
nsSystemFontsOS2::nsSystemFontsOS2()
{
#ifdef DEBUG_thebes
printf("nsSystemFontsOS2::nsSystemFontsOS2()\n");
#endif
}
nsresult nsSystemFontsOS2::GetSystemFont(nsSystemFontID aID, nsString* aFontName,
gfxFontStyle *aFontStyle) const
{
return GetSystemFontInfo(aID, aFontName, aFontStyle);
}
nsresult nsSystemFontsOS2::GetSystemFontInfo(nsSystemFontID aID, nsString* aFontName,
gfxFontStyle *aFontStyle) const
{
#ifdef DEBUG_thebes
printf("nsSystemFontsOS2::GetSystemFontInfo: ");
#endif
char szFontNameSize[MAXNAMEL];
switch (aID)
{
case eSystemFont_Icon:
QueryFontFromINI("IconText", szFontNameSize, MAXNAMEL);
#ifdef DEBUG_thebes
printf("IconText ");
#endif
break;
case eSystemFont_Menu:
QueryFontFromINI("Menus", szFontNameSize, MAXNAMEL);
#ifdef DEBUG_thebes
printf("Menus ");
#endif
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);
#ifdef DEBUG_thebes
printf("WindowText ");
#endif
break;
default:
NS_WARNING("None of the listed font types, using 9.WarpSans");
#ifdef DEBUG_thebes
printf("using 9.WarpSans... ");
#endif
strcpy(szFontNameSize, "9.WarpSans");
} // switch
#ifdef DEBUG_thebes
printf(" (%s)\n", szFontNameSize);
#endif
int pointSize = atoi(szFontNameSize);
char *szFacename = strchr(szFontNameSize, '.');
if ((pointSize == 0) || (!szFacename) || (*(szFacename++) == '\0'))
return NS_ERROR_FAILURE;
NS_NAMED_LITERAL_STRING(quote, "\""); // seems like we need quotes around the font name
NS_ConvertUTF8toUTF16 fontFace(szFacename);
*aFontName = quote + fontFace + quote;
// As in old gfx/src/os2 set the styles to the defaults
aFontStyle->style = FONT_STYLE_NORMAL;
aFontStyle->variant = FONT_VARIANT_NORMAL;
aFontStyle->weight = FONT_WEIGHT_NORMAL;
aFontStyle->decorations = FONT_DECORATION_NONE;
aFontStyle->size = gfxFloat(pointSize);
aFontStyle->systemFont = PR_TRUE;
return NS_OK;
}

View File

@ -0,0 +1,62 @@
/* vim: set sw=4 sts=4 et cin: */
/* ***** 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 OS/2 system font code in Thebes.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* John Fairhurst, <john_fairhurst@iname.com> } original developers of
* Henry Sobotka <sobotka@axess.com> } code taken from
* IBM Corp. } nsDeviceContextOS2
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 ***** */
#ifndef _NS_SYSTEMFONTSOS2_H_
#define _NS_SYSTEMFONTSOS2_H_
#include <gfxFont.h>
#define INCL_WINSHELLDATA
#define INCL_DOSNLS
#define INCL_DOSERRORS
#include <os2.h>
class nsSystemFontsOS2
{
public:
nsSystemFontsOS2();
nsresult GetSystemFont(nsSystemFontID aID, nsString* aFontName,
gfxFontStyle *aFontStyle) const;
private:
nsresult GetSystemFontInfo(nsSystemFontID aID, nsString* aFontName,
gfxFontStyle *aFontStyle) const;
};
#endif /* _NS_SYSTEMFONTSOS2_H_ */

View File

@ -0,0 +1,184 @@
/* vim: set sw=4 sts=4 et cin: */
/* ***** 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 OS/2 code in Thebes.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* IBM Corp. (code inherited from nsFontMetricsOS2 and OS2Uni)
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 ***** */
#ifndef GFX_OS2_FONTS_H
#define GFX_OS2_FONTS_H
#include "gfxTypes.h"
#include "gfxFont.h"
#define INCL_GPI
#include <os2.h>
#include <cairo-os2.h>
#include "nsAutoBuffer.h"
#include "nsICharsetConverterManager.h"
class gfxOS2Font : public gfxFont {
public:
gfxOS2Font(const nsAString &aName, const gfxFontStyle *aFontStyle);
virtual ~gfxOS2Font();
virtual const gfxFont::Metrics& GetMetrics();
double GetWidth(HPS aPS, const char* aString, PRUint32 aLength);
double GetWidth(HPS aPS, const PRUnichar* aString, PRUint32 aLength);
protected:
//cairo_font_face_t *CairoFontFace();
//cairo_scaled_font_t *CairoScaledFont();
private:
void ComputeMetrics();
//cairo_font_face_t *mFontFace;
gfxFont::Metrics *mMetrics;
//FATTRS mFAttrs;
};
class THEBES_API gfxOS2FontGroup : public gfxFontGroup {
public:
gfxOS2FontGroup(const nsAString& aFamilies, const gfxFontStyle* aStyle);
virtual ~gfxOS2FontGroup();
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle) {
NS_ERROR("NOT IMPLEMENTED");
return nsnull;
}
virtual gfxTextRun *MakeTextRun(const PRUnichar* aString, PRUint32 aLength, Parameters* aParams);
virtual gfxTextRun *MakeTextRun(const PRUint8* aString, PRUint32 aLength, Parameters* aParams);
const nsACString& GetGenericFamily() const {
return mGenericFamily;
}
PRUint32 FontListLength() const {
return mFonts.Length();
}
gfxOS2Font *GetFontAt(PRInt32 i) {
return NS_STATIC_CAST(gfxOS2Font*, NS_STATIC_CAST(gfxFont*, mFonts[i]));
}
void AppendFont(gfxOS2Font *aFont) {
mFonts.AppendElement(aFont);
}
PRBool HasFontNamed(const nsAString& aName) const {
PRUint32 len = mFonts.Length();
for (PRUint32 i = 0; i < len; ++i)
if (aName.Equals(mFonts[i]->GetName()))
return PR_TRUE;
return PR_FALSE;
}
protected:
static PRBool MakeFont(const nsAString& fontName,
const nsACString& genericName,
void *closure);
private:
friend class gfxOS2TextRun;
nsCString mGenericFamily;
};
class THEBES_API gfxOS2TextRun {
public:
gfxOS2TextRun(const nsAString& aString, gfxOS2FontGroup *aFontGroup);
gfxOS2TextRun(const nsACString& aString, gfxOS2FontGroup *aFontGroup);
~gfxOS2TextRun();
virtual void Draw(gfxContext *aContext, gfxPoint pt);
virtual gfxFloat Measure(gfxContext *aContext);
virtual void SetSpacing(const nsTArray<gfxFloat>& spacingArray);
virtual const nsTArray<gfxFloat> *const GetSpacing() const;
void SetRightToLeft(PRBool aIsRTL) { mIsRTL = aIsRTL; }
PRBool IsRightToLeft() { return mIsRTL; }
protected:
private:
/* these only return a length measurement if aDraw is PR_FALSE *
* we have an easy and a sophisticated variant */
double MeasureOrDrawFast(gfxContext *aContext, PRBool aDraw, gfxPoint aPt);
double MeasureOrDrawSlow(gfxContext *aContext, PRBool aDraw, gfxPoint aPt);
gfxOS2FontGroup *mGroup;
nsString mString;
nsCString mCString;
const PRPackedBool mIsASCII;
PRPackedBool mIsRTL;
nsTArray<gfxFloat> mSpacing;
double mLength; /* cached */
};
// =============================================================================
// class gfxOS2Uni to handle Unicode on OS/2 (copied from gfx/src/os2)
enum ConverterRequest {
eConv_Encoder,
eConv_Decoder
};
#define CHAR_BUFFER_SIZE 1024
typedef nsAutoBuffer<char, CHAR_BUFFER_SIZE> nsAutoCharBuffer;
typedef nsAutoBuffer<PRUnichar, CHAR_BUFFER_SIZE> nsAutoChar16Buffer;
class gfxOS2Uni {
public:
static nsISupports* GetUconvObject(int CodePage, ConverterRequest aReq);
static void FreeUconvObjects();
private:
static nsICharsetConverterManager* gCharsetManager;
};
nsresult WideCharToMultiByte(int aCodePage,
const PRUnichar* aSrc, PRInt32 aSrcLength,
nsAutoCharBuffer& aResult, PRInt32& aResultLength);
nsresult MultiByteToWideChar(int aCodePage,
const char* aSrc, PRInt32 aSrcLength,
nsAutoChar16Buffer& aResult, PRInt32& aResultLength);
// =============================================================================
#endif /* GFX_OS2_FONTS_H */

View File

@ -0,0 +1,74 @@
/* vim: set sw=4 sts=4 et cin: */
/* ***** 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 OS/2 code in Thebes.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 ***** */
#ifndef GFX_OS2_PLATFORM_H
#define GFX_OS2_PLATFORM_H
#define INCL_GPIBITMAPS
#include <os2.h>
#include "gfxPlatform.h"
class THEBES_API gfxOS2Platform : public gfxPlatform {
public:
gfxOS2Platform();
virtual ~gfxOS2Platform();
static gfxOS2Platform *GetPlatform() {
return (gfxOS2Platform*) gfxPlatform::GetPlatform();
}
already_AddRefed<gfxASurface>
CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxImageFormat imageFormat);
nsresult GetFontList(const nsACString& aLangGroup,
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts);
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
private:
HDC mDC;
HPS mPS;
HBITMAP mBitmap;
};
#endif /* GFX_OS2_PLATFORM_H */

View File

@ -0,0 +1,62 @@
/* vim: set sw=4 sts=4 et cin: */
/* ***** 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 OS/2 code in Thebes.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 ***** */
#ifndef GFX_OS2_SURFACE_H
#define GFX_OS2_SURFACE_H
#include "gfxASurface.h"
#include <os2.h>
#include <cairo-os2.h>
class THEBES_API gfxOS2Surface : public gfxASurface {
public:
gfxOS2Surface(HPS aPS, const gfxIntSize& aSize);
gfxOS2Surface(HWND aWnd);
virtual ~gfxOS2Surface();
HPS GetPS() { return mPS; }
gfxIntSize GetSize() { return mSize; }
private:
PRBool mOwnsPS;
HPS mPS;
gfxIntSize mSize;
};
#endif /* GFX_OS2_SURFACE_H */

View File

@ -0,0 +1,809 @@
/* vim: set sw=4 sts=4 et cin: */
/* ***** 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 OS/2 code in Thebes.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* IBM Corp. (code inherited from nsFontMetricsOS2 and OS2Uni)
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 "gfxContext.h"
#include "gfxOS2Platform.h"
#include "gfxOS2Surface.h"
#include "gfxOS2Fonts.h"
#include "nsIServiceManager.h"
#include "nsIPlatformCharset.h"
/**********************************************************************
* helper macros and functions
**********************************************************************/
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define MK_RGB(r,g,b) ((LONG)r*255 * 65536) + ((LONG)g*255 * 256) + ((LONG)b*255)
// get the extent of bit of text and return it in aSizeL->cx and cy
BOOL GetTextExtentPoint32(HPS aPS, const char* aString, int aLength, PSIZEL aSizeL)
{
BOOL rc = TRUE;
POINTL ptls[5];
aSizeL->cx = 0;
while (aLength > 0 && rc == TRUE) {
ULONG thislen = min(aLength, 512);
rc = GpiQueryTextBox(aPS, thislen, (PCH)aString, 5, ptls);
aSizeL->cx += ptls[TXTBOX_CONCAT].x;
aLength -= thislen;
aString += thislen;
}
aSizeL->cy = ptls[TXTBOX_TOPLEFT].y - ptls[TXTBOX_BOTTOMLEFT].y;
return rc;
}
BOOL ExtTextOut(HPS aPS, int aX, int aY, UINT aFuOptions, const RECTL* aLprc,
const char* aString, unsigned int aLength, const int* aPSpacing)
{
long rc = GPI_OK;
POINTL ptl = { aX, aY};
GpiMove(aPS, &ptl);
// GpiCharString has a max length of 512 chars at a time...
while (aLength > 0 && rc == GPI_OK) {
ULONG ulChunkLen = min(aLength, 512);
if (aPSpacing) {
rc = GpiCharStringPos(aPS, nsnull, CHS_VECTOR, ulChunkLen,
(PCH)aString, (PLONG)aPSpacing);
aPSpacing += ulChunkLen;
} else {
rc = GpiCharString(aPS, ulChunkLen, (PCH)aString);
}
aLength -= ulChunkLen;
aString += ulChunkLen;
}
if (rc != GPI_ERROR)
return TRUE;
else
return FALSE;
}
/**********************************************************************
* class gfxOS2Font
**********************************************************************/
gfxOS2Font::gfxOS2Font(const nsAString &aName, const gfxFontStyle *aFontStyle)
: gfxFont(aName, aFontStyle), mMetrics(nsnull)
{
#ifdef DEBUG_thebes
printf("gfxOS2Font::gfxOS2Font(\"%s\", aFontStyle)\n",
NS_LossyConvertUTF16toASCII(aName).get());
#endif
}
gfxOS2Font::~gfxOS2Font()
{
#ifdef DEBUG_thebes
printf("gfxOS2Font::~gfxOS2Font()\n");
#endif
if (mMetrics)
delete mMetrics;
mMetrics = nsnull;
}
const gfxFont::Metrics& gfxOS2Font::GetMetrics()
{
if (!mMetrics)
ComputeMetrics();
return *mMetrics;
}
void gfxOS2Font::ComputeMetrics()
{
if (!mMetrics)
mMetrics = new gfxFont::Metrics;
HPS hps = WinGetPS(HWND_DESKTOP); // temporary PS to get font metrics
FONTMETRICS fm;
if (GpiQueryFontMetrics(hps, sizeof(fm), &fm)) {
mMetrics->xHeight = fm.lXHeight;
mMetrics->superscriptOffset = fm.lSuperscriptYOffset;
mMetrics->subscriptOffset = fm.lSubscriptYOffset;
mMetrics->strikeoutSize = fm.lStrikeoutSize;
mMetrics->strikeoutOffset = fm.lStrikeoutPosition;
mMetrics->underlineSize = fm.lUnderscoreSize;
mMetrics->underlineOffset = fm.lUnderscorePosition;
mMetrics->internalLeading = fm.lInternalLeading;
mMetrics->externalLeading = fm.lExternalLeading;
mMetrics->emHeight = fm.lEmHeight;
mMetrics->emAscent = fm.lLowerCaseAscent;
mMetrics->emDescent = fm.lLowerCaseDescent;
mMetrics->maxHeight = fm.lXHeight + fm.lMaxAscender + fm.lMaxDescender;
mMetrics->maxAscent = fm.lMaxAscender;
mMetrics->maxDescent = fm.lMaxDescender;
mMetrics->maxAdvance = fm.lMaxCharInc;
mMetrics->aveCharWidth = fm.lAveCharWidth;
// special handling for space width
SIZEL space;
GetTextExtentPoint32(hps, " ", 1, &space);
mMetrics->spaceWidth = space.cx;
}
WinReleasePS(hps);
#ifdef DEBUG_thebes
printf("gfxOS2Font::ComputeMetrics():\n"
" emHeight=%f\n"
" maxHeight=%f\n"
" aveCharWidth=%f\n"
" spaceWidth=%ld/%f\n",
mMetrics->emHeight,
mMetrics->maxHeight,
mMetrics->aveCharWidth,
fm.lMaxCharInc, mMetrics->spaceWidth);
#endif
}
double gfxOS2Font::GetWidth(HPS aPS, const char* aString, PRUint32 aLength)
{
#ifdef DEBUG_thebes
printf("gfxOS2Font::GetWidth(ASCII)\n");
#endif
SIZEL size;
GetTextExtentPoint32(aPS, aString, aLength, &size);
return (double)size.cx;
}
double gfxOS2Font::GetWidth(HPS aPS, const PRUnichar* aString, PRUint32 aLength)
{
#ifdef DEBUG_thebes
printf("gfxOS2Font::GetWidth(WIDE)\n");
#endif
nsAutoCharBuffer buffer;
PRInt32 destLength = aLength;
// XXX dummy convert!
if (WideCharToMultiByte(0, aString, aLength, buffer, destLength))
return 0.0; // somehow the conversion did not work
SIZEL size;
GetTextExtentPoint32(aPS, buffer.get(), destLength, &size);
return (double)size.cx;
}
/**********************************************************************
* class gfxOS2FontGroup
**********************************************************************/
gfxOS2FontGroup::gfxOS2FontGroup(const nsAString& aFamilies, const gfxFontStyle* aStyle)
: gfxFontGroup(aFamilies, aStyle)
{
#ifdef DEBUG_thebes
printf("gfxOS2FontGroup::gfxOS2FontGroup(\"%s\", %#x)\n",
NS_LossyConvertUTF16toASCII(aFamilies).get(), (unsigned)aStyle);
#endif
//mFontCache.Init(25);
ForEachFont(MakeFont, this);
if (mGenericFamily.IsEmpty())
FindGenericFontFromStyle(MakeFont, this);
if (mFonts.Length() == 0) {
// Should append default GUI font if there are no available fonts.
// We use WarpSans as in the default case in nsSystemFontsOS2.
nsAutoString defaultFont(NS_LITERAL_STRING("WarpSans"));
MakeFont(defaultFont, mGenericFamily, this);
}
}
gfxOS2FontGroup::~gfxOS2FontGroup()
{
#ifdef DEBUG_thebes
printf("gfxOS2FontGroup::~gfxOS2FontGroup()\n");
#endif
}
// gfxWrapperTextRun, adapted the code from gfxAtsui/gfxWindowsFonts.cpp
class gfxWrapperTextRun : public gfxTextRun {
public:
gfxWrapperTextRun(gfxOS2FontGroup *aGroup, const PRUint8* aString, PRUint32 aLength,
gfxTextRunFactory::Parameters* aParams)
: gfxTextRun(aParams), mContext(aParams->mContext),
mInner(nsDependentCSubstring(reinterpret_cast<const char*>(aString),
reinterpret_cast<const char*>(aString + aLength)),
aGroup),
mLength(aLength)
{
mInner.SetRightToLeft(IsRightToLeft());
}
gfxWrapperTextRun(gfxOS2FontGroup *aGroup, const PRUnichar* aString, PRUint32 aLength,
gfxTextRunFactory::Parameters* aParams)
: gfxTextRun(aParams), mContext(aParams->mContext),
mInner(nsDependentSubstring(aString, aString + aLength), aGroup),
mLength(aLength)
{
mInner.SetRightToLeft(IsRightToLeft());
}
~gfxWrapperTextRun() {}
virtual void GetCharFlags(PRUint32 aStart, PRUint32 aLength, PRUint8* aFlags) { NS_ERROR("NOT IMPLEMENTED"); }
virtual PRUint8 GetCharFlags(PRUint32 aOffset) { NS_ERROR("NOT IMPLEMENTED"); return 0; }
virtual PRUint32 GetLength() { NS_ERROR("NOT IMPLEMENTED"); return 0; }
virtual PRBool SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength, PRPackedBool* aBreakBefore) { NS_ERROR("NOT IMPLEMENTED"); return PR_FALSE; }
virtual void DrawToPath(gfxContext *aContext, gfxPoint aPt, PRUint32 aStart, PRUint32 aLength, PropertyProvider* aBreakProvider, gfxFloat* aAdvanceWidth) { NS_ERROR("NOT IMPLEMENTED"); }
virtual Metrics MeasureText(PRUint32 aStart, PRUint32 aLength, PRBool aTightBoundingBox, PropertyProvider* aBreakProvider) { NS_ERROR("NOT IMPLEMENTED"); return Metrics(); }
virtual void SetLineBreaks(PRUint32 aStart, PRUint32 aLength, PRBool aLineBreakBefore, PRBool aLineBreakAfter, TextProvider* aProvider, gfxFloat* aAdvanceWidthDelta) { NS_ERROR("NOT IMPLEMENTED"); }
virtual PRUint32 BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength, PRBool aLineBreakBefore, gfxFloat aWidth, PropertyProvider* aProvider, PRBool aSuppressInitialBreak, Metrics* aMetrics, PRBool aTightBoundingBox, PRBool* aUsedHyphenation, PRUint32* aLastBreak) { NS_ERROR("NOT IMPLEMENTED"); return 0; }
virtual void Draw(gfxContext *aContext, gfxPoint aPt, PRUint32 aStart, PRUint32 aLength, const gfxRect* aDirtyRect, PropertyProvider* aBreakProvider, gfxFloat* aAdvanceWidth);
virtual gfxFloat GetAdvanceWidth(PRUint32 aStart, PRUint32 aLength, PropertyProvider* aBreakProvider);
virtual void SetContext(gfxContext* aContext) { mContext = aContext; }
private:
gfxContext* mContext;
gfxOS2TextRun mInner;
PRUint32 mLength;
void SetupSpacingFromProvider(PropertyProvider* aProvider);
};
#define ROUND(x) floor((x) + 0.5)
void gfxWrapperTextRun::SetupSpacingFromProvider(PropertyProvider* aProvider)
{
if (!(mFlags & gfxTextRunFactory::TEXT_ENABLE_SPACING))
return;
NS_ASSERTION(mFlags & gfxTextRunFactory::TEXT_ABSOLUTE_SPACING,
"Can't handle relative spacing");
nsAutoTArray<PropertyProvider::Spacing,200> spacing;
spacing.AppendElements(mLength);
aProvider->GetSpacing(0, mLength, spacing.Elements());
nsTArray<gfxFloat> spaceArray;
PRUint32 i;
gfxFloat offset = 0;
for (i = 0; i < mLength; ++i) {
NS_ASSERTION(spacing.Elements()[i].mBefore == 0, "Can't handle before-spacing!");
gfxFloat nextOffset = offset + spacing.Elements()[i].mAfter/mAppUnitsPerDevUnit;
spaceArray.AppendElement(ROUND(nextOffset) - ROUND(offset));
offset = nextOffset;
}
mInner.SetSpacing(spaceArray);
}
void gfxWrapperTextRun::Draw(gfxContext *aContext,
gfxPoint aPt,
PRUint32 aStart,
PRUint32 aLength,
const gfxRect* aDirtyRect,
PropertyProvider* aBreakProvider,
gfxFloat* aAdvanceWidth)
{
NS_ASSERTION(aStart == 0 && aLength == mLength, "Can't handle substrings");
SetupSpacingFromProvider(aBreakProvider);
gfxPoint pt(aPt.x/mAppUnitsPerDevUnit, aPt.y/mAppUnitsPerDevUnit);
return mInner.Draw(mContext, pt);
}
gfxFloat gfxWrapperTextRun::GetAdvanceWidth(PRUint32 aStart,
PRUint32 aLength,
PropertyProvider* aBreakProvider)
{
NS_ASSERTION(aStart == 0 && aLength == mLength, "Can't handle substrings");
SetupSpacingFromProvider(aBreakProvider);
return mInner.Measure(mContext)*mAppUnitsPerDevUnit;
}
gfxTextRun *gfxOS2FontGroup::MakeTextRun(const PRUnichar* aString,
PRUint32 aLength,
Parameters* aParams)
{
return new gfxWrapperTextRun(this, aString, aLength, aParams);
}
gfxTextRun *gfxOS2FontGroup::MakeTextRun(const PRUint8* aString,
PRUint32 aLength,
Parameters* aParams)
{
aParams->mFlags |= TEXT_IS_8BIT;
return new gfxWrapperTextRun(this, aString, aLength, aParams);
}
PRBool gfxOS2FontGroup::MakeFont(const nsAString& aName,
const nsACString& aGenericName,
void *closure)
{
#ifdef DEBUG_thebes
printf("gfxOS2FontGroup::MakeFont(\"%s\", \"%s\", %#x)\n",
NS_LossyConvertUTF16toASCII(aName).get(),
nsPromiseFlatCString(aGenericName).get(), (unsigned)closure);
#endif
if (!aName.IsEmpty()) {
gfxOS2FontGroup *fg = NS_STATIC_CAST(gfxOS2FontGroup*, closure);
if (fg->HasFontNamed(aName))
return PR_TRUE;
gfxOS2Font *font = new gfxOS2Font(aName, fg->GetStyle());
fg->AppendFont(font);
if (!aGenericName.IsEmpty() && fg->GetGenericFamily().IsEmpty())
fg->mGenericFamily = aGenericName;
}
return PR_TRUE;
}
/**********************************************************************
* class gfxOS2TextRun
**********************************************************************/
// Helper to easily get the presentation handle from a gfxSurface
inline HPS GetPSFromSurface(gfxASurface *aSurface) {
if (aSurface->GetType() != gfxASurface::SurfaceTypeOS2) {
NS_ERROR("gfxOS2TextRun: GetPSFromSurface: Context target is not os2!");
return nsnull;
}
return NS_STATIC_CAST(gfxOS2Surface*, aSurface)->GetPS();
}
// Helper to easily get the size from a gfxSurface
inline gfxIntSize GetSizeFromSurface(gfxASurface *aSurface) {
gfxIntSize size(0, 0);
if (aSurface->GetType() != gfxASurface::SurfaceTypeOS2) {
NS_ERROR("gfxOS2TextRun: GetPSFromSurface: Context target is not os2!");
return size;
}
return NS_STATIC_CAST(gfxOS2Surface*, aSurface)->GetSize();
}
gfxOS2TextRun::gfxOS2TextRun(const nsAString& aString, gfxOS2FontGroup *aFontGroup)
: mGroup(aFontGroup), mString(aString), mIsASCII(PR_FALSE), mLength(-1.0)
{
#ifdef DEBUG_thebes
printf("gfxOS2TextRun::gfxOS2TextRun(nsAString \"%s\", %#x)\n",
NS_LossyConvertUTF16toASCII(aString).get(), (unsigned)aFontGroup);
#endif
}
gfxOS2TextRun::gfxOS2TextRun(const nsACString& aString, gfxOS2FontGroup *aFontGroup)
: mGroup(aFontGroup), mCString(aString), mIsASCII(PR_TRUE), mLength(-1.0)
{
#ifdef DEBUG_thebes
printf("gfxOS2TextRun::gfxOS2TextRun(nsACString \"%s\", %#x)\n",
nsPromiseFlatCString(aString).get(), (unsigned)aFontGroup);
#endif
}
gfxOS2TextRun::~gfxOS2TextRun()
{
#ifdef DEBUG_thebes
printf("gfxOS2TextRun::~gfxOS2TextRun()\n");
#endif
}
void gfxOS2TextRun::Draw(gfxContext *aContext, gfxPoint aPt)
{
#ifdef DEBUG_thebes
printf("gfxOS2TextRun::Draw(...): ");
#endif
const char *string;
if (mIsASCII) {
string = mCString.get();
} else {
string = NS_LossyConvertUTF16toASCII(mString).get();
}
#ifdef DEBUG_thebes
printf("%s\n", string);
#endif
#ifdef USE_CAIRO_FOR_DRAWING
cairo_t *cr = aContext->GetCairo();
if (!cr) {
printf(" no cairo context!\n");
return;
}
cairo_select_font_face(cr, "Helvetica", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 12.0);
cairo_show_text(cr, string);
#else
double rc = MeasureOrDrawFast(aContext, PR_TRUE, aPt);
if (rc >= 0) {
return;
}
MeasureOrDrawSlow(aContext, PR_TRUE, aPt);
#endif
}
gfxFloat gfxOS2TextRun::Measure(gfxContext *aContext)
{
#ifdef DEBUG_thebes
printf("gfxOS2TextRun::Measure(...): ");
#endif
const char *string;
if (mIsASCII) {
string = mCString.get();
} else {
string = NS_LossyConvertUTF16toASCII(mString).get();
}
#ifdef DEBUG_thebes
printf("%s\n", string);
#endif
static const gfxPoint kZeroZero(0, 0);
if (mLength < 0) {
#ifdef USE_CAIRO_FOR_DRAWING
cairo_t *cr = aContext->GetCairo();
cairo_text_extents_t extents;
if (!cr) {
printf(" no cairo context!\n");
return -1;
}
cairo_select_font_face(cr, "Helvetica", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 12.0);
cairo_text_extents(cr, string, &extents);
mLength = extents.width;
#ifdef DEBUG_thebes
printf(" string=%s\n", string);
printf(" font\n");
printf(" size\n");
printf(" extents\n");
printf(" mLength=%f\n",mLength);
#endif
#else
mLength = MeasureOrDrawFast(aContext, PR_FALSE, kZeroZero);
#endif
if (mLength >= 0) {
return mLength;
}
// need something more sophisticated
mLength = MeasureOrDrawSlow(aContext, PR_FALSE, kZeroZero);
}
return mLength;
}
double
gfxOS2TextRun::MeasureOrDrawFast(gfxContext *aContext, PRBool aDraw, gfxPoint aPt)
{
#ifdef DEBUG_thebes
printf("gfxOS2TextRun::MeasureOrDrawFast(0x%p, %d, aPt)\n", (void*)aContext, aDraw);
#endif
double length = 0;
gfxRGBA color;
//#ifdef WE_HAVE_REALLY_FAST
if (!aContext->CurrentMatrix().HasNonTranslation()) {
// need to not call this if the color isn't solid
// or the pattern isn't a color
// or the destination has alpha
if (mSpacing.IsEmpty()) { // XXX remove this once the below handles spacing
if (aContext->GetColor(color) && color.a == 1) {
// we can measure with 32bpp surfaces, but we can't draw to them using this API
nsRefPtr<gfxASurface> currentSurface = aContext->CurrentSurface();
if (!aDraw || currentSurface->GetContentType() == gfxASurface::CONTENT_COLOR) {
// XXX version of Windows' MeasureOrDrawReallyFast(...)
#ifdef DEBUG_thebes
printf(" should call MeasureOrDrawReallyFast()\n");
#endif
} // if !aDraw
} // if color
} // if not empty spacing
} // if !...HasNonTranslation()
//#endif
if (IsRightToLeft()) { // this function doesn't handle RTL text
return -1;
}
const char *asciiString;
const PRUnichar *wideString;
PRUint32 stringLength;
if (mIsASCII) {
asciiString = mCString.BeginReading();
stringLength = mCString.Length();
} else {
wideString = mString.BeginReading();
stringLength = mString.Length();
// XXX there is no "ScriptIsComplex(...)" API on OS/2,
// not sure what to do
}
nsRefPtr<gfxASurface> surf = aContext->CurrentSurface();
HPS hps = GetPSFromSurface(surf);
NS_ASSERTION(hps, "No HPS");
nsRefPtr<gfxOS2Font> currentFont = mGroup->GetFontAt(0);
//GpiCreateLogFont(hps, NULL, 1, currentFont->mFAttrs)
if (aDraw) {
aContext->GetColor(color);
LONG lColor = MK_RGB(color.r, color.g, color.b);
if (lColor == 0x0) {
// XXX somehow CLR_BLACK is -1 not 0, will palette handling perhaps rectify this?
lColor = CLR_BLACK;
}
#ifdef DEBUG_thebes
printf(" color(RGBA)=%f,%f,%f,%f, 0x%0lx\n", color.r, color.g, color.b, color.a, lColor);
#endif
GpiSetColor(hps, lColor);
GpiSetBackColor(hps, CLR_BACKGROUND);
//GpiSetBackMix(hps, BM_LEAVEALONE); // XXX BM_LEAVEALONE is default
aContext->UpdateSurfaceClip();
gfxPoint offset;
nsRefPtr<gfxASurface> surf = aContext->CurrentSurface(&offset.x, &offset.y);
gfxIntSize size = GetSizeFromSurface(surf);
gfxPoint p = aContext->CurrentMatrix().Transform(aPt) + offset;
p.y = (gfxFloat)size.height - p.y;
//#define SIMPLE_DRAW
#ifdef SIMPLE_DRAW
POINTL startPos = { (LONG)p.x, (LONG)p.y };
#endif
// finally output it
if (mIsASCII) {
#ifdef SIMPLE_DRAW
GpiCharStringAt(hps, &startPos, stringLength, asciiString);
#else
ExtTextOut(hps, (int)p.x, (int)p.y, 0, NULL, asciiString, stringLength, NULL);
#endif
#ifdef DEBUG_thebes
printf(" string=%s\n", asciiString);
#endif
} else {
nsAutoCharBuffer destBuffer;
PRInt32 destLength = stringLength;
// XXX dummy convert!
if (WideCharToMultiByte(0, wideString, stringLength, destBuffer, destLength)) {
#ifdef DEBUG_thebes
printf("conversion didn't work!\n");
#endif
return 0.0; // conversion didn't work
}
#ifdef SIMPLE_DRAW
GpiCharStringAt(hps, &startPos, destLength, destBuffer.get());
#else
ExtTextOut(hps, (int)p.x, (int)p.y, 0, NULL, destBuffer.get(), destLength, NULL);
#endif
#ifdef DEBUG_thebes
printf(" string=%s\n", destBuffer.get());
#endif
}
// XXX why do we need to mark dirty after Gpi function call?!
surf->MarkDirty();
} else { // just measure
if (mIsASCII) {
// XXX this gives rubbish!!
//length = currentFont->GetWidth(hps, asciiString, stringLength);
// XXX for now just take the average char width as good measure
length = currentFont->GetMetrics().aveCharWidth * stringLength;
} else {
// XXX this gives rubbish!!
// length = currentFont->GetWidth(hps, wideString, stringLength);
// XXX for now just take the average char width as good measure
length = currentFont->GetMetrics().aveCharWidth * stringLength;
}
#ifdef DEBUG_thebes
printf(" Measured as %f\n", length);
#endif
}
return length;
}
double
gfxOS2TextRun::MeasureOrDrawSlow(gfxContext *aContext, PRBool aDraw, gfxPoint aPt)
{
printf("gfxOS2TextRun::MeasureOrDrawSlow(.., %d, ..)\n", aDraw);
// XXX hack for now
return 12;
}
void gfxOS2TextRun::SetSpacing(const nsTArray<gfxFloat> &aSpacingArray)
{
#ifdef DEBUG_thebes
printf("gfxOS2TextRun::SetSpacing(...)\n");
#endif
mSpacing = aSpacingArray;
}
const nsTArray<gfxFloat> *const gfxOS2TextRun::GetSpacing() const
{
#ifdef DEBUG_thebes
printf("gfxOS2TextRun::GetSpacing()\n");
#endif
return &mSpacing;
}
/**********************************************************************
* class gfxOS2Uni, to handle Unicode on OS/2 (copied from gfx/src/os2)
**********************************************************************/
nsICharsetConverterManager* gfxOS2Uni::gCharsetManager = nsnull;
struct ConverterInfo
{
PRUint16 mCodePage;
char *mConvName;
nsIUnicodeEncoder *mEncoder;
nsIUnicodeDecoder *mDecoder;
};
#define eCONVERTER_COUNT 17
ConverterInfo gConverterInfo[eCONVERTER_COUNT] =
{
{ 0, "", nsnull, nsnull },
{ 1252, "windows-1252", nsnull, nsnull },
{ 1208, "UTF-8", nsnull, nsnull },
{ 1250, "windows-1250", nsnull, nsnull },
{ 1251, "windows-1251", nsnull, nsnull },
{ 813, "ISO-8859-7", nsnull, nsnull },
{ 1254, "windows-1254", nsnull, nsnull },
{ 864, "IBM864", nsnull, nsnull },
{ 1257, "windows-1257", nsnull, nsnull },
{ 874, "windows-874", nsnull, nsnull },
{ 932, "Shift_JIS", nsnull, nsnull },
{ 943, "Shift_JIS", nsnull, nsnull },
{ 1381, "GB2312", nsnull, nsnull },
{ 1386, "GB2312", nsnull, nsnull },
{ 949, "x-windows-949", nsnull, nsnull },
{ 950, "Big5", nsnull, nsnull },
{ 1361, "x-johab", nsnull, nsnull }
};
nsISupports* gfxOS2Uni::GetUconvObject(int aCodePage, ConverterRequest aReq)
{
if (gCharsetManager == nsnull) {
CallGetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &gCharsetManager);
}
nsresult rv;
nsISupports* uco = nsnull;
for (int i = 0; i < eCONVERTER_COUNT; i++) {
if (aCodePage == gConverterInfo[i].mCodePage) {
if (gConverterInfo[i].mEncoder == nsnull) {
const char* convname;
nsCAutoString charset;
if (aCodePage == 0) {
nsCOMPtr<nsIPlatformCharset>
plat(do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv)) {
plat->GetCharset(kPlatformCharsetSel_FileName, charset);
} else {
// default to IBM850 if this should fail
charset = "IBM850";
}
convname = charset.get();
} else {
convname = gConverterInfo[i].mConvName;
}
rv = gCharsetManager->GetUnicodeEncoderRaw(convname,
&gConverterInfo[i].mEncoder);
gConverterInfo[i].mEncoder->
SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace,
nsnull, '?');
gCharsetManager->GetUnicodeDecoderRaw(convname,
&gConverterInfo[i].mDecoder);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get converter");
}
if (aReq == eConv_Encoder) {
uco = gConverterInfo[i].mEncoder;
} else {
uco = gConverterInfo[i].mDecoder;
}
break;
}
}
return uco;
}
void gfxOS2Uni::FreeUconvObjects()
{
for (int i = 0; i < eCONVERTER_COUNT; i++) {
NS_IF_RELEASE(gConverterInfo[i].mEncoder);
NS_IF_RELEASE(gConverterInfo[i].mDecoder);
}
NS_IF_RELEASE(gCharsetManager);
}
nsresult WideCharToMultiByte(int aCodePage,
const PRUnichar* aSrc, PRInt32 aSrcLength,
nsAutoCharBuffer& aResult, PRInt32& aResultLength)
{
#ifdef DEBUG_thebes
printf("WideCharToMultiByte()\n");
#endif
nsresult rv;
nsISupports* sup = gfxOS2Uni::GetUconvObject(aCodePage, eConv_Encoder);
nsCOMPtr<nsIUnicodeEncoder> uco = do_QueryInterface(sup);
if (!uco || NS_FAILED(uco->GetMaxLength(aSrc, aSrcLength, &aResultLength))) {
return NS_ERROR_UNEXPECTED;
}
if (!aResult.EnsureElemCapacity(aResultLength + 1)) {
return NS_ERROR_OUT_OF_MEMORY;
}
char* str = aResult.get();
rv = uco->Convert(aSrc, &aSrcLength, str, &aResultLength);
aResult.get()[aResultLength] = '\0';
return rv;
}
nsresult MultiByteToWideChar(int aCodePage,
const char* aSrc, PRInt32 aSrcLength,
nsAutoChar16Buffer& aResult, PRInt32& aResultLength)
{
#ifdef DEBUG_thebes
printf("MultiByteToWideChar()\n");
#endif
nsresult rv;
nsISupports* sup = gfxOS2Uni::GetUconvObject(aCodePage, eConv_Decoder);
nsCOMPtr<nsIUnicodeDecoder> uco = do_QueryInterface(sup);
if (!uco || NS_FAILED(uco->GetMaxLength(aSrc, aSrcLength, &aResultLength))) {
return NS_ERROR_UNEXPECTED;
}
if (!aResult.EnsureElemCapacity(aResultLength + 1))
return NS_ERROR_OUT_OF_MEMORY;
PRUnichar* str = aResult.get();
rv = uco->Convert(aSrc, &aSrcLength, str, &aResultLength);
aResult.get()[aResultLength] = '\0';
return rv;
}

View File

@ -0,0 +1,163 @@
/* vim: set sw=4 sts=4 et cin: */
/* ***** 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 OS/2 code in Thebes.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 "gfxOS2Platform.h"
#include "gfxOS2Surface.h"
#include "gfxImageSurface.h"
/**********************************************************************
* class gfxOS2Platform
**********************************************************************/
gfxOS2Platform::gfxOS2Platform()
: mDC(NULL), mPS(NULL), mBitmap(NULL)
{
#ifdef DEBUG_thebes
printf("gfxOS2Platform::gfxOS2Platform()\n");
#endif
// this seems to be reasonably early in the process and only once,
// so it's a good place to initialize OS/2 cairo stuff
cairo_os2_init();
#ifdef DEBUG_thebes
printf(" cairo_os2_init() was called\n");
#endif
}
gfxOS2Platform::~gfxOS2Platform()
{
#ifdef DEBUG_thebes
printf("gfxOS2Platform::~gfxOS2Platform()\n");
#endif
if (mBitmap) {
GpiSetBitmap(mPS, NULL);
GpiDeleteBitmap(mBitmap);
}
if (mPS) {
GpiDestroyPS(mPS);
}
if (mDC) {
DevCloseDC(mDC);
}
// clean up OS/2 cairo stuff
cairo_os2_fini();
#ifdef DEBUG_thebes
printf(" cairo_os2_fini() was called\n");
#endif
}
already_AddRefed<gfxASurface>
gfxOS2Platform::CreateOffscreenSurface(const gfxIntSize& aSize,
gfxASurface::gfxImageFormat aImageFormat)
{
#ifdef DEBUG_thebes
printf("gfxOS2Platform::CreateOffscreenSurface(%d/%d, %d)\n",
aSize.width, aSize.height, aImageFormat);
#endif
gfxASurface *newSurface = nsnull;
// XXX we only ever seem to get aImageFormat=0 or ImageFormatARGB32 but
// I don't really know if we need to differ between ARGB32 and RGB24 here
if (aImageFormat == gfxASurface::ImageFormatARGB32 ||
aImageFormat == gfxASurface::ImageFormatRGB24)
{
// create a PS, partly taken from nsOffscreenSurface::Init(), i.e. nsDrawingSurfaceOS2.cpp
DEVOPENSTRUC dop = { 0, 0, 0, 0, 0 };
SIZEL sizel = { 0, 0 }; /* use same page size as device */
mDC = DevOpenDC(0, OD_MEMORY, "*", 5, (PDEVOPENDATA)&dop, NULLHANDLE);
if (mDC != DEV_ERROR) {
mPS = GpiCreatePS(0, mDC, &sizel, PU_PELS | GPIT_MICRO | GPIA_ASSOC);
if (mPS != GPI_ERROR) {
// XXX: nsPaletteOS2::SelectGlobalPalette(mPS);
// perhaps implement the palette stuff at some point?!
// now create a bitmap of the right size
BITMAPINFOHEADER2 hdr = { 0 };
hdr.cbFix = sizeof(BITMAPINFOHEADER2);
hdr.cx = aSize.width;
hdr.cy = aSize.height;
hdr.cPlanes = 1;
// find bit depth, XXX this may not work here, use the aImageFormat instead?!
LONG lBitCount = 0;
DevQueryCaps(mDC, CAPS_COLOR_BITCOUNT, 1, &lBitCount);
hdr.cBitCount = (USHORT)lBitCount;
mBitmap = GpiCreateBitmap(mPS, &hdr, 0, 0, 0);
if (mBitmap != GPI_ERROR) {
// set final stats & select bitmap into ps
GpiSetBitmap(mPS, mBitmap);
}
} /* if mPS */
} /* if mDC */
newSurface = new gfxOS2Surface(mPS, aSize);
} else if (aImageFormat == gfxASurface::ImageFormatA8 ||
aImageFormat == gfxASurface::ImageFormatA1) {
newSurface = new gfxImageSurface(aSize, aImageFormat);
} else {
return nsnull;
}
NS_IF_ADDREF(newSurface);
return newSurface;
}
nsresult
gfxOS2Platform::GetFontList(const nsACString& aLangGroup,
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts)
{
#ifdef DEBUG_thebes
char *langgroup = ToNewCString(aLangGroup),
*family = ToNewCString(aGenericFamily);
printf("gfxOS2Platform::GetFontList(%s, %s, ..)\n",
langgroup, family);
#endif
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
gfxOS2Platform::ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted)
{
#ifdef DEBUG_thebes
char *fontname = ToNewCString(aFontName);
printf("gfxOS2Platform::ResolveFontName(%s, ...)\n", fontname);
#endif
aAborted = !(*aCallback)(aFontName, aClosure);
return NS_OK;
}

View File

@ -0,0 +1,100 @@
/* vim: set sw=4 sts=4 et cin: */
/* ***** 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 OS/2 code in Thebes.
*
* The Initial Developer of the Original Code is
* Peter Weilbacher <mozilla@Weilbacher.org>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 "gfxOS2Surface.h"
#include <stdio.h>
/**********************************************************************
* class gfxOS2Surface
**********************************************************************/
gfxOS2Surface::gfxOS2Surface(HPS aPS, const gfxIntSize& aSize)
: mOwnsPS(PR_FALSE), mPS(aPS), mSize(aSize)
{
#ifdef DEBUG_thebes
printf("gfxOS2Surface::gfxOS2Surface(HPS, ...)\n");
#endif
cairo_surface_t *surf = cairo_os2_surface_create(mPS, mSize.width, mSize.height);
#ifdef DEBUG_thebes
printf(" type(%#x)=%d (own=%d, h/w=%d/%d)\n", surf, cairo_surface_get_type(surf),
mOwnsPS, mSize.width, mSize.height);
#endif
cairo_surface_mark_dirty(surf);
Init(surf);
}
gfxOS2Surface::gfxOS2Surface(HWND aWnd)
{
#ifdef DEBUG_thebes
printf("gfxOS2Surface::gfxOS2Surface(HWND)\n");
#endif
if (!mPS) {
// it must have been passed to us from somwhere else
mOwnsPS = PR_TRUE;
mPS = WinGetPS(aWnd);
} else {
mOwnsPS = PR_FALSE;
}
RECTL rectl;
WinQueryWindowRect(aWnd, &rectl);
mSize.width = rectl.xRight - rectl.xLeft;
mSize.height = rectl.yTop - rectl.yBottom;
if (mSize.width == 0) mSize.width = 10; // XXX fake some surface area to make
if (mSize.height == 0) mSize.height = 10; // cairo_os2_surface_create() return something sensible
cairo_surface_t *surf = cairo_os2_surface_create(mPS, mSize.width, mSize.height);
#ifdef DEBUG_thebes
printf(" type(%#x)=%d (own=%d, h/w=%d/%d)\n", surf,
cairo_surface_get_type(surf), mOwnsPS, mSize.width, mSize.height);
#endif
cairo_os2_surface_set_hwnd(surf, aWnd); // XXX is this needed here??
cairo_surface_mark_dirty(surf);
Init(surf);
}
gfxOS2Surface::~gfxOS2Surface()
{
#ifdef DEBUG_thebes
printf("gfxOS2Surface::~gfxOS2Surface()\n");
#endif
if (mOwnsPS)
WinReleasePS(mPS);
}