зеркало из https://github.com/mozilla/pjs.git
[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:
Родитель
e0569da19a
Коммит
19e9208204
|
@ -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;
|
||||||
|
}
|
|
@ -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_ */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче