зеркало из https://github.com/mozilla/pjs.git
[dfb,422221] Gtk/DirectFB port core; patches from dfb tree, r=vlad
This commit is contained in:
Родитель
e20e7b3c4d
Коммит
888c67ad87
96
configure.in
96
configure.in
|
@ -965,7 +965,7 @@ MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/modules/libimg/png)'
|
|||
|
||||
MOZ_JS_LIBS='-L$(LIBXUL_DIST)/bin -lmozjs'
|
||||
DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/bin -lxpcom -lxpcom_core'
|
||||
MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin'
|
||||
MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin -Wl,-rpath-link,$(PREFIX)/lib'
|
||||
XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/bin -lxpcom'
|
||||
LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) -lxul'
|
||||
XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
|
||||
|
@ -4708,6 +4708,7 @@ MOZ_ARG_HEADER(Toolkit Options)
|
|||
OS/2 - cairo-os2
|
||||
Win32 - cairo-windows
|
||||
WinCE - windows
|
||||
Gtk2 with DirectFB - cairo-gtk2-dfb
|
||||
* - cairo-gtk2],
|
||||
[ _DEFAULT_TOOLKIT=$enableval ],
|
||||
[ _DEFAULT_TOOLKIT=$_PLATFORM_DEFAULT_TOOLKIT])
|
||||
|
@ -4715,6 +4716,8 @@ MOZ_ARG_HEADER(Toolkit Options)
|
|||
if test "$_DEFAULT_TOOLKIT" = "photon" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-windows" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-gtk2" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-gtk2-dfb" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-gtk2-x11" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-beos" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-os2" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-mac" \
|
||||
|
@ -4724,11 +4727,7 @@ MOZ_ARG_HEADER(Toolkit Options)
|
|||
dnl so ignore everything after the first comma (",").
|
||||
MOZ_WIDGET_TOOLKIT=`echo "$_DEFAULT_TOOLKIT" | sed -e "s/,.*$//"`
|
||||
else
|
||||
if test "$no_x" != "yes"; then
|
||||
AC_MSG_ERROR([Toolkit must be cairo-gtk2.])
|
||||
else
|
||||
AC_MSG_ERROR([Toolkit must be $_PLATFORM_DEFAULT_TOOLKIT (if supported).])
|
||||
fi
|
||||
AC_MSG_ERROR([You must specify a default toolkit (perhaps $_PLATFORM_DEFAULT_TOOLKIT).])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(MOZ_DEFAULT_TOOLKIT,"$MOZ_WIDGET_TOOLKIT")
|
||||
|
@ -4748,15 +4747,37 @@ cairo-windows)
|
|||
MOZ_GFX_TOOLKIT=cairo
|
||||
;;
|
||||
|
||||
cairo-gtk2)
|
||||
cairo-gtk2|cairo-gtk2-x11)
|
||||
MOZ_WIDGET_TOOLKIT=gtk2
|
||||
MOZ_GFX_TOOLKIT=cairo
|
||||
MOZ_ENABLE_GTK2=1
|
||||
MOZ_ENABLE_XREMOTE=1
|
||||
|
||||
AC_DEFINE(MOZ_X11)
|
||||
MOZ_X11=1
|
||||
|
||||
TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
|
||||
TK_LIBS='$(MOZ_GTK2_LIBS)'
|
||||
AC_DEFINE(MOZ_WIDGET_GTK2)
|
||||
;;
|
||||
|
||||
cairo-gtk2-dfb)
|
||||
MOZ_WIDGET_TOOLKIT=gtk2
|
||||
MOZ_GFX_TOOLKIT=cairo
|
||||
MOZ_ENABLE_GTK2=1
|
||||
|
||||
AC_DEFINE(MOZ_DFB)
|
||||
MOZ_DFB=1
|
||||
|
||||
TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
|
||||
TK_LIBS='$(MOZ_GTK2_LIBS)'
|
||||
AC_DEFINE(MOZ_WIDGET_GTK2)
|
||||
if test "$no_x" != "yes"; then
|
||||
AC_MSG_WARN([Disabling X when DirectFB is specified.])
|
||||
no_x=yes
|
||||
fi
|
||||
;;
|
||||
|
||||
cairo-beos)
|
||||
MOZ_WIDGET_TOOLKIT=beos
|
||||
MOZ_GFX_TOOLKIT=cairo
|
||||
|
@ -4796,10 +4817,17 @@ if test "$MOZ_ENABLE_XREMOTE"; then
|
|||
fi
|
||||
|
||||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
if test "$MOZ_ENABLE_GTK2"
|
||||
then
|
||||
PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 gdk-x11-2.0 glib-2.0 gobject-2.0)
|
||||
fi
|
||||
if test "$MOZ_ENABLE_GTK2"; then
|
||||
if test "$MOZ_X11"; then
|
||||
GDK_PACKAGES=gdk-x11-2.0
|
||||
elif test "$MOZ_DFB"; then
|
||||
PKG_CHECK_MODULES(MOZ_DFB, directfb >= 1.1.0)
|
||||
GDK_PACKAGES=directfb
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 glib-2.0 gobject-2.0 $GDK_PACKAGES)
|
||||
fi
|
||||
|
||||
fi # COMPILE_ENVIRONMENT
|
||||
|
||||
AC_SUBST(MOZ_DEFAULT_TOOLKIT)
|
||||
|
@ -4853,11 +4881,7 @@ AC_SUBST(MOZ_GTK2_LIBS)
|
|||
|
||||
AC_SUBST(MOC)
|
||||
|
||||
if test "$MOZ_ENABLE_GTK2"
|
||||
then
|
||||
AC_DEFINE(MOZ_X11)
|
||||
MOZ_X11=1
|
||||
fi
|
||||
AC_SUBST(MOZ_DFB)
|
||||
AC_SUBST(MOZ_X11)
|
||||
|
||||
dnl ========================================================
|
||||
|
@ -4972,19 +4996,47 @@ fi
|
|||
AC_DEFINE_UNQUOTED(MOZ_DISTRIBUTION_ID,"$MOZ_DISTRIBUTION_ID")
|
||||
AC_SUBST(MOZ_DISTRIBUTION_ID)
|
||||
|
||||
|
||||
dnl ========================================================
|
||||
dnl complex text support off by default
|
||||
dnl ========================================================
|
||||
MOZ_PANGO=1
|
||||
MOZ_ARG_DISABLE_BOOL(pango,
|
||||
[ --disable-pango Disable usage of Pango ],
|
||||
MOZ_PANGO=,
|
||||
MOZ_PANGO=1)
|
||||
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Xft and Pango
|
||||
dnl ========================================================
|
||||
if test "$MOZ_ENABLE_GTK2"
|
||||
then
|
||||
PKG_CHECK_MODULES(MOZ_XFT, xft)
|
||||
AC_SUBST(MOZ_XFT_CFLAGS)
|
||||
AC_SUBST(MOZ_XFT_LIBS)
|
||||
if test "$MOZ_X11"; then
|
||||
PKG_CHECK_MODULES(MOZ_XFT, xft)
|
||||
AC_SUBST(MOZ_XFT_CFLAGS)
|
||||
AC_SUBST(MOZ_XFT_LIBS)
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_PANGO)
|
||||
|
||||
PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
|
||||
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangocairo >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
|
||||
AC_SUBST(MOZ_PANGO_CFLAGS)
|
||||
AC_SUBST(MOZ_PANGO_LIBS)
|
||||
|
||||
if test "$MOZ_PANGO"
|
||||
then
|
||||
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangocairo >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
|
||||
AC_SUBST(MOZ_PANGO_CFLAGS)
|
||||
AC_SUBST(MOZ_PANGO_LIBS)
|
||||
AC_DEFINE(MOZ_PANGO)
|
||||
else
|
||||
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
|
||||
AC_SUBST(MOZ_PANGO_CFLAGS)
|
||||
AC_SUBST(MOZ_PANGO_LIBS)
|
||||
|
||||
PKG_CHECK_MODULES(FT2, freetype2 > 6.1.0 fontconfig)
|
||||
AC_SUBST(FT2_CFLAGS)
|
||||
AC_SUBST(FT2_LIBS)
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
|
|
|
@ -45,18 +45,18 @@
|
|||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#ifdef MOZ_PANGO
|
||||
#include <pango/pango.h>
|
||||
#include <pango/pangox.h>
|
||||
#include <pango/pango-fontmap.h>
|
||||
#endif
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include "nsSystemFontsGTK2.h"
|
||||
#include "gfxPlatformGtk.h"
|
||||
|
||||
// Glue to avoid build/runtime dependencies on Pango > 1.6
|
||||
#ifndef THEBES_USE_PANGO_CAIRO
|
||||
#if defined(MOZ_PANGO) && !defined(THEBES_USE_PANGO_CAIRO)
|
||||
static gboolean
|
||||
(* PTR_pango_font_description_get_size_is_absolute)(PangoFontDescription*)
|
||||
= nsnull;
|
||||
|
@ -101,12 +101,14 @@ static inline void ShutdownPangoLib()
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef MOZ_PANGO
|
||||
static inline gboolean
|
||||
MOZ_pango_font_description_get_size_is_absolute(PangoFontDescription *desc)
|
||||
{
|
||||
pango_font_description_get_size_is_absolute(desc);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
nsSystemFontsGTK2::nsSystemFontsGTK2()
|
||||
: mDefaultFontName(NS_LITERAL_STRING("sans-serif"))
|
||||
|
@ -190,6 +192,7 @@ nsresult
|
|||
nsSystemFontsGTK2::GetSystemFontInfo(GtkWidget *aWidget, nsString *aFontName,
|
||||
gfxFontStyle *aFontStyle) const
|
||||
{
|
||||
#ifdef MOZ_PANGO
|
||||
GtkSettings *settings = gtk_widget_get_settings(aWidget);
|
||||
|
||||
aFontStyle->style = FONT_STYLE_NORMAL;
|
||||
|
@ -225,6 +228,18 @@ nsSystemFontsGTK2::GetSystemFontInfo(GtkWidget *aWidget, nsString *aFontName,
|
|||
|
||||
pango_font_description_free(desc);
|
||||
|
||||
#else
|
||||
/* FIXME: DFB FT2 Hardcoding the system font info for now.. */
|
||||
aFontStyle->style = FONT_STYLE_NORMAL;
|
||||
aFontStyle->systemFont = PR_TRUE;
|
||||
|
||||
NS_NAMED_LITERAL_STRING(fontname, "\"Sans\"");
|
||||
*aFontName = fontname;
|
||||
aFontStyle->weight = 400;
|
||||
aFontStyle->size = 40/3;
|
||||
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,11 +55,14 @@
|
|||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "nsFont.h"
|
||||
|
||||
#include <pango/pango.h>
|
||||
#ifdef MOZ_X11
|
||||
#include <gdk/gdkx.h>
|
||||
#include <pango/pangox.h>
|
||||
#endif /* MOZ_X11 */
|
||||
#include <pango/pango-fontmap.h>
|
||||
#endif /* GTK2 */
|
||||
|
||||
|
@ -92,7 +95,7 @@ static nsSystemFontsMac *gSystemFonts = nsnull;
|
|||
#error Need to declare gSystemFonts!
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
#if defined(MOZ_ENABLE_GTK2) && defined(MOZ_X11)
|
||||
extern "C" {
|
||||
static int x11_error_handler (Display *dpy, XErrorEvent *err) {
|
||||
NS_ASSERTION(PR_FALSE, "X Error");
|
||||
|
@ -271,7 +274,7 @@ nsThebesDeviceContext::Init(nsNativeWidget aWidget)
|
|||
SetDPI();
|
||||
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
#if defined(MOZ_ENABLE_GTK2) && defined(MOZ_X11)
|
||||
if (getenv ("MOZ_X_SYNC")) {
|
||||
PR_LOG (gThebesGFXLog, PR_LOG_DEBUG, ("+++ Enabling XSynchronize\n"));
|
||||
XSynchronize (gdk_x11_get_default_xdisplay(), True);
|
||||
|
|
|
@ -974,7 +974,7 @@ nsThebesRenderingContext::GetTextDimensionsInternal(const PRUnichar* aString,
|
|||
return GetWidth(aString, aLength, aDimensions.width, aFontID);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) || defined(XP_MACOSX)
|
||||
#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) || defined(XP_MACOSX) || defined (MOZ_DFB)
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::GetTextDimensionsInternal(const char* aString,
|
||||
PRInt32 aLength,
|
||||
|
|
|
@ -53,8 +53,22 @@ endif
|
|||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
EXPORTS += gfxXlibSurface.h gfxPlatformGtk.h gfxXlibNativeRenderer.h
|
||||
EXPORTS += gfxPangoFonts.h
|
||||
|
||||
ifdef MOZ_X11
|
||||
EXPORTS += gfxXlibSurface.h
|
||||
endif
|
||||
|
||||
ifdef MOZ_PANGO
|
||||
EXPORTS += gfxPangoFonts.h
|
||||
else
|
||||
EXPORTS += gfxFT2Fonts.h
|
||||
endif
|
||||
|
||||
ifdef MOZ_DFB
|
||||
EXPORTS += gfxDirectFBSurface.h
|
||||
endif
|
||||
|
||||
EXPORTS += gfxPlatformGtk.h gfxGdkNativeRenderer.h
|
||||
EXPORTS += gfxPDFSurface.h gfxPSSurface.h
|
||||
|
||||
ifdef MOZ_ENABLE_GLITZ
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** 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 DirectFB Thebes code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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_DIRECTFBSURFACE_H
|
||||
#define GFX_DIRECTFBSURFACE_H
|
||||
|
||||
#include "gfxASurface.h"
|
||||
|
||||
extern "C" {
|
||||
#include "direct/messages.h"
|
||||
|
||||
typedef struct _IDirectFB IDirectFB;
|
||||
typedef struct _IDirectFBSurface IDirectFBSurface;
|
||||
|
||||
}
|
||||
|
||||
class THEBES_API gfxDirectFBSurface : public gfxASurface {
|
||||
public:
|
||||
gfxDirectFBSurface(IDirectFB *dfb, IDirectFBSurface *surface);
|
||||
gfxDirectFBSurface(IDirectFBSurface *surface);
|
||||
gfxDirectFBSurface(cairo_surface_t *csurf);
|
||||
|
||||
gfxDirectFBSurface(const gfxIntSize& size, gfxImageFormat format);
|
||||
|
||||
virtual ~gfxDirectFBSurface();
|
||||
|
||||
IDirectFB* DirectFB() { return mDFB; }
|
||||
IDirectFBSurface* DirectFBSurface() { return mDFBSurface; }
|
||||
|
||||
protected:
|
||||
IDirectFB *mDFB;
|
||||
IDirectFBSurface *mDFBSurface;
|
||||
};
|
||||
|
||||
#endif /* GFX_DIRECTFBSURFACE_H */
|
|
@ -0,0 +1,185 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Foundation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
* Masayuki Nakano <masayuki@d-toybox.com>
|
||||
*
|
||||
* 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_GTKDFBFONTS_H
|
||||
#define GFX_GTKDFBFONTS_H
|
||||
|
||||
#include "cairo.h"
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxFont.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxFontUtils.h"
|
||||
|
||||
typedef struct FT_FaceRec_* FT_Face;
|
||||
|
||||
/**
|
||||
* FontFamily is a class that describes one of the fonts on the users system. It holds
|
||||
* each FontEntry (maps more directly to a font face) which holds font type, charset info
|
||||
* and character map info.
|
||||
*/
|
||||
class FontEntry;
|
||||
class FontFamily
|
||||
{
|
||||
public:
|
||||
THEBES_INLINE_DECL_REFCOUNTING(FontFamily)
|
||||
|
||||
FontFamily(const nsAString& aName) :
|
||||
mName(aName) { }
|
||||
|
||||
FontEntry *FindFontEntry(const gfxFontStyle& aFontStyle);
|
||||
|
||||
public:
|
||||
nsTArray<nsRefPtr<FontEntry> > mFaces;
|
||||
nsString mName;
|
||||
};
|
||||
|
||||
class FontEntry
|
||||
{
|
||||
public:
|
||||
THEBES_INLINE_DECL_REFCOUNTING(FontEntry)
|
||||
|
||||
FontEntry(const nsString& aFaceName) :
|
||||
mFontFace(nsnull), mFaceName(aFaceName), mFTFontIndex(0), mUnicodeFont(PR_FALSE), mSymbolFont(PR_FALSE)
|
||||
{ }
|
||||
|
||||
FontEntry(const FontEntry& aFontEntry);
|
||||
~FontEntry();
|
||||
|
||||
const nsString& GetName() const {
|
||||
return mFaceName;
|
||||
}
|
||||
|
||||
cairo_font_face_t *CairoFontFace();
|
||||
|
||||
cairo_font_face_t *mFontFace;
|
||||
|
||||
nsString mFaceName;
|
||||
nsCString mFilename;
|
||||
PRUint8 mFTFontIndex;
|
||||
|
||||
PRPackedBool mUnicodeFont : 1;
|
||||
PRPackedBool mSymbolFont : 1;
|
||||
PRPackedBool mTrueType : 1;
|
||||
PRPackedBool mIsType1 : 1;
|
||||
PRPackedBool mItalic : 1;
|
||||
PRUint16 mWeight;
|
||||
|
||||
gfxSparseBitSet mCharacterMap;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class gfxFT2Font : public gfxFont {
|
||||
public: // new functions
|
||||
gfxFT2Font(FontEntry *aFontEntry,
|
||||
const gfxFontStyle *aFontStyle);
|
||||
virtual ~gfxFT2Font ();
|
||||
|
||||
virtual const gfxFont::Metrics& GetMetrics();
|
||||
|
||||
cairo_font_face_t *CairoFontFace();
|
||||
cairo_scaled_font_t *CairoScaledFont();
|
||||
|
||||
virtual PRBool SetupCairoFont(gfxContext *aContext);
|
||||
virtual nsString GetUniqueName();
|
||||
virtual PRUint32 GetSpaceGlyph();
|
||||
|
||||
FontEntry *GetFontEntry() { return mFontEntry; }
|
||||
private:
|
||||
cairo_scaled_font_t *mScaledFont;
|
||||
|
||||
PRBool mHasSpaceGlyph;
|
||||
PRUint32 mSpaceGlyph;
|
||||
PRBool mHasMetrics;
|
||||
Metrics mMetrics;
|
||||
gfxFloat mAdjustedSize;
|
||||
|
||||
nsRefPtr<FontEntry> mFontEntry;
|
||||
};
|
||||
|
||||
class THEBES_API gfxFT2FontGroup : public gfxFontGroup {
|
||||
public: // new functions
|
||||
gfxFT2FontGroup (const nsAString& families,
|
||||
const gfxFontStyle *aStyle);
|
||||
virtual ~gfxFT2FontGroup ();
|
||||
|
||||
inline gfxFT2Font *GetFontAt (PRInt32 i) {
|
||||
return static_cast <gfxFT2Font *>(static_cast <gfxFont *>(mFonts[i]));
|
||||
}
|
||||
|
||||
protected: // from gfxFontGroup
|
||||
virtual gfxTextRun *MakeTextRun(const PRUnichar *aString,
|
||||
PRUint32 aLength,
|
||||
const Parameters *aParams,
|
||||
PRUint32 aFlags);
|
||||
|
||||
virtual gfxTextRun *MakeTextRun(const PRUint8 *aString,
|
||||
PRUint32 aLength,
|
||||
const Parameters *aParams,
|
||||
PRUint32 aFlags);
|
||||
|
||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||
|
||||
|
||||
protected: // new functions
|
||||
void InitTextRun(gfxTextRun *aTextRun);
|
||||
|
||||
void CreateGlyphRunsFT(gfxTextRun *aTextRun);
|
||||
void AddRange(gfxTextRun *aTextRun, gfxFT2Font *font, const PRUnichar *str, PRUint32 len);
|
||||
|
||||
static PRBool FontCallback (const nsAString & fontName,
|
||||
const nsACString & genericName,
|
||||
void *closure);
|
||||
PRBool mEnableKerning;
|
||||
|
||||
gfxFT2Font *FindFontForChar(PRUint32 ch, PRUint32 prevCh, PRUint32 nextCh, gfxFT2Font *aFont);
|
||||
PRUint32 ComputeRanges();
|
||||
|
||||
struct TextRange {
|
||||
TextRange(PRUint32 aStart, PRUint32 aEnd) : start(aStart), end(aEnd) { }
|
||||
PRUint32 Length() const { return end - start; }
|
||||
nsRefPtr<gfxFT2Font> font;
|
||||
PRUint32 start, end;
|
||||
};
|
||||
|
||||
nsTArray<TextRange> mRanges;
|
||||
nsString mString;
|
||||
};
|
||||
|
||||
#endif /* GFX_GTKDFBFONTS_H */
|
||||
|
|
@ -39,11 +39,20 @@
|
|||
#ifndef GFX_PLATFORM_GTK_H
|
||||
#define GFX_PLATFORM_GTK_H
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
extern "C" {
|
||||
typedef struct _GdkDrawable GdkDrawable;
|
||||
}
|
||||
|
||||
class gfxFontconfigUtils;
|
||||
#ifndef MOZ_PANGO
|
||||
class FontFamily;
|
||||
class FontEntry;
|
||||
typedef struct FT_LibraryRec_ *FT_Library;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class THEBES_API gfxPlatformGtk : public gfxPlatform {
|
||||
public:
|
||||
|
@ -72,6 +81,11 @@ public:
|
|||
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
|
||||
const gfxFontStyle *aStyle);
|
||||
|
||||
#ifndef MOZ_PANGO
|
||||
FontFamily *FindFontFamily(const nsAString& aName);
|
||||
FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
|
||||
#endif
|
||||
|
||||
static PRInt32 DPI() {
|
||||
if (sDPI == -1) {
|
||||
InitDPI();
|
||||
|
@ -80,6 +94,14 @@ public:
|
|||
return sDPI;
|
||||
}
|
||||
|
||||
#ifndef MOZ_PANGO
|
||||
FT_Library GetFTLibrary();
|
||||
#endif
|
||||
|
||||
void SetGdkDrawable(gfxASurface *target,
|
||||
GdkDrawable *drawable);
|
||||
GdkDrawable *GetGdkDrawable(gfxASurface *target);
|
||||
|
||||
protected:
|
||||
static void InitDPI();
|
||||
|
||||
|
|
|
@ -80,15 +80,37 @@ REQUIRES += uconv
|
|||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
CPPSRCS += gfxXlibSurface.cpp gfxPlatformGtk.cpp gfxXlibNativeRenderer.cpp
|
||||
CPPSRCS += gfxPangoFonts.cpp
|
||||
|
||||
ifdef MOZ_PANGO
|
||||
CPPSRCS += gfxPangoFonts.cpp
|
||||
else
|
||||
CPPSRCS += gfxFT2Fonts.cpp
|
||||
endif
|
||||
|
||||
ifdef MOZ_X11
|
||||
CPPSRCS += gfxXlibSurface.cpp
|
||||
endif
|
||||
|
||||
CPPSRCS += gfxPlatformGtk.cpp gfxGdkNativeRenderer.cpp
|
||||
CPPSRCS += gfxPDFSurface.cpp gfxPSSurface.cpp
|
||||
CPPSRCS += gfxFontconfigUtils.cpp
|
||||
CPPSRCS += nsUnicodeRange.cpp
|
||||
|
||||
ifdef MOZ_X11
|
||||
CSRCS = cairo-xlib-utils.c
|
||||
endif
|
||||
|
||||
ifdef MOZ_DFB
|
||||
CSRCS = cairo-gdk-utils.c
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_PANGO_LIBS) $(ZLIB_LIBS) $(MOZ_XFT_LIBS) $(XLDFLAGS) $(XLIBS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_DFB
|
||||
CPPSRCS += gfxDirectFBSurface.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
|
||||
CPPSRCS += gfxBeOSSurface.cpp gfxBeOSPlatform.cpp
|
||||
CPPSRCS += gfxPangoFonts.cpp
|
||||
|
|
|
@ -55,6 +55,10 @@
|
|||
#include "gfxQuartzImageSurface.h"
|
||||
#endif
|
||||
|
||||
#ifdef CAIRO_HAS_DIRECTFB_SURFACE
|
||||
#include "gfxDirectFBSurface.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
@ -162,6 +166,11 @@ gfxASurface::Wrap (cairo_surface_t *csurf)
|
|||
else if (stype == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) {
|
||||
result = new gfxQuartzImageSurface(csurf);
|
||||
}
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_DIRECTFB_SURFACE
|
||||
else if (stype == CAIRO_SURFACE_TYPE_DIRECTFB) {
|
||||
result = new gfxDirectFBSurface(csurf);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
result = new gfxUnknownSurface(csurf);
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 "gfxDirectFBSurface.h"
|
||||
|
||||
#include "cairo-directfb.h"
|
||||
|
||||
gfxDirectFBSurface::gfxDirectFBSurface(IDirectFB *dfb, IDirectFBSurface *dfbs)
|
||||
: mDFB(nsnull), mDFBSurface(nsnull)
|
||||
{
|
||||
dfb->AddRef( dfb );
|
||||
dfbs->AddRef( dfbs );
|
||||
|
||||
cairo_surface_t *surf = cairo_directfb_surface_create(dfb, dfbs);
|
||||
|
||||
mDFB = dfb;
|
||||
mDFBSurface = dfbs;
|
||||
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
gfxDirectFBSurface::gfxDirectFBSurface(IDirectFBSurface *dfbs)
|
||||
: mDFB(nsnull), mDFBSurface(nsnull)
|
||||
{
|
||||
DFBResult ret;
|
||||
|
||||
dfbs->AddRef( dfbs );
|
||||
|
||||
/* Lightweight, getting singleton */
|
||||
ret = DirectFBCreate( &mDFB );
|
||||
if (ret) {
|
||||
D_DERROR( (DirectResult) ret, "gfxDirectFBSurface: DirectFBCreate() failed!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_surface_t *surf = cairo_directfb_surface_create(mDFB, dfbs);
|
||||
|
||||
mDFBSurface = dfbs;
|
||||
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
gfxDirectFBSurface::gfxDirectFBSurface(cairo_surface_t *csurf)
|
||||
{
|
||||
mDFB = nsnull;
|
||||
mDFBSurface = nsnull;
|
||||
|
||||
Init(csurf, PR_TRUE);
|
||||
}
|
||||
|
||||
gfxDirectFBSurface::gfxDirectFBSurface(const gfxIntSize& size, gfxImageFormat format) :
|
||||
mDFB(nsnull), mDFBSurface(nsnull)
|
||||
{
|
||||
DFBResult ret;
|
||||
DFBSurfaceDescription desc;
|
||||
|
||||
if (!CheckSurfaceSize(size) || size.width <= 0 || size.height <= 0)
|
||||
return;
|
||||
|
||||
/* Lightweight, getting singleton */
|
||||
ret = DirectFBCreate( &mDFB );
|
||||
if (ret) {
|
||||
D_DERROR( (DirectResult) ret, "gfxDirectFBSurface: DirectFBCreate() failed!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
desc.flags = (DFBSurfaceDescriptionFlags)( DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT );
|
||||
desc.width = size.width;
|
||||
desc.height = size.height;
|
||||
|
||||
switch (format) {
|
||||
case gfxASurface::ImageFormatARGB32:
|
||||
desc.pixelformat = DSPF_ARGB;
|
||||
break;
|
||||
|
||||
case gfxASurface::ImageFormatRGB24:
|
||||
desc.pixelformat = DSPF_RGB32;
|
||||
break;
|
||||
|
||||
case gfxASurface::ImageFormatA8:
|
||||
desc.pixelformat = DSPF_A8;
|
||||
break;
|
||||
|
||||
case gfxASurface::ImageFormatA1:
|
||||
desc.pixelformat = DSPF_A1;
|
||||
break;
|
||||
|
||||
default:
|
||||
D_BUG( "unknown format" );
|
||||
return;
|
||||
}
|
||||
|
||||
ret = mDFB->CreateSurface( mDFB, &desc, &mDFBSurface );
|
||||
if (ret) {
|
||||
D_DERROR( (DirectResult) ret, "gfxDirectFBSurface: "
|
||||
"IDirectFB::CreateSurface( %dx%d ) failed!\n", desc.width, desc.height );
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_surface_t *surface = cairo_directfb_surface_create(mDFB, mDFBSurface);
|
||||
|
||||
Init(surface);
|
||||
}
|
||||
|
||||
gfxDirectFBSurface::~gfxDirectFBSurface()
|
||||
{
|
||||
if (mDFBSurface)
|
||||
mDFBSurface->Release( mDFBSurface );
|
||||
|
||||
if (mDFB)
|
||||
mDFB->Release( mDFB );
|
||||
}
|
||||
|
|
@ -0,0 +1,862 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Foundation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* 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 "gfxPlatformGtk.h"
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxFT2Fonts.h"
|
||||
#include <locale.h>
|
||||
#include "cairo-ft.h"
|
||||
#include <freetype/tttables.h>
|
||||
#include "gfxFontUtils.h"
|
||||
|
||||
/**
|
||||
* FontEntry
|
||||
*/
|
||||
|
||||
FontEntry::FontEntry(const FontEntry& aFontEntry) :
|
||||
mFaceName(aFontEntry.mFaceName),
|
||||
mUnicodeFont(aFontEntry.mUnicodeFont),
|
||||
mSymbolFont(aFontEntry.mSymbolFont),
|
||||
mItalic(aFontEntry.mItalic),
|
||||
mWeight(aFontEntry.mWeight),
|
||||
mCharacterMap(aFontEntry.mCharacterMap)
|
||||
{
|
||||
if (aFontEntry.mFontFace)
|
||||
mFontFace = cairo_font_face_reference(aFontEntry.mFontFace);
|
||||
else
|
||||
mFontFace = nsnull;
|
||||
}
|
||||
|
||||
FontEntry::~FontEntry()
|
||||
{
|
||||
if (mFontFace) {
|
||||
cairo_font_face_destroy(mFontFace);
|
||||
mFontFace = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FTFontDestroyFunc(void *data)
|
||||
{
|
||||
FT_Face face = (FT_Face)data;
|
||||
FT_Done_Face(face);
|
||||
}
|
||||
|
||||
cairo_font_face_t *
|
||||
FontEntry::CairoFontFace()
|
||||
{
|
||||
static cairo_user_data_key_t key;
|
||||
|
||||
if (!mFontFace) {
|
||||
FT_Face face;
|
||||
FT_New_Face(gfxPlatformGtk::GetPlatform()->GetFTLibrary(), mFilename.get(), mFTFontIndex, &face);
|
||||
mFontFace = cairo_ft_font_face_create_for_ft_face(face, 0);
|
||||
cairo_font_face_set_user_data(mFontFace, &key, face, FTFontDestroyFunc);
|
||||
}
|
||||
return mFontFace;
|
||||
}
|
||||
|
||||
FontEntry *
|
||||
FontFamily::FindFontEntry(const gfxFontStyle& aFontStyle)
|
||||
{
|
||||
PRBool italic = (aFontStyle.style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
|
||||
|
||||
FontEntry *weightList[10] = { 0 };
|
||||
for (PRUint32 j = 0; j < 2; j++) {
|
||||
PRBool matchesSomething = PR_FALSE;
|
||||
// build up an array of weights that match the italicness we're looking for
|
||||
for (PRUint32 i = 0; i < mFaces.Length(); i++) {
|
||||
FontEntry *fe = mFaces[i];
|
||||
const PRUint8 weight = (fe->mWeight / 100);
|
||||
if (fe->mItalic == italic) {
|
||||
weightList[weight] = fe;
|
||||
matchesSomething = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (matchesSomething)
|
||||
break;
|
||||
italic = !italic;
|
||||
}
|
||||
|
||||
PRInt8 baseWeight, weightDistance;
|
||||
aFontStyle.ComputeWeightAndOffset(&baseWeight, &weightDistance);
|
||||
|
||||
// 500 isn't quite bold so we want to treat it as 400 if we don't
|
||||
// have a 500 weight
|
||||
if (baseWeight == 5 && weightDistance == 0) {
|
||||
// If we have a 500 weight then use it
|
||||
if (weightList[5])
|
||||
return weightList[5];
|
||||
|
||||
// Otherwise treat as 400
|
||||
baseWeight = 4;
|
||||
}
|
||||
|
||||
PRInt8 matchBaseWeight = 0;
|
||||
PRInt8 direction = (baseWeight > 5) ? 1 : -1;
|
||||
for (PRInt8 i = baseWeight; ; i += direction) {
|
||||
if (weightList[i]) {
|
||||
matchBaseWeight = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// if we've reached one side without finding a font,
|
||||
// go the other direction until we find a match
|
||||
if (i == 1 || i == 9)
|
||||
direction = -direction;
|
||||
}
|
||||
|
||||
FontEntry *matchFE;
|
||||
const PRInt8 absDistance = abs(weightDistance);
|
||||
direction = (weightDistance >= 0) ? 1 : -1;
|
||||
for (PRInt8 i = matchBaseWeight, k = 0; i < 10 && i > 0; i += direction) {
|
||||
if (weightList[i]) {
|
||||
matchFE = weightList[i];
|
||||
k++;
|
||||
}
|
||||
if (k > absDistance)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!matchFE)
|
||||
matchFE = weightList[matchBaseWeight];
|
||||
|
||||
NS_ASSERTION(matchFE, "we should always be able to return something here");
|
||||
return matchFE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* gfxFT2FontGroup
|
||||
*/
|
||||
|
||||
PRBool
|
||||
gfxFT2FontGroup::FontCallback(const nsAString& fontName,
|
||||
const nsACString& genericName,
|
||||
void *closure)
|
||||
{
|
||||
nsStringArray *sa = static_cast<nsStringArray*>(closure);
|
||||
|
||||
if (!fontName.IsEmpty() && sa->IndexOf(fontName) < 0) {
|
||||
sa->AppendString(fontName);
|
||||
#ifdef DEBUG_pavlov
|
||||
printf(" - %s\n", NS_ConvertUTF16toUTF8(fontName).get());
|
||||
#endif
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the font in the gfxFont cache. If we don't find it, create one.
|
||||
* In either case, add a ref, append it to the aFonts array, and return it ---
|
||||
* except for OOM in which case we do nothing and return null.
|
||||
*/
|
||||
static already_AddRefed<gfxFT2Font>
|
||||
GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle)
|
||||
{
|
||||
nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aName, aStyle);
|
||||
if (!font) {
|
||||
FontEntry *fe = gfxPlatformGtk::GetPlatform()->FindFontEntry(aName, *aStyle);
|
||||
if (!fe) {
|
||||
printf("Failed to find font entry for %s\n", NS_ConvertUTF16toUTF8(aName).get());
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
font = new gfxFT2Font(fe, aStyle);
|
||||
if (!font)
|
||||
return nsnull;
|
||||
gfxFontCache::GetCache()->AddNew(font);
|
||||
}
|
||||
gfxFont *f = nsnull;
|
||||
font.swap(f);
|
||||
return static_cast<gfxFT2Font *>(f);
|
||||
}
|
||||
|
||||
|
||||
gfxFT2FontGroup::gfxFT2FontGroup(const nsAString& families,
|
||||
const gfxFontStyle *aStyle)
|
||||
: gfxFontGroup(families, aStyle)
|
||||
{
|
||||
#ifdef DEBUG_pavlov
|
||||
printf("Looking for %s\n", NS_ConvertUTF16toUTF8(families).get());
|
||||
#endif
|
||||
nsStringArray familyArray;
|
||||
ForEachFont(FontCallback, &familyArray);
|
||||
|
||||
if (familyArray.Count() == 0) {
|
||||
nsAutoString prefFamilies;
|
||||
gfxPlatformGtk::GetPlatform()->GetPrefFonts(aStyle->langGroup.get(), prefFamilies, nsnull);
|
||||
if (!prefFamilies.IsEmpty()) {
|
||||
ForEachFont(prefFamilies, aStyle->langGroup, FontCallback, &familyArray);
|
||||
}
|
||||
}
|
||||
#if 0 /* FIXME DFB */
|
||||
if (familyArray.Count() == 0) {
|
||||
printf("failde to find a font. sadface\n");
|
||||
// We want to get rid of this entirely at some point, but first we need real lists of fonts.
|
||||
QFont defaultFont;
|
||||
QFontInfo fi (defaultFont);
|
||||
familyArray.AppendString(nsDependentString(static_cast<const PRUnichar *>(fi.family().utf16())));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < familyArray.Count(); i++) {
|
||||
nsRefPtr<gfxFT2Font> font = GetOrMakeFont(*familyArray[i], &mStyle);
|
||||
if (font) {
|
||||
mFonts.AppendElement(font);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfxFT2FontGroup::~gfxFT2FontGroup()
|
||||
{
|
||||
}
|
||||
|
||||
gfxFontGroup *
|
||||
gfxFT2FontGroup::Copy(const gfxFontStyle *aStyle)
|
||||
{
|
||||
return new gfxFT2FontGroup(mFamilies, aStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* We use this to append an LTR or RTL Override character to the start of the
|
||||
* string. This forces Pango to honour our direction even if there are neutral
|
||||
* characters in the string.
|
||||
*/
|
||||
static PRInt32 AppendDirectionalIndicatorUTF8(PRBool aIsRTL, nsACString& aString)
|
||||
{
|
||||
static const PRUnichar overrides[2][2] = { { 0x202d, 0 }, { 0x202e, 0 }}; // LRO, RLO
|
||||
AppendUTF16toUTF8(overrides[aIsRTL], aString);
|
||||
return 3; // both overrides map to 3 bytes in UTF8
|
||||
}
|
||||
|
||||
gfxTextRun *gfxFT2FontGroup::MakeTextRun(const PRUnichar* aString, PRUint32 aLength,
|
||||
const Parameters* aParams, PRUint32 aFlags)
|
||||
{
|
||||
gfxTextRun *textRun = gfxTextRun::Create(aParams, aString, aLength, this, aFlags);
|
||||
if (!textRun)
|
||||
return nsnull;
|
||||
|
||||
textRun->RecordSurrogates(aString);
|
||||
|
||||
mString.Assign(nsDependentSubstring(aString, aString + aLength));
|
||||
|
||||
InitTextRun(textRun);
|
||||
|
||||
textRun->FetchGlyphExtents(aParams->mContext);
|
||||
|
||||
return textRun;
|
||||
}
|
||||
|
||||
gfxTextRun *gfxFT2FontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
|
||||
const Parameters *aParams, PRUint32 aFlags)
|
||||
{
|
||||
NS_ASSERTION(aFlags & TEXT_IS_8BIT, "8bit should have been set");
|
||||
gfxTextRun *textRun = gfxTextRun::Create(aParams, aString, aLength, this, aFlags);
|
||||
if (!textRun)
|
||||
return nsnull;
|
||||
|
||||
const char *chars = reinterpret_cast<const char *>(aString);
|
||||
|
||||
mString.Assign(NS_ConvertASCIItoUTF16(nsDependentCSubstring(chars, chars + aLength)));
|
||||
|
||||
InitTextRun(textRun);
|
||||
|
||||
textRun->FetchGlyphExtents(aParams->mContext);
|
||||
|
||||
return textRun;
|
||||
}
|
||||
|
||||
void gfxFT2FontGroup::InitTextRun(gfxTextRun *aTextRun)
|
||||
{
|
||||
CreateGlyphRunsFT(aTextRun);
|
||||
}
|
||||
|
||||
|
||||
// Helper function to return the leading UTF-8 character in a char pointer
|
||||
// as 32bit number. Also sets the length of the current character (i.e. the
|
||||
// offset to the next one) in the second argument
|
||||
PRUint32 getUTF8CharAndNext(const PRUint8 *aString, PRUint8 *aLength)
|
||||
{
|
||||
*aLength = 1;
|
||||
if (aString[0] < 0x80) { // normal 7bit ASCII char
|
||||
return aString[0];
|
||||
}
|
||||
if ((aString[0] >> 5) == 6) { // two leading ones -> two bytes
|
||||
*aLength = 2;
|
||||
return ((aString[0] & 0x1F) << 6) + (aString[1] & 0x3F);
|
||||
}
|
||||
if ((aString[0] >> 4) == 14) { // three leading ones -> three bytes
|
||||
*aLength = 3;
|
||||
return ((aString[0] & 0x0F) << 12) + ((aString[1] & 0x3F) << 6) +
|
||||
(aString[2] & 0x3F);
|
||||
}
|
||||
if ((aString[0] >> 4) == 15) { // four leading ones -> four bytes
|
||||
*aLength = 4;
|
||||
return ((aString[0] & 0x07) << 18) + ((aString[1] & 0x3F) << 12) +
|
||||
((aString[2] & 0x3F) << 6) + (aString[3] & 0x3F);
|
||||
}
|
||||
return aString[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
HasCharacter(gfxFT2Font *aFont, PRUint32 ch)
|
||||
{
|
||||
if (aFont->GetFontEntry()->mCharacterMap.test(ch))
|
||||
return PR_TRUE;
|
||||
|
||||
// XXX move this lock way way out
|
||||
FT_Face face = cairo_ft_scaled_font_lock_face(aFont->CairoScaledFont());
|
||||
FT_UInt gid = FT_Get_Char_Index(face, ch);
|
||||
cairo_ft_scaled_font_unlock_face(aFont->CairoScaledFont());
|
||||
|
||||
if (gid != 0) {
|
||||
aFont->GetFontEntry()->mCharacterMap.set(ch);
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
inline FontEntry *
|
||||
gfxFT2FontGroup::WhichFontSupportsChar(const nsTArray<>& foo, PRUint32 ch)
|
||||
{
|
||||
for (int i = 0; i < aGroup->FontListLength(); i++) {
|
||||
nsRefPtr<gfxFT2Font> font = aGroup->GetFontAt(i);
|
||||
if (HasCharacter(font, ch))
|
||||
return font;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline gfxFT2Font *
|
||||
gfxFT2FontGroup::FindFontForChar(PRUint32 ch, PRUint32 prevCh, PRUint32 nextCh, gfxFT2Font *aFont)
|
||||
{
|
||||
gfxFT2Font *selectedFont;
|
||||
|
||||
// if this character or the next one is a joiner use the
|
||||
// same font as the previous range if we can
|
||||
if (gfxFontUtils::IsJoiner(ch) || gfxFontUtils::IsJoiner(prevCh) || gfxFontUtils::IsJoiner(nextCh)) {
|
||||
if (aFont && HasCharacter(aFont, ch))
|
||||
return aFont;
|
||||
}
|
||||
|
||||
for (PRUint32 i = 0; i < FontListLength(); i++) {
|
||||
nsRefPtr<gfxFT2Font> font = GetFontAt(i);
|
||||
if (HasCharacter(font, ch))
|
||||
return font;
|
||||
}
|
||||
return nsnull;
|
||||
|
||||
#if 0
|
||||
// check the list of fonts
|
||||
selectedFont = WhichFontSupportsChar(mGroup->GetFontList(), ch);
|
||||
|
||||
|
||||
// don't look in other fonts if the character is in a Private Use Area
|
||||
if ((ch >= 0xE000 && ch <= 0xF8FF) ||
|
||||
(ch >= 0xF0000 && ch <= 0x10FFFD))
|
||||
return selectedFont;
|
||||
|
||||
// check out the style's language group
|
||||
if (!selectedFont) {
|
||||
nsAutoTArray<nsRefPtr<FontEntry>, 5> fonts;
|
||||
this->GetPrefFonts(mGroup->GetStyle()->langGroup.get(), fonts);
|
||||
selectedFont = WhichFontSupportsChar(fonts, ch);
|
||||
}
|
||||
|
||||
// otherwise search prefs
|
||||
if (!selectedFont) {
|
||||
/* first check with the script properties to see what they think */
|
||||
if (ch <= 0xFFFF) {
|
||||
PRUint32 unicodeRange = FindCharUnicodeRange(ch);
|
||||
|
||||
/* special case CJK */
|
||||
if (unicodeRange == kRangeSetCJK) {
|
||||
if (PR_LOG_TEST(gFontLog, PR_LOG_DEBUG))
|
||||
PR_LOG(gFontLog, PR_LOG_DEBUG, (" - Trying to find fonts for: CJK"));
|
||||
|
||||
nsAutoTArray<nsRefPtr<FontEntry>, 15> fonts;
|
||||
this->GetCJKPrefFonts(fonts);
|
||||
selectedFont = WhichFontSupportsChar(fonts, ch);
|
||||
} else {
|
||||
const char *langGroup = LangGroupFromUnicodeRange(unicodeRange);
|
||||
if (langGroup) {
|
||||
PR_LOG(gFontLog, PR_LOG_DEBUG, (" - Trying to find fonts for: %s", langGroup));
|
||||
|
||||
nsAutoTArray<nsRefPtr<FontEntry>, 5> fonts;
|
||||
this->GetPrefFonts(langGroup, fonts);
|
||||
selectedFont = WhichFontSupportsChar(fonts, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// before searching for something else check the font used for the previous character
|
||||
if (!selectedFont && aFont && HasCharacter(aFont, ch))
|
||||
selectedFont = aFont;
|
||||
|
||||
// otherwise look for other stuff
|
||||
if (!selectedFont) {
|
||||
PR_LOG(gFontLog, PR_LOG_DEBUG, (" - Looking for best match"));
|
||||
|
||||
nsRefPtr<gfxWindowsFont> refFont = mGroup->GetFontAt(0);
|
||||
gfxWindowsPlatform *platform = gfxWindowsPlatform::GetPlatform();
|
||||
selectedFont = platform->FindFontForChar(ch, refFont);
|
||||
}
|
||||
|
||||
return selectedFont;
|
||||
#endif
|
||||
}
|
||||
|
||||
PRUint32
|
||||
gfxFT2FontGroup::ComputeRanges()
|
||||
{
|
||||
const PRUnichar *str = mString.get();
|
||||
PRUint32 len = mString.Length();
|
||||
|
||||
mRanges.Clear();
|
||||
|
||||
PRUint32 prevCh = 0;
|
||||
for (PRUint32 i = 0; i < len; i++) {
|
||||
const PRUint32 origI = i; // save off incase we increase for surrogate
|
||||
PRUint32 ch = str[i];
|
||||
if ((i+1 < len) && NS_IS_HIGH_SURROGATE(ch) && NS_IS_LOW_SURROGATE(str[i+1])) {
|
||||
i++;
|
||||
ch = SURROGATE_TO_UCS4(ch, str[i]);
|
||||
}
|
||||
|
||||
PRUint32 nextCh = 0;
|
||||
if (i+1 < len) {
|
||||
nextCh = str[i+1];
|
||||
if ((i+2 < len) && NS_IS_HIGH_SURROGATE(ch) && NS_IS_LOW_SURROGATE(str[i+2]))
|
||||
nextCh = SURROGATE_TO_UCS4(nextCh, str[i+2]);
|
||||
}
|
||||
gfxFT2Font *fe = FindFontForChar(ch,
|
||||
prevCh,
|
||||
nextCh,
|
||||
(mRanges.Length() == 0) ? nsnull : mRanges[mRanges.Length() - 1].font);
|
||||
|
||||
prevCh = ch;
|
||||
|
||||
if (mRanges.Length() == 0) {
|
||||
TextRange r(0,1);
|
||||
r.font = fe;
|
||||
mRanges.AppendElement(r);
|
||||
} else {
|
||||
TextRange& prevRange = mRanges[mRanges.Length() - 1];
|
||||
if (prevRange.font != fe) {
|
||||
// close out the previous range
|
||||
prevRange.end = origI;
|
||||
|
||||
TextRange r(origI, i+1);
|
||||
r.font = fe;
|
||||
mRanges.AppendElement(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
mRanges[mRanges.Length()-1].end = len;
|
||||
|
||||
PRUint32 nranges = mRanges.Length();
|
||||
return nranges;
|
||||
}
|
||||
|
||||
void gfxFT2FontGroup::CreateGlyphRunsFT(gfxTextRun *aTextRun)
|
||||
{
|
||||
ComputeRanges();
|
||||
|
||||
const PRUnichar *strStart = mString.get();
|
||||
for (PRUint32 i = 0; i < mRanges.Length(); ++i) {
|
||||
const TextRange& range = mRanges[i];
|
||||
const PRUnichar *rangeString = strStart + range.start;
|
||||
PRUint32 rangeLength = range.Length();
|
||||
|
||||
gfxFT2Font *font = range.font ? range.font.get() : GetFontAt(0);
|
||||
AddRange(aTextRun, font, rangeString, rangeLength);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
gfxFT2FontGroup::AddRange(gfxTextRun *aTextRun, gfxFT2Font *font, const PRUnichar *str, PRUint32 len)
|
||||
{
|
||||
const PRUint32 appUnitsPerDevUnit = aTextRun->GetAppUnitsPerDevUnit();
|
||||
// we'll pass this in/figure it out dynamically, but at this point there can be only one face.
|
||||
FT_Face face = cairo_ft_scaled_font_lock_face(font->CairoScaledFont());
|
||||
|
||||
gfxTextRun::CompressedGlyph g;
|
||||
|
||||
aTextRun->AddGlyphRun(font, 0);
|
||||
for (PRUint32 i = 0; i < len; i++) {
|
||||
PRUint32 ch = str[i];
|
||||
|
||||
if (ch == 0) {
|
||||
// treat this null byte as a missing glyph, don't create a glyph for it
|
||||
aTextRun->SetMissingGlyph(i, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!IsInvalidChar(ch), "Invalid char detected");
|
||||
FT_UInt gid = FT_Get_Char_Index(face, ch); // find the glyph id
|
||||
PRInt32 advance = 0;
|
||||
|
||||
if (gid == font->GetSpaceGlyph()) {
|
||||
advance = (int)(font->GetMetrics().spaceWidth * appUnitsPerDevUnit);
|
||||
} else if (gid == 0) {
|
||||
advance = -1; // trigger the missing glyphs case below
|
||||
} else {
|
||||
// find next character and its glyph -- in case they exist
|
||||
// and exist in the current font face -- to compute kerning
|
||||
PRUint32 chNext = 0;
|
||||
FT_UInt gidNext = 0;
|
||||
FT_Pos lsbDeltaNext = 0;
|
||||
|
||||
if (FT_HAS_KERNING(face) && i + 1 < len) {
|
||||
chNext = str[i+1];
|
||||
if (chNext != 0) {
|
||||
gidNext = FT_Get_Char_Index(face, chNext);
|
||||
if (gidNext && gidNext != font->GetSpaceGlyph()) {
|
||||
FT_Load_Glyph(face, gidNext, FT_LOAD_DEFAULT);
|
||||
lsbDeltaNext = face->glyph->lsb_delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now load the current glyph
|
||||
FT_Load_Glyph(face, gid, FT_LOAD_DEFAULT); // load glyph into the slot
|
||||
advance = face->glyph->advance.x;
|
||||
|
||||
// now add kerning to the current glyph's advance
|
||||
if (chNext && gidNext) {
|
||||
FT_Vector kerning; kerning.x = 0;
|
||||
FT_Get_Kerning(face, gid, gidNext, FT_KERNING_DEFAULT, &kerning);
|
||||
advance += kerning.x;
|
||||
if (face->glyph->rsb_delta - lsbDeltaNext >= 32) {
|
||||
advance -= 64;
|
||||
} else if (face->glyph->rsb_delta - lsbDeltaNext < -32) {
|
||||
advance += 64;
|
||||
}
|
||||
}
|
||||
|
||||
// now apply unit conversion and scaling
|
||||
advance = (advance >> 6) * appUnitsPerDevUnit;
|
||||
}
|
||||
#ifdef DEBUG_thebes_2
|
||||
printf(" gid=%d, advance=%d (%s)\n", gid, advance,
|
||||
NS_LossyConvertUTF16toASCII(font->GetName()).get());
|
||||
#endif
|
||||
|
||||
if (advance >= 0 &&
|
||||
gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) &&
|
||||
gfxTextRun::CompressedGlyph::IsSimpleGlyphID(gid)) {
|
||||
aTextRun->SetSimpleGlyph(i, g.SetSimpleGlyph(advance, gid));
|
||||
} else if (gid == 0) {
|
||||
// gid = 0 only happens when the glyph is missing from the font
|
||||
aTextRun->SetMissingGlyph(i, ch);
|
||||
} else {
|
||||
gfxTextRun::DetailedGlyph details;
|
||||
details.mGlyphID = gid;
|
||||
NS_ASSERTION(details.mGlyphID == gid, "Seriously weird glyph ID detected!");
|
||||
details.mAdvance = advance;
|
||||
details.mXOffset = 0;
|
||||
details.mYOffset = 0;
|
||||
g.SetComplex(aTextRun->IsClusterStart(i), PR_TRUE, 1);
|
||||
aTextRun->SetGlyphs(i, g, &details);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_ft_scaled_font_unlock_face(font->CairoScaledFont());
|
||||
}
|
||||
|
||||
/**
|
||||
* gfxFT2Font
|
||||
*/
|
||||
gfxFT2Font::gfxFT2Font(FontEntry *aFontEntry,
|
||||
const gfxFontStyle *aFontStyle)
|
||||
: gfxFont(aFontEntry->GetName(), aFontStyle),
|
||||
mScaledFont(nsnull),
|
||||
mHasSpaceGlyph(PR_FALSE),
|
||||
mSpaceGlyph(0),
|
||||
mHasMetrics(PR_FALSE),
|
||||
mAdjustedSize(0),
|
||||
mFontEntry(aFontEntry)
|
||||
{
|
||||
}
|
||||
|
||||
gfxFT2Font::~gfxFT2Font()
|
||||
{
|
||||
if (mScaledFont) {
|
||||
cairo_scaled_font_destroy(mScaledFont);
|
||||
mScaledFont = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// rounding and truncation functions for a Freetype floating point number
|
||||
// (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer
|
||||
// part and low 6 bits for the fractional part.
|
||||
#define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1
|
||||
#define MOZ_FT_TRUNC(x) ((x) >> 6)
|
||||
#define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \
|
||||
MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s))))
|
||||
|
||||
const gfxFont::Metrics&
|
||||
gfxFT2Font::GetMetrics()
|
||||
{
|
||||
if (mHasMetrics)
|
||||
return mMetrics;
|
||||
|
||||
mMetrics.emHeight = GetStyle()->size;
|
||||
|
||||
FT_Face face = cairo_ft_scaled_font_lock_face(CairoScaledFont());
|
||||
|
||||
if (!face) {
|
||||
// Abort here already, otherwise we crash in the following
|
||||
// this can happen if the font-size requested is zero.
|
||||
// The metrics will be incomplete, but then we don't care.
|
||||
return mMetrics;
|
||||
}
|
||||
|
||||
mMetrics.emHeight = GetStyle()->size;
|
||||
|
||||
FT_UInt gid; // glyph ID
|
||||
|
||||
const double emUnit = 1.0 * face->units_per_EM;
|
||||
const double xScale = face->size->metrics.x_ppem / emUnit;
|
||||
const double yScale = face->size->metrics.y_ppem / emUnit;
|
||||
|
||||
// properties of space
|
||||
gid = FT_Get_Char_Index(face, ' ');
|
||||
if (gid) {
|
||||
FT_Load_Glyph(face, gid, FT_LOAD_DEFAULT);
|
||||
// face->glyph->metrics.width doesn't work for spaces, use advance.x instead
|
||||
mMetrics.spaceWidth = face->glyph->advance.x >> 6;
|
||||
// save the space glyph
|
||||
mSpaceGlyph = gid;
|
||||
} else {
|
||||
NS_ASSERTION(0, "blah");
|
||||
}
|
||||
|
||||
// properties of 'x', also use its width as average width
|
||||
gid = FT_Get_Char_Index(face, 'x'); // select the glyph
|
||||
if (gid) {
|
||||
// Load glyph into glyph slot. Here, use no_scale to get font units.
|
||||
FT_Load_Glyph(face, gid, FT_LOAD_NO_SCALE);
|
||||
mMetrics.xHeight = face->glyph->metrics.height * yScale;
|
||||
mMetrics.aveCharWidth = face->glyph->metrics.width * xScale;
|
||||
} else {
|
||||
// this font doesn't have an 'x'...
|
||||
// fake these metrics using a fraction of the font size
|
||||
mMetrics.xHeight = mMetrics.emHeight * 0.5;
|
||||
mMetrics.aveCharWidth = mMetrics.emHeight * 0.5;
|
||||
}
|
||||
|
||||
// compute an adjusted size if we need to
|
||||
if (mAdjustedSize == 0 && GetStyle()->sizeAdjust != 0) {
|
||||
gfxFloat aspect = mMetrics.xHeight / GetStyle()->size;
|
||||
mAdjustedSize = GetStyle()->GetAdjustedSize(aspect);
|
||||
mMetrics.emHeight = mAdjustedSize;
|
||||
}
|
||||
|
||||
// now load the OS/2 TrueType table to load access some more properties
|
||||
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
|
||||
if (os2 && os2->version != 0xFFFF) { // should be there if not old Mac font
|
||||
// if we are here we can improve the avgCharWidth
|
||||
mMetrics.aveCharWidth = os2->xAvgCharWidth * xScale;
|
||||
|
||||
mMetrics.superscriptOffset = os2->ySuperscriptYOffset * yScale;
|
||||
mMetrics.superscriptOffset = PR_MAX(1, mMetrics.superscriptOffset);
|
||||
// some fonts have the incorrect sign (from gfxPangoFonts)
|
||||
mMetrics.subscriptOffset = fabs(os2->ySubscriptYOffset * yScale);
|
||||
mMetrics.subscriptOffset = PR_MAX(1, fabs(mMetrics.subscriptOffset));
|
||||
mMetrics.strikeoutOffset = os2->yStrikeoutPosition * yScale;
|
||||
mMetrics.strikeoutSize = os2->yStrikeoutSize * yScale;
|
||||
} else {
|
||||
// use fractions of emHeight instead of xHeight for these to be more robust
|
||||
mMetrics.superscriptOffset = mMetrics.emHeight * 0.5;
|
||||
mMetrics.subscriptOffset = mMetrics.emHeight * 0.2;
|
||||
mMetrics.strikeoutOffset = mMetrics.emHeight * 0.3;
|
||||
mMetrics.strikeoutSize = face->underline_thickness * yScale;
|
||||
}
|
||||
// seems that underlineOffset really has to be negative
|
||||
mMetrics.underlineOffset = face->underline_position * yScale;
|
||||
mMetrics.underlineSize = face->underline_thickness * yScale;
|
||||
|
||||
// descents are negative in FT but Thebes wants them positive
|
||||
mMetrics.emAscent = face->ascender * yScale;
|
||||
mMetrics.emDescent = -face->descender * yScale;
|
||||
mMetrics.maxHeight = face->height * yScale;
|
||||
mMetrics.maxAscent = face->bbox.yMax * yScale;
|
||||
mMetrics.maxDescent = -face->bbox.yMin * yScale;
|
||||
mMetrics.maxAdvance = face->max_advance_width * xScale;
|
||||
// leading are not available directly (only for WinFNTs)
|
||||
double lineHeight = mMetrics.maxAscent + mMetrics.maxDescent;
|
||||
if (lineHeight > mMetrics.emHeight) {
|
||||
mMetrics.internalLeading = lineHeight - mMetrics.emHeight;
|
||||
} else {
|
||||
mMetrics.internalLeading = 0;
|
||||
}
|
||||
mMetrics.externalLeading = 0; // normal value for OS/2 fonts, too
|
||||
|
||||
SanitizeMetrics(&mMetrics, PR_FALSE);
|
||||
|
||||
/*
|
||||
printf("gfxOS2Font[%#x]::GetMetrics():\n"
|
||||
" emHeight=%f == %f=gfxFont::style.size == %f=adjSz\n"
|
||||
" maxHeight=%f xHeight=%f\n"
|
||||
" aveCharWidth=%f==xWidth spaceWidth=%f\n"
|
||||
" supOff=%f SubOff=%f strOff=%f strSz=%f\n"
|
||||
" undOff=%f undSz=%f intLead=%f extLead=%f\n"
|
||||
" emAsc=%f emDesc=%f maxH=%f\n"
|
||||
" maxAsc=%f maxDes=%f maxAdv=%f\n",
|
||||
(unsigned)this,
|
||||
mMetrics.emHeight, GetStyle()->size, mAdjustedSize,
|
||||
mMetrics.maxHeight, mMetrics.xHeight,
|
||||
mMetrics.aveCharWidth, mMetrics.spaceWidth,
|
||||
mMetrics.superscriptOffset, mMetrics.subscriptOffset,
|
||||
mMetrics.strikeoutOffset, mMetrics.strikeoutSize,
|
||||
mMetrics.underlineOffset, mMetrics.underlineSize,
|
||||
mMetrics.internalLeading, mMetrics.externalLeading,
|
||||
mMetrics.emAscent, mMetrics.emDescent, mMetrics.maxHeight,
|
||||
mMetrics.maxAscent, mMetrics.maxDescent, mMetrics.maxAdvance
|
||||
);
|
||||
*/
|
||||
|
||||
// XXX mMetrics.height needs to be set.
|
||||
cairo_ft_scaled_font_unlock_face(CairoScaledFont());
|
||||
|
||||
mHasMetrics = PR_TRUE;
|
||||
return mMetrics;
|
||||
}
|
||||
|
||||
|
||||
nsString
|
||||
gfxFT2Font::GetUniqueName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
gfxFT2Font::GetSpaceGlyph()
|
||||
{
|
||||
NS_ASSERTION (GetStyle ()->size != 0,
|
||||
"forgot to short-circuit a text run with zero-sized font?");
|
||||
|
||||
if(!mHasSpaceGlyph)
|
||||
{
|
||||
FT_UInt gid = 0; // glyph ID
|
||||
FT_Face face = cairo_ft_scaled_font_lock_face(CairoScaledFont());
|
||||
gid = FT_Get_Char_Index(face, ' ');
|
||||
FT_Load_Glyph(face, gid, FT_LOAD_DEFAULT);
|
||||
mSpaceGlyph = gid;
|
||||
mHasSpaceGlyph = PR_TRUE;
|
||||
cairo_ft_scaled_font_unlock_face(CairoScaledFont());
|
||||
}
|
||||
return mSpaceGlyph;
|
||||
}
|
||||
|
||||
cairo_font_face_t *
|
||||
gfxFT2Font::CairoFontFace()
|
||||
{
|
||||
// XXX we need to handle fake bold here (or by having a sepaerate font entry)
|
||||
if (mStyle.weight >= 600 && mFontEntry->mWeight < 600)
|
||||
printf("** We want fake weight\n");
|
||||
return mFontEntry->CairoFontFace();
|
||||
}
|
||||
|
||||
cairo_scaled_font_t *
|
||||
gfxFT2Font::CairoScaledFont()
|
||||
{
|
||||
if (!mScaledFont) {
|
||||
cairo_matrix_t sizeMatrix;
|
||||
cairo_matrix_t identityMatrix;
|
||||
|
||||
// XXX deal with adjusted size
|
||||
cairo_matrix_init_scale(&sizeMatrix, mStyle.size, mStyle.size);
|
||||
cairo_matrix_init_identity(&identityMatrix);
|
||||
|
||||
// synthetic oblique by skewing via the font matrix
|
||||
PRBool needsOblique = (!mFontEntry->mItalic && (mStyle.style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)));
|
||||
|
||||
if (needsOblique) {
|
||||
const double kSkewFactor = 0.25;
|
||||
|
||||
cairo_matrix_t style;
|
||||
cairo_matrix_init(&style,
|
||||
1, //xx
|
||||
0, //yx
|
||||
-1 * kSkewFactor, //xy
|
||||
1, //yy
|
||||
0, //x0
|
||||
0); //y0
|
||||
cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
|
||||
}
|
||||
|
||||
cairo_font_options_t *fontOptions = cairo_font_options_create();
|
||||
mScaledFont = cairo_scaled_font_create(CairoFontFace(), &sizeMatrix,
|
||||
&identityMatrix, fontOptions);
|
||||
cairo_font_options_destroy(fontOptions);
|
||||
}
|
||||
|
||||
NS_ASSERTION(mAdjustedSize == 0.0 ||
|
||||
cairo_scaled_font_status(mScaledFont) == CAIRO_STATUS_SUCCESS,
|
||||
"Failed to make scaled font");
|
||||
|
||||
return mScaledFont;
|
||||
}
|
||||
|
||||
PRBool
|
||||
gfxFT2Font::SetupCairoFont(gfxContext *aContext)
|
||||
{
|
||||
cairo_scaled_font_t *scaledFont = CairoScaledFont();
|
||||
|
||||
if (cairo_scaled_font_status(scaledFont) != CAIRO_STATUS_SUCCESS) {
|
||||
// Don't cairo_set_scaled_font as that would propagate the error to
|
||||
// the cairo_t, precluding any further drawing.
|
||||
return PR_FALSE;
|
||||
}
|
||||
cairo_set_scaled_font(aContext->GetCairo(), scaledFont);
|
||||
return PR_TRUE;
|
||||
}
|
|
@ -36,40 +36,70 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifdef MOZ_PANGO
|
||||
#define PANGO_ENABLE_BACKEND
|
||||
#define PANGO_ENABLE_ENGINE
|
||||
#endif
|
||||
|
||||
#include "gfxPlatformGtk.h"
|
||||
|
||||
#include "gfxFontconfigUtils.h"
|
||||
#ifdef MOZ_PANGO
|
||||
#include <pango/pangocairo.h>
|
||||
#include "gfxPangoFonts.h"
|
||||
#include "gfxContext.h"
|
||||
#else
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "gfxFT2Fonts.h"
|
||||
#endif
|
||||
|
||||
#include "cairo.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
#ifdef MOZ_X11
|
||||
#include <gdk/gdkx.h>
|
||||
#include "gfxXlibSurface.h"
|
||||
#endif /* MOZ_X11 */
|
||||
|
||||
#include "gfxPangoFonts.h"
|
||||
|
||||
#include <pango/pangocairo.h>
|
||||
#ifdef MOZ_DFB
|
||||
#include "gfxDirectFBSurface.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_GLITZ
|
||||
#include "gfxGlitzSurface.h"
|
||||
#include "glitz-glx.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_DFB
|
||||
#include "gfxDirectFBSurface.h"
|
||||
#endif
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
#include "nsMathUtils.h"
|
||||
|
||||
#include "lcms.h"
|
||||
|
||||
#ifndef MOZ_PANGO
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#endif
|
||||
|
||||
PRInt32 gfxPlatformGtk::sDPI = -1;
|
||||
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nsnull;
|
||||
|
||||
static cairo_user_data_key_t cairo_gdk_drawable_key;
|
||||
|
||||
#ifndef MOZ_PANGO
|
||||
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
|
||||
static FontTable *gPlatformFonts = NULL;
|
||||
static FontTable *gPlatformFontAliases = NULL;
|
||||
static FT_Library gPlatformFTLibrary = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
static cairo_user_data_key_t cairo_gdk_pixmap_key;
|
||||
static void do_gdk_pixmap_unref (void *data)
|
||||
{
|
||||
|
@ -86,6 +116,20 @@ gfxPlatformGtk::gfxPlatformGtk()
|
|||
if (!sFontconfigUtils)
|
||||
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
|
||||
|
||||
#ifndef MOZ_PANGO
|
||||
FT_Init_FreeType(&gPlatformFTLibrary);
|
||||
|
||||
gPlatformFonts = new FontTable();
|
||||
/* FIXME: DFB */
|
||||
//gPlatformFonts->Init(100);
|
||||
gPlatformFonts->Init(20);
|
||||
gPlatformFontAliases = new FontTable();
|
||||
/* FIXME: DFB */
|
||||
//gPlatformFontAliases->Init(100);
|
||||
gPlatformFontAliases->Init(20);
|
||||
UpdateFontList();
|
||||
#endif
|
||||
|
||||
InitDPI();
|
||||
}
|
||||
|
||||
|
@ -94,7 +138,17 @@ gfxPlatformGtk::~gfxPlatformGtk()
|
|||
gfxFontconfigUtils::Shutdown();
|
||||
sFontconfigUtils = nsnull;
|
||||
|
||||
#ifdef MOZ_PANGO
|
||||
gfxPangoFont::Shutdown();
|
||||
#else
|
||||
delete gPlatformFonts;
|
||||
gPlatformFonts = NULL;
|
||||
delete gPlatformFontAliases;
|
||||
gPlatformFontAliases = NULL;
|
||||
|
||||
FT_Done_FreeType(gPlatformFTLibrary);
|
||||
gPlatformFTLibrary = NULL;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// It would be nice to do this (although it might need to be after
|
||||
|
@ -111,6 +165,7 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size,
|
|||
{
|
||||
nsRefPtr<gfxASurface> newSurface = nsnull;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
int glitzf;
|
||||
int xrenderFormatID;
|
||||
switch (imageFormat) {
|
||||
|
@ -164,6 +219,7 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size,
|
|||
newSurface->SetData(&cairo_gdk_pixmap_key,
|
||||
pixmap,
|
||||
do_gdk_pixmap_unref);
|
||||
SetGdkDrawable(newSurface, GDK_DRAWABLE(pixmap));
|
||||
} else {
|
||||
// something went wrong with the surface creation.
|
||||
// Ignore and let's fall back to image surfaces.
|
||||
|
@ -207,6 +263,7 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size,
|
|||
newSurface = new gfxGlitzSurface(gdraw, gsurf, PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (newSurface) {
|
||||
gfxContext tmpCtx(newSurface);
|
||||
|
@ -217,6 +274,8 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size,
|
|||
return newSurface.forget();
|
||||
}
|
||||
|
||||
#ifdef MOZ_PANGO
|
||||
|
||||
nsresult
|
||||
gfxPlatformGtk::GetFontList(const nsACString& aLangGroup,
|
||||
const nsACString& aGenericFamily,
|
||||
|
@ -255,13 +314,236 @@ gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
|
|||
return new gfxPangoFontGroup(aFamilies, aStyle);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
nsresult
|
||||
gfxPlatformGtk::GetFontList(const nsACString& aLangGroup,
|
||||
const nsACString& aGenericFamily,
|
||||
nsStringArray& aListOfFonts)
|
||||
{
|
||||
return sFontconfigUtils->GetFontList(aLangGroup, aGenericFamily,
|
||||
aListOfFonts);
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxPlatformGtk::UpdateFontList()
|
||||
{
|
||||
FcPattern *pat = NULL;
|
||||
FcObjectSet *os = NULL;
|
||||
FcFontSet *fs = NULL;
|
||||
PRInt32 result = -1;
|
||||
|
||||
pat = FcPatternCreate();
|
||||
os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, NULL);
|
||||
|
||||
fs = FcFontList(NULL, pat, os);
|
||||
|
||||
|
||||
for (int i = 0; i < fs->nfont; i++) {
|
||||
char *str;
|
||||
|
||||
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
||||
continue;
|
||||
|
||||
//printf("Family: %s\n", str);
|
||||
|
||||
nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
|
||||
nsAutoString key(name);
|
||||
/* FIXME DFB */
|
||||
//ToLowerCase(key);
|
||||
nsRefPtr<FontFamily> ff;
|
||||
if (!gPlatformFonts->Get(key, &ff)) {
|
||||
ff = new FontFamily(name);
|
||||
gPlatformFonts->Put(key, ff);
|
||||
}
|
||||
|
||||
nsRefPtr<FontEntry> fe = new FontEntry(ff->mName);
|
||||
ff->mFaces.AppendElement(fe);
|
||||
|
||||
if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
|
||||
fe->mFilename = nsDependentCString(str);
|
||||
//printf(" - file: %s\n", str);
|
||||
}
|
||||
|
||||
int x;
|
||||
if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
|
||||
//printf(" - index: %d\n", x);
|
||||
fe->mFTFontIndex = x;
|
||||
} else {
|
||||
fe->mFTFontIndex = 0;
|
||||
}
|
||||
|
||||
if (FcPatternGetInteger(fs->fonts[i], FC_WEIGHT, 0, &x) == FcResultMatch) {
|
||||
switch(x) {
|
||||
case 0:
|
||||
fe->mWeight = 100;
|
||||
break;
|
||||
case 40:
|
||||
fe->mWeight = 200;
|
||||
break;
|
||||
case 50:
|
||||
fe->mWeight = 300;
|
||||
break;
|
||||
case 75:
|
||||
case 80:
|
||||
fe->mWeight = 400;
|
||||
break;
|
||||
case 100:
|
||||
fe->mWeight = 500;
|
||||
break;
|
||||
case 180:
|
||||
fe->mWeight = 600;
|
||||
break;
|
||||
case 200:
|
||||
fe->mWeight = 700;
|
||||
break;
|
||||
case 205:
|
||||
fe->mWeight = 800;
|
||||
break;
|
||||
case 210:
|
||||
fe->mWeight = 900;
|
||||
break;
|
||||
default:
|
||||
// rough estimate
|
||||
fe->mWeight = (((x * 4) + 100) / 100) * 100;
|
||||
break;
|
||||
}
|
||||
//printf(" - weight: %d\n", fe->mWeight);
|
||||
}
|
||||
|
||||
fe->mItalic = PR_FALSE;
|
||||
if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
|
||||
switch (x) {
|
||||
case FC_SLANT_ITALIC:
|
||||
case FC_SLANT_OBLIQUE:
|
||||
fe->mItalic = PR_TRUE;
|
||||
}
|
||||
//printf(" - slant: %d\n", x);
|
||||
}
|
||||
|
||||
//if (FcPatternGetInteger(fs->fonts[i], FC_WIDTH, 0, &x) == FcResultMatch)
|
||||
//printf(" - width: %d\n", x);
|
||||
// XXX deal with font-stretch stuff later
|
||||
}
|
||||
|
||||
if (pat)
|
||||
FcPatternDestroy(pat);
|
||||
if (os)
|
||||
FcObjectSetDestroy(os);
|
||||
if (fs)
|
||||
FcFontSetDestroy(fs);
|
||||
|
||||
return sFontconfigUtils->UpdateFontList();
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxPlatformGtk::ResolveFontName(const nsAString& aFontName,
|
||||
FontResolverCallback aCallback,
|
||||
void *aClosure,
|
||||
PRBool& aAborted)
|
||||
{
|
||||
|
||||
nsAutoString name(aFontName);
|
||||
/* FIXME: DFB */
|
||||
//ToLowerCase(name);
|
||||
|
||||
nsRefPtr<FontFamily> ff;
|
||||
if (gPlatformFonts->Get(name, &ff) ||
|
||||
gPlatformFontAliases->Get(name, &ff)) {
|
||||
aAborted = !(*aCallback)(ff->mName, aClosure);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCAutoString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
|
||||
|
||||
FcPattern *npat = FcPatternCreate();
|
||||
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
|
||||
FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, NULL);
|
||||
FcFontSet *nfs = FcFontList(NULL, npat, nos);
|
||||
|
||||
for (int k = 0; k < nfs->nfont; k++) {
|
||||
FcChar8 *str;
|
||||
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
||||
continue;
|
||||
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
|
||||
/* FIXME: DFB */
|
||||
//ToLowerCase(altName);
|
||||
if (gPlatformFonts->Get(altName, &ff)) {
|
||||
//printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
|
||||
gPlatformFontAliases->Put(name, ff);
|
||||
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
|
||||
FcPatternDestroy(npat);
|
||||
FcObjectSetDestroy(nos);
|
||||
FcFontSetDestroy(nfs);
|
||||
|
||||
{
|
||||
npat = FcPatternCreate();
|
||||
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
|
||||
FcPatternDel(npat, FC_LANG);
|
||||
FcConfigSubstitute(NULL, npat, FcMatchPattern);
|
||||
FcDefaultSubstitute(npat);
|
||||
|
||||
nos = FcObjectSetBuild(FC_FAMILY, NULL);
|
||||
nfs = FcFontList(NULL, npat, nos);
|
||||
|
||||
FcResult fresult;
|
||||
|
||||
FcPattern *match = FcFontMatch(NULL, npat, &fresult);
|
||||
if (match)
|
||||
FcFontSetAdd(nfs, match);
|
||||
|
||||
for (int k = 0; k < nfs->nfont; k++) {
|
||||
FcChar8 *str;
|
||||
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
||||
continue;
|
||||
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
|
||||
/* FIXME: DFB */
|
||||
//ToLowerCase(altName);
|
||||
if (gPlatformFonts->Get(altName, &ff)) {
|
||||
//printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
|
||||
gPlatformFontAliases->Put(name, ff);
|
||||
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
DONE:
|
||||
FcPatternDestroy(npat);
|
||||
FcObjectSetDestroy(nos);
|
||||
FcFontSetDestroy(nfs);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
|
||||
{
|
||||
return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
|
||||
}
|
||||
|
||||
gfxFontGroup *
|
||||
gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
|
||||
const gfxFontStyle *aStyle)
|
||||
{
|
||||
return new gfxFT2FontGroup(aFamilies, aStyle);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* static */
|
||||
void
|
||||
gfxPlatformGtk::InitDPI()
|
||||
{
|
||||
#ifdef MOZ_PANGO
|
||||
PangoContext *context = gdk_pango_context_get ();
|
||||
sDPI = pango_cairo_context_get_resolution (context);
|
||||
g_object_unref (context);
|
||||
#endif
|
||||
|
||||
if (sDPI <= 0) {
|
||||
// Fall back to something sane
|
||||
|
@ -272,6 +554,7 @@ gfxPlatformGtk::InitDPI()
|
|||
cmsHPROFILE
|
||||
gfxPlatformGtk::GetPlatformCMSOutputProfile()
|
||||
{
|
||||
#ifdef MOZ_X11
|
||||
const char EDID1_ATOM_NAME[] = "XFree86_DDC_EDID1_RAWDATA";
|
||||
const char ICC_PROFILE_ATOM_NAME[] = "_ICC_PROFILE";
|
||||
|
||||
|
@ -393,5 +676,64 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile()
|
|||
return profile;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
#ifndef MOZ_PANGO
|
||||
FT_Library
|
||||
gfxPlatformGtk::GetFTLibrary()
|
||||
{
|
||||
return gPlatformFTLibrary;
|
||||
}
|
||||
|
||||
FontFamily *
|
||||
gfxPlatformGtk::FindFontFamily(const nsAString& aName)
|
||||
{
|
||||
nsAutoString name(aName);
|
||||
/* FIXME: DFB */
|
||||
//ToLowerCase(name);
|
||||
|
||||
nsRefPtr<FontFamily> ff;
|
||||
if (!gPlatformFonts->Get(name, &ff)) {
|
||||
return nsnull;
|
||||
}
|
||||
return ff.get();
|
||||
}
|
||||
|
||||
FontEntry *
|
||||
gfxPlatformGtk::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
|
||||
{
|
||||
nsRefPtr<FontFamily> ff = FindFontFamily(aName);
|
||||
if (!ff)
|
||||
return nsnull;
|
||||
|
||||
return ff->FindFontEntry(aFontStyle);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
gfxPlatformGtk::SetGdkDrawable(gfxASurface *target,
|
||||
GdkDrawable *drawable)
|
||||
{
|
||||
if (target->CairoStatus())
|
||||
return;
|
||||
|
||||
cairo_surface_set_user_data (target->CairoSurface(),
|
||||
&cairo_gdk_drawable_key,
|
||||
drawable,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GdkDrawable *
|
||||
gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
|
||||
{
|
||||
if (target->CairoStatus())
|
||||
return nsnull;
|
||||
|
||||
return (GdkDrawable*) cairo_surface_get_user_data (target->CairoSurface(),
|
||||
&cairo_gdk_drawable_key);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче