Added support for Unicode rendering through Pango to wxX11.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@17778 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2002-11-09 15:20:42 +00:00
parent bbd230a11d
commit 3049550ceb
20 changed files with 1176 additions and 269 deletions

View File

@@ -2213,6 +2213,15 @@ equivalent variable and GTK+ is version 1.2.3 or above.
wxUSE_PRINTING_ARCHITECTURE="no"
]
)
PKG_CHECK_MODULES(PANGOXFT, pangoxft,
[
CXXFLAGS="$CXXFLAGS $PANGOXFT_CFLAGS"
LIBS="$LIBS $PANGOXFT_LIBS"
],
[
AC_MSG_WARN([pangoxft library not found, library will be compiled without anti-aliasing support])
]
)
fi
wxUSE_UNIVERSAL="yes"

View File

@@ -2084,16 +2084,24 @@ typedef GtkWidget *WXWidget;
#endif
#ifdef __WXGTK20__
/* Input method thing */
typedef struct _GtkIMMulticontext GtkIMMulticontext;
#endif // __WXGTK20__
#endif // __WXGTK__
#if defined(__WXGTK20__) || (defined(__WXX11__) && wxUSE_UNICODE)
#define wxUSE_PANGO 1
#else
#define wxUSE_PANGO 0
#endif
#if wxUSE_PANGO
/* Stand-ins for Pango types */
typedef struct _PangoContext PangoContext;
typedef struct _PangoLayout PangoLayout;
typedef struct _PangoFontDescription PangoFontDescription;
/* Input method thing */
typedef struct _GtkIMMulticontext GtkIMMulticontext;
#endif // GTK+ 2.0
#endif // GTK
#endif
#ifdef __WXMGL__
typedef struct window_t *WXWidget;

View File

@@ -72,7 +72,9 @@ enum wxXLFDField
// further it might make sense to make it a real class with virtual methods
struct WXDLLEXPORT wxNativeFontInfo
{
#if defined(_WX_X_FONTLIKE)
#if wxUSE_PANGO
PangoFontDescription *description;
#elif defined(_WX_X_FONTLIKE)
// the members can't be accessed directly as we only parse the
// xFontName on demand
private:
@@ -113,8 +115,6 @@ public:
FATTRS fa;
FONTMETRICS fm;
FACENAMEDESC fn;
#elif defined(__WXGTK20__)
PangoFontDescription *description;
#else // other platforms
//
// This is a generic implementation that should work on all ports

View File

@@ -101,6 +101,13 @@ public:
const wxSize& GetInitialSize() const { return m_initialSize; }
bool GetShowIconic() const { return m_showIconic; }
#if wxUSE_UNICODE
// Global context for Pango layout. Either use X11
// or use Xft rendering according to GDK_USE_XFT
// environment variable
PangoContext* GetPangoContext();
#endif
// We need this before creating the app
static WXDisplay* GetDisplay() { return ms_display; }
static WXDisplay* ms_display;

View File

@@ -133,6 +133,11 @@ protected:
wxRegion m_currentClippingRegion;
wxRegion m_paintClippingRegion;
#if wxUSE_UNICODE
PangoContext *m_context;
PangoFontDescription *m_fontdesc;
#endif
void SetUpDC();
void Destroy();
void ComputeScaleAndOrigin();

View File

@@ -48,10 +48,11 @@ public:
bool underlined = FALSE,
const wxString& face = wxEmptyString,
wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
// wxMOTIF-specific
#if wxUSE_UNICODE
bool Create(const wxString& fontname,
wxFontEncoding fontenc = wxFONTENCODING_DEFAULT);
#endif
bool Create(const wxNativeFontInfo& fontinfo);
virtual ~wxFont();
@@ -69,6 +70,8 @@ public:
virtual wxFontEncoding GetEncoding() const;
virtual wxNativeFontInfo *GetNativeFontInfo() const;
virtual bool IsFixedWidth() const;
virtual void SetPointSize(int pointSize);
virtual void SetFamily(int family);
virtual void SetStyle(int style);
@@ -78,8 +81,13 @@ public:
virtual void SetEncoding(wxFontEncoding encoding);
virtual void SetNativeFontInfo( const wxNativeFontInfo& info );
// Implementation
virtual void SetNoAntiAliasing( bool no = TRUE );
virtual bool GetNoAntiAliasing();
// Implementation
#if wxUSE_PANGO
#else
// Find an existing, or create a new, XFontStruct
// based on this wxFont and the given scale. Append the
// font to list in the private data for future reference.
@@ -98,13 +106,12 @@ public:
// Helper function for convenient access of the above.
WXFontStructPtr GetFontStruct(double scale = 1.0,
WXDisplay* display = NULL) const;
#endif
protected:
// common part of all ctors
void Init();
// VZ: IMHO, we don't need it at all...
bool RealizeResource() { return TRUE; }
void Unshare();
private:

View File

@@ -21,10 +21,26 @@
// Include common declarations
#include "wx/x11/privx.h"
#if wxUSE_UNICODE
#include "pango/pango.h"
#endif
class wxMouseEvent;
class wxKeyEvent;
class wxWindow;
// ----------------------------------------------------------------------------
// Some Unicode <-> UTF8 macros stolen from GTK
// ----------------------------------------------------------------------------
#if wxUSE_UNICODE
#define wxGTK_CONV(s) wxConvUTF8.cWX2MB(s)
#define wxGTK_CONV_BACK(s) wxConvUTF8.cMB2WX(s)
#else
#define wxGTK_CONV(s) s.c_str()
#define wxGTK_CONV_BACK(s) s
#endif
// ----------------------------------------------------------------------------
// we maintain a hash table which contains the mapping from Widget to wxWindow
// corresponding to the window for this widget

View File

@@ -14,6 +14,8 @@
#include "wx/defs.h"
#include "wx/utils.h"
#include "wx/colour.h"
#include "X11/Xlib.h"
#include "X11/Xatom.h"
#include "X11/Xutil.h"

View File

@@ -171,10 +171,16 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxString localeInfo;
#if 0
localeInfo.Printf( _("Language: %s\nSystem locale name: %s\nCanonical locale name: %s\n"),
m_locale.GetLocale(),
m_locale.GetSysName().c_str(),
m_locale.GetCanonicalName().c_str() );
#endif
localeInfo.Printf( _("Language: %s\nCanonical locale name: %s\n"),
m_locale.GetLocale(),
m_locale.GetCanonicalName().c_str() );
wxMessageDialog(this, wxString(_("I18n sample\n(c) 1998, 1999 Vadim Zeitlin and Julian Smart"))
+ wxT("\n\n") + localeInfo,

View File

@@ -90,7 +90,7 @@ void wxTimerScheduler::QueueTimer(wxTimerDesc *desc, unsigned long when)
desc->shotTime = when;
desc->running = TRUE;
wxLogTrace("timer", "queued timer %p at tick %ld",
wxLogTrace( wxT("timer"), wxT("queued timer %p at tick %ld"),
desc->timer, (long) when);
if ( m_timers )
@@ -143,7 +143,7 @@ void wxTimerScheduler::NotifyTimers()
if ( !timerDeleted )
{
wxLogTrace("timer", "notified timer %p sheduled for %ld",
wxLogTrace( wxT("timer"), wxT("notified timer %p sheduled for %ld"),
desc->timer, (long) desc->shotTime);
desc->deleteFlag = NULL;
@@ -172,7 +172,7 @@ void wxTimer::Init()
wxTimer::~wxTimer()
{
wxLogTrace("timer", "destroying timer %p...", this);
wxLogTrace( wxT("timer"), wxT("destroying timer %p..."), this);
if ( IsRunning() )
Stop();
@@ -184,7 +184,7 @@ wxTimer::~wxTimer()
*m_desc->deleteFlag = TRUE;
delete m_desc;
wxLogTrace("timer", " ...done destroying timer %p...", this);
wxLogTrace( wxT("timer"), wxT(" ...done destroying timer %p..."), this);
}
bool wxTimer::IsRunning() const
@@ -194,7 +194,7 @@ bool wxTimer::IsRunning() const
bool wxTimer::Start(int millisecs, bool oneShot)
{
wxLogTrace("timer", "started timer %p: %i ms, oneshot=%i",
wxLogTrace( wxT("timer"), wxT("started timer %p: %i ms, oneshot=%i"),
this, millisecs, oneShot);
if ( !wxTimerBase::Start(millisecs, oneShot) )

View File

@@ -133,12 +133,10 @@ protected:
void InitFromNative();
private:
#ifdef __WXGTK20__
void ClearGdkFonts() { }
#else // GTK 1.x
// clear m_scaled_xfonts
// clear m_scaled_xfonts if any
void ClearGdkFonts();
#ifndef __WXGTK20__
// the map of font sizes to "GdkFont *"
wxScaledFontList m_scaled_xfonts;
#endif // GTK 2.0/1.x
@@ -159,12 +157,8 @@ private:
friend class wxFont;
};
// ============================================================================
// wxFontRefData implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxFontRefData creation
// wxFontRefData
// ----------------------------------------------------------------------------
void wxFontRefData::Init(int pointSize,
@@ -423,9 +417,9 @@ wxFontRefData::wxFontRefData(const wxString& fontname)
InitFromNative();
}
#ifndef __WXGTK20__
void wxFontRefData::ClearGdkFonts()
{
#ifndef __WXGTK20__
for ( wxScaledFontList::iterator i = m_scaled_xfonts.begin();
i != m_scaled_xfonts.end();
++i )
@@ -435,8 +429,8 @@ void wxFontRefData::ClearGdkFonts()
}
m_scaled_xfonts.clear();
}
#endif // GTK 1.x
}
wxFontRefData::~wxFontRefData()
{
@@ -606,10 +600,6 @@ void wxFontRefData::SetNativeFontInfo(const wxNativeFontInfo& info)
InitFromNative();
}
// ============================================================================
// wxFont implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxFont creation
// ----------------------------------------------------------------------------
@@ -633,7 +623,7 @@ wxFont::wxFont(const wxNativeFontInfo& info)
info.GetFaceName(),
info.GetEncoding() );
#else
Create(info.GetXFontName());
(void) Create(info.GetXFontName());
#endif
}
@@ -645,6 +635,8 @@ bool wxFont::Create( int pointSize,
const wxString& face,
wxFontEncoding encoding)
{
UnRef();
m_refData = new wxFontRefData(pointSize, family, style, weight,
underlined, face, encoding);
@@ -688,9 +680,6 @@ wxFont::~wxFont()
// accessors
// ----------------------------------------------------------------------------
// all accessors are just forwarded to wxFontRefData which has everything we
// need
int wxFont::GetPointSize() const
{
wxCHECK_MSG( Ok(), 0, wxT("invalid font") );

View File

@@ -133,12 +133,10 @@ protected:
void InitFromNative();
private:
#ifdef __WXGTK20__
void ClearGdkFonts() { }
#else // GTK 1.x
// clear m_scaled_xfonts
// clear m_scaled_xfonts if any
void ClearGdkFonts();
#ifndef __WXGTK20__
// the map of font sizes to "GdkFont *"
wxScaledFontList m_scaled_xfonts;
#endif // GTK 2.0/1.x
@@ -159,12 +157,8 @@ private:
friend class wxFont;
};
// ============================================================================
// wxFontRefData implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxFontRefData creation
// wxFontRefData
// ----------------------------------------------------------------------------
void wxFontRefData::Init(int pointSize,
@@ -423,9 +417,9 @@ wxFontRefData::wxFontRefData(const wxString& fontname)
InitFromNative();
}
#ifndef __WXGTK20__
void wxFontRefData::ClearGdkFonts()
{
#ifndef __WXGTK20__
for ( wxScaledFontList::iterator i = m_scaled_xfonts.begin();
i != m_scaled_xfonts.end();
++i )
@@ -435,8 +429,8 @@ void wxFontRefData::ClearGdkFonts()
}
m_scaled_xfonts.clear();
}
#endif // GTK 1.x
}
wxFontRefData::~wxFontRefData()
{
@@ -606,10 +600,6 @@ void wxFontRefData::SetNativeFontInfo(const wxNativeFontInfo& info)
InitFromNative();
}
// ============================================================================
// wxFont implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxFont creation
// ----------------------------------------------------------------------------
@@ -633,7 +623,7 @@ wxFont::wxFont(const wxNativeFontInfo& info)
info.GetFaceName(),
info.GetEncoding() );
#else
Create(info.GetXFontName());
(void) Create(info.GetXFontName());
#endif
}
@@ -645,6 +635,8 @@ bool wxFont::Create( int pointSize,
const wxString& face,
wxFontEncoding encoding)
{
UnRef();
m_refData = new wxFontRefData(pointSize, family, style, weight,
underlined, face, encoding);
@@ -688,9 +680,6 @@ wxFont::~wxFont()
// accessors
// ----------------------------------------------------------------------------
// all accessors are just forwarded to wxFontRefData which has everything we
// need
int wxFont::GetPointSize() const
{
wxCHECK_MSG( Ok(), 0, wxT("invalid font") );

View File

@@ -26,20 +26,22 @@
#include "wx/string.h"
#include "wx/regex.h"
#include "wx/utils.h"
#include "wx/app.h"
#include "wx/fontmap.h"
#include "wx/fontenum.h"
#include "wx/fontutil.h"
// ----------------------------------------------------------------------------
// GTK 2.0
// Pango
// ----------------------------------------------------------------------------
#if wxUSE_PANGO
#include "pango/pango.h"
#ifdef __WXGTK20__
#include "wx/gtk/private.h"
extern GtkWidget *wxGetRootWindow();
#endif
static int
cmp_families (const void *a, const void *b)
@@ -63,7 +65,11 @@ bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
PangoFontFamily **families = NULL;
gint n_families = 0;
pango_context_list_families (
#ifdef __WXGTK20__
gtk_widget_get_pango_context( wxGetRootWindow() ),
#else
wxTheApp->GetPangoContext(),
#endif
&families, &n_families );
qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
@@ -86,7 +92,7 @@ bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
#else
// GTK 2.0
// Pango
#ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
// The resulting warnings are switched off here

View File

@@ -37,9 +37,15 @@
#include "wx/hash.h"
#include "wx/module.h"
#ifdef __WXGTK20__
#if wxUSE_PANGO
#include "pango/pango.h"
#ifdef __WXGTK20__
#include "wx/gtk/private.h"
#else
#include "wx/x11/private.h"
#endif
// ----------------------------------------------------------------------------
// wxNativeFontInfo

View File

@@ -238,7 +238,6 @@ int wxEntryStart( int& argc, char *argv[] )
}
// X11 display stuff
Display* xdisplay = XOpenDisplay( displayName );
if (!xdisplay)
@@ -254,32 +253,14 @@ int wxEntryStart( int& argc, char *argv[] )
XSelectInput( xdisplay, XDefaultRootWindow(xdisplay), PropertyChangeMask);
// Command line argument stuff
wxTheApp->argc = argc;
#if wxUSE_UNICODE
wxTheApp->argv = new wxChar*[argc+1];
int mb_argc = 0;
while (mb_argc < argc)
{
wxString tmp = wxString::FromAscii( argv[mb_argc] );
wxTheApp->argv[mb_argc] = wxStrdup( tmp.c_str() );
mb_argc++;
}
wxTheApp->argv[mb_argc] = (wxChar *)NULL;
#else
wxTheApp->argv = argv;
#endif
if (wxTheApp->argc > 0)
{
wxFileName fname( wxTheApp->argv[0] );
wxTheApp->SetAppName( fname.GetName() );
}
// Misc.
wxSetDetectableAutoRepeat( TRUE );
#if wxUSE_UNICODE
// Glib's type system required by Pango
g_type_init();
#endif
if (!wxApp::Initialize())
return -1;
@@ -329,6 +310,28 @@ int wxEntry( int argc, char *argv[] )
return 0;
}
// Command line argument stuff
wxTheApp->argc = argc;
#if wxUSE_UNICODE
wxTheApp->argv = new wxChar*[argc+1];
int mb_argc = 0;
while (mb_argc < argc)
{
wxString tmp = wxString::FromAscii( argv[mb_argc] );
wxTheApp->argv[mb_argc] = wxStrdup( tmp.c_str() );
mb_argc++;
}
wxTheApp->argv[mb_argc] = (wxChar *)NULL;
#else
wxTheApp->argv = argv;
#endif
if (wxTheApp->argc > 0)
{
wxFileName fname( wxTheApp->argv[0] );
wxTheApp->SetAppName( fname.GetName() );
}
wxTheApp->m_showIconic = g_showIconic;
wxTheApp->m_initialSize = g_initialSize;
@@ -1099,6 +1102,40 @@ bool wxApp::OnInitGui()
return TRUE;
}
#if wxUSE_UNICODE
#include <pango/pango.h>
#include <pango/pangox.h>
#include <pango/pangoxft.h>
PangoContext* wxApp::GetPangoContext()
{
static int use_xft = -1;
if (use_xft == -1)
{
wxString val = wxGetenv( L"GDK_USE_XFT" );
use_xft = (val == L"1");
}
Display *xdisplay = (Display*) wxApp::GetDisplay();
int xscreen = DefaultScreen(xdisplay);
PangoContext *ret = NULL;
#if 0
if (use_xft)
ret = pango_xft_get_context( xdisplay, xscreen );
else
#endif
ret = pango_x_get_context( xdisplay );
if (!PANGO_IS_CONTEXT(ret))
wxLogError( wxT("No pango context.") );
return ret;
}
#endif
WXColormap wxApp::GetMainColormap(WXDisplay* display)
{
if (!display) /* Must be called first with non-NULL display */

View File

@@ -19,11 +19,20 @@
#include "wx/app.h"
#include "wx/image.h"
#include "wx/module.h"
#include "wx/fontutil.h"
#include "wx/x11/private.h"
#include <math.h>
#if wxUSE_UNICODE
#include "glib.h"
#include "pango/pangox.h"
#include "pango/pangoxft.h"
#include "pangox11.cpp"
#endif
//-----------------------------------------------------------------------------
// local defines
//-----------------------------------------------------------------------------
@@ -163,6 +172,11 @@ wxWindowDC::wxWindowDC()
m_isMemDC = FALSE;
m_isScreenDC = FALSE;
m_owner = (wxWindow *)NULL;
#if wxUSE_UNICODE
m_context = (PangoContext *)NULL;
m_fontdesc = (PangoFontDescription *)NULL;
#endif
}
wxWindowDC::wxWindowDC( wxWindow *window )
@@ -193,6 +207,11 @@ wxWindowDC::wxWindowDC( wxWindow *window )
m_display = (WXDisplay *) wxGlobalDisplay();
#if wxUSE_UNICODE
m_context = wxTheApp->GetPangoContext();
m_fontdesc = window->GetFont().GetNativeFontInfo()->description;
#endif
int screen = DefaultScreen( (Display*) m_display );
m_cmap = (WXColormap) DefaultColormap( (Display*) m_display, screen );
@@ -1368,19 +1387,35 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y )
wxCHECK_RET( Ok(), wxT("invalid window dc") );
if (!m_window) return;
#if wxUSE_UNICODE
// later
#else
XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display );
wxCHECK_RET( xfont, wxT("invalid font") );
x = XLOG2DEV(x);
y = YLOG2DEV(y);
#if wxUSE_UNICODE
PangoLayout *layout = pango_layout_new(m_context);
pango_layout_set_font_description(layout, m_fontdesc);
const wxCharBuffer data = wxConvUTF8.cWC2MB( text );
pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
// Measure layout.
int w,h;
pango_layout_get_pixel_size(layout, &w, &h);
wxCoord width = w;
wxCoord height = h;
// Draw layout.
x11_draw_layout( (Drawable) m_window, (GC) m_textGC, x, y, layout );
g_object_unref( G_OBJECT( layout ) );
CalcBoundingBox (x + width, y + height);
CalcBoundingBox (x, y);
#else
XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display );
wxCHECK_RET( xfont, wxT("invalid font") );
// First draw a rectangle representing the text background, if a text
// background is specified
if (m_textBackgroundColour.Ok () && (m_backgroundMode != wxTRANSPARENT))
@@ -1445,6 +1480,39 @@ void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoor
{
wxCHECK_RET( Ok(), "invalid dc" );
if (string.IsEmpty())
{
if (width) (*width) = 0;
if (height) (*height) = 0;
return;
}
#if wxUSE_UNICODE
PangoLayout *layout = pango_layout_new( m_context );
if (font)
pango_layout_set_font_description( layout, font->GetNativeFontInfo()->description );
else
pango_layout_set_font_description(layout, m_fontdesc);
const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
// Measure text.
int w,h;
pango_layout_get_pixel_size(layout, &w, &h);
if (width) (*width) = (wxCoord) w;
if (height) (*height) = (wxCoord) h;
if (descent)
{
// Do something about metrics here. TODO.
(*descent) = 0;
}
if (externalLeading) (*externalLeading) = 0; // ??
g_object_unref( G_OBJECT( layout ) );
#else
wxFont fontToUse = m_font;
if (font) fontToUse = *font;
@@ -1468,12 +1536,30 @@ void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoor
*descent = (wxCoord)(descent2 / m_scaleY );
if (externalLeading)
*externalLeading = 0; // ??
#endif
}
wxCoord wxWindowDC::GetCharWidth() const
{
wxCHECK_MSG( Ok(), 0, "invalid dc" );
#if wxUSE_UNICODE
PangoLayout *layout = pango_layout_new( m_context );
if (!m_fontdesc)
{
char *crash = NULL;
*crash = 0;
}
pango_layout_set_font_description(layout, m_fontdesc);
pango_layout_set_text(layout, "H", 1 );
int w,h;
pango_layout_get_pixel_size(layout, &w, &h);
g_object_unref( G_OBJECT( layout ) );
return w;
#else
wxCHECK_MSG( m_font.Ok(), 0, "invalid font" );
XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display );
@@ -1486,12 +1572,31 @@ wxCoord wxWindowDC::GetCharWidth() const
XTextExtents( xfont, "H", 1, &direction, &ascent, &descent, &overall );
return (wxCoord)(overall.width / m_scaleX);
#endif
}
wxCoord wxWindowDC::GetCharHeight() const
{
wxCHECK_MSG( Ok(), 0, "invalid dc" );
#if wxUSE_UNICODE
PangoLayout *layout = pango_layout_new( m_context );
if (!m_fontdesc)
{
char *crash = NULL;
*crash = 0;
}
pango_layout_set_font_description(layout, m_fontdesc);
pango_layout_set_text(layout, "H", 1 );
int w,h;
pango_layout_get_pixel_size(layout, &w, &h);
g_object_unref( G_OBJECT( layout ) );
return h;
#else
wxCHECK_MSG( m_font.Ok(), 0, "invalid font" );
XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display );
@@ -1504,6 +1609,7 @@ wxCoord wxWindowDC::GetCharHeight() const
XTextExtents( xfont, "H", 1, &direction, &ascent, &descent, &overall );
return (wxCoord)((ascent+descent) / m_scaleY);
#endif
}
void wxWindowDC::Clear()

View File

@@ -17,6 +17,8 @@
#include "wx/frame.h"
#include "wx/dcscreen.h"
#include "wx/utils.h"
#include "wx/app.h"
#include "wx/fontutil.h"
#include "wx/x11/private.h"
@@ -47,6 +49,11 @@ wxScreenDC::wxScreenDC()
m_isScreenDC = TRUE;
#if wxUSE_UNICODE
m_context = wxTheApp->GetPangoContext();
m_fontdesc = wxNORMAL_FONT->GetNativeFontInfo()->description;
#endif
SetUpDC();
XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors );

View File

@@ -38,12 +38,23 @@
#include "wx/fontutil.h" // for wxNativeFontInfo
#include "wx/tokenzr.h"
#include "wx/settings.h"
#include "wx/x11/private.h"
IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
// ----------------------------------------------------------------------------
// private classes
// constants
// ----------------------------------------------------------------------------
// the default size (in points) for the fonts
static const int wxDEFAULT_FONT_SIZE = 12;
#if wxUSE_UNICODE
#else
// ----------------------------------------------------------------------------
// wxXFont
// ----------------------------------------------------------------------------
// For every wxFont, there must be a font for each display and scale requested.
@@ -59,63 +70,6 @@ public:
int m_scale; // Scale * 100
};
class wxFontRefData: public wxGDIRefData
{
friend class wxFont;
public:
wxFontRefData(int size = wxDEFAULT,
int family = wxDEFAULT,
int style = wxDEFAULT,
int weight = wxDEFAULT,
bool underlined = FALSE,
const wxString& faceName = wxEmptyString,
wxFontEncoding encoding = wxFONTENCODING_DEFAULT)
{
Init(size, family, style, weight, underlined, faceName, encoding);
}
wxFontRefData(const wxFontRefData& data)
{
Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
data.m_underlined, data.m_faceName, data.m_encoding);
}
~wxFontRefData();
protected:
// common part of all ctors
void Init(int size,
int family,
int style,
int weight,
bool underlined,
const wxString& faceName,
wxFontEncoding encoding);
// font attributes
int m_pointSize;
int m_family;
int m_style;
int m_weight;
bool m_underlined;
wxString m_faceName;
wxFontEncoding m_encoding;
wxNativeFontInfo m_nativeFontInfo;
// A list of wxXFonts
wxList m_fonts;
};
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxXFont
// ----------------------------------------------------------------------------
wxXFont::wxXFont()
{
m_fontStruct = (WXFontStructPtr) 0;
@@ -130,6 +84,83 @@ wxXFont::~wxXFont()
// XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
// XFreeFont((Display*) m_display, fontStruct);
}
#endif
// ----------------------------------------------------------------------------
// wxFontRefData
// ----------------------------------------------------------------------------
class wxFontRefData: public wxObjectRefData
{
friend class wxFont;
public:
wxFontRefData(int size = wxDEFAULT,
int family = wxDEFAULT,
int style = wxDEFAULT,
int weight = wxDEFAULT,
bool underlined = FALSE,
const wxString& faceName = wxEmptyString,
wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
// copy cstr
wxFontRefData(const wxFontRefData& data);
// from XFLD
wxFontRefData(const wxString& fontname);
// dstr
virtual ~wxFontRefData();
// setters: all of them also take care to modify m_nativeFontInfo if we
// have it so as to not lose the information not carried by our fields
void SetPointSize(int pointSize);
void SetFamily(int family);
void SetStyle(int style);
void SetWeight(int weight);
void SetUnderlined(bool underlined);
void SetFaceName(const wxString& facename);
void SetEncoding(wxFontEncoding encoding);
void SetNoAntiAliasing( bool no = TRUE ) { m_noAA = no; }
bool GetNoAntiAliasing() { return m_noAA; }
// and this one also modifies all the other font data fields
void SetNativeFontInfo(const wxNativeFontInfo& info);
protected:
// common part of all ctors
void Init(int size,
int family,
int style,
int weight,
bool underlined,
const wxString& faceName,
wxFontEncoding encoding);
// set all fields from (already initialized and valid) m_nativeFontInfo
void InitFromNative();
// font attributes
int m_pointSize;
int m_family;
int m_style;
int m_weight;
bool m_underlined;
wxString m_faceName;
wxFontEncoding m_encoding; // Unused in Unicode mode
bool m_noAA; // No anti-aliasing
wxNativeFontInfo m_nativeFontInfo;
void ClearX11Fonts();
#if wxUSE_UNICODE
#else
// A list of wxXFonts
wxList m_fonts;
#endif
};
// ----------------------------------------------------------------------------
// wxFontRefData
@@ -143,34 +174,256 @@ void wxFontRefData::Init(int pointSize,
const wxString& faceName,
wxFontEncoding encoding)
{
if (family == wxDEFAULT)
m_family = wxSWISS;
else
m_family = family;
m_family = family == wxFONTFAMILY_DEFAULT ? wxFONTFAMILY_SWISS : family;
m_faceName = faceName;
if (style == wxDEFAULT)
m_style = wxNORMAL;
else
m_style = style;
// we accept both wxDEFAULT and wxNORMAL here - should we?
m_style = style == wxDEFAULT ? wxFONTSTYLE_NORMAL : style;
m_weight = weight == wxDEFAULT ? wxFONTWEIGHT_NORMAL : weight;
if (weight == wxDEFAULT)
m_weight = wxNORMAL;
else
m_weight = weight;
if (pointSize == wxDEFAULT)
m_pointSize = 12;
else
m_pointSize = pointSize;
// and here, do we really want to forbid creation of the font of the size
// 90 (the value of wxDEFAULT)??
m_pointSize = pointSize == wxDEFAULT || pointSize == -1
? wxDEFAULT_FONT_SIZE
: pointSize;
m_underlined = underlined;
m_encoding = encoding;
#if wxUSE_UNICODE
// Create native font info
m_nativeFontInfo.description = pango_font_description_new();
// And set its values
switch (m_family)
{
case wxFONTFAMILY_MODERN:
case wxFONTFAMILY_TELETYPE:
pango_font_description_set_family( m_nativeFontInfo.description, "monospace" );
break;
case wxFONTFAMILY_SWISS:
pango_font_description_set_family( m_nativeFontInfo.description, "serif" );
break;
default:
pango_font_description_set_family( m_nativeFontInfo.description, "sans" );
break;
}
SetStyle( m_style );
SetPointSize( m_pointSize );
SetWeight( m_weight );
#endif
}
wxFontRefData::~wxFontRefData()
void wxFontRefData::InitFromNative()
{
m_noAA = FALSE;
#if wxUSE_UNICODE
// Get native info
PangoFontDescription *desc = m_nativeFontInfo.description;
// init fields
m_faceName = wxGTK_CONV_BACK( pango_font_description_get_family( desc ) );
m_pointSize = pango_font_description_get_size( desc ) / PANGO_SCALE;
switch (pango_font_description_get_style( desc ))
{
case PANGO_STYLE_NORMAL:
m_style = wxFONTSTYLE_NORMAL;
break;
case PANGO_STYLE_ITALIC:
m_style = wxFONTSTYLE_ITALIC;
break;
case PANGO_STYLE_OBLIQUE:
m_style = wxFONTSTYLE_SLANT;
break;
}
switch (pango_font_description_get_weight( desc ))
{
case PANGO_WEIGHT_ULTRALIGHT:
m_weight = wxFONTWEIGHT_LIGHT;
break;
case PANGO_WEIGHT_LIGHT:
m_weight = wxFONTWEIGHT_LIGHT;
break;
case PANGO_WEIGHT_NORMAL:
m_weight = wxFONTWEIGHT_NORMAL;
break;
case PANGO_WEIGHT_BOLD:
m_weight = wxFONTWEIGHT_BOLD;
break;
case PANGO_WEIGHT_ULTRABOLD:
m_weight = wxFONTWEIGHT_BOLD;
break;
case PANGO_WEIGHT_HEAVY:
m_weight = wxFONTWEIGHT_BOLD;
break;
}
if (m_faceName == wxT("monospace"))
{
m_family = wxFONTFAMILY_TELETYPE;
}
else if (m_faceName == wxT("sans"))
{
m_family = wxFONTFAMILY_SWISS;
}
else
{
m_family = wxFONTFAMILY_UNKNOWN;
}
// Pango description are never underlined (?)
m_underlined = FALSE;
// Cannot we choose that
m_encoding = wxFONTENCODING_SYSTEM;
#else // X11
// get the font parameters from the XLFD
// -------------------------------------
m_faceName = m_nativeFontInfo.GetXFontComponent(wxXLFD_FAMILY);
m_weight = wxFONTWEIGHT_NORMAL;
wxString w = m_nativeFontInfo.GetXFontComponent(wxXLFD_WEIGHT).Upper();
if ( !w.empty() && w != _T('*') )
{
// the test below catches all of BOLD, EXTRABOLD, DEMIBOLD, ULTRABOLD
// and BLACK
if ( ((w[0u] == _T('B') && (!wxStrcmp(w.c_str() + 1, wxT("OLD")) ||
!wxStrcmp(w.c_str() + 1, wxT("LACK"))))) ||
wxStrstr(w.c_str() + 1, _T("BOLD")) )
{
m_weight = wxFONTWEIGHT_BOLD;
}
else if ( w == _T("LIGHT") || w == _T("THIN") )
{
m_weight = wxFONTWEIGHT_LIGHT;
}
}
switch ( wxToupper(*m_nativeFontInfo.
GetXFontComponent(wxXLFD_SLANT).c_str()) )
{
case _T('I'): // italique
m_style = wxFONTSTYLE_ITALIC;
break;
case _T('O'): // oblique
m_style = wxFONTSTYLE_SLANT;
break;
default:
m_style = wxFONTSTYLE_NORMAL;
}
long ptSize;
if ( m_nativeFontInfo.GetXFontComponent(wxXLFD_POINTSIZE).ToLong(&ptSize) )
{
// size in XLFD is in 10 point units
m_pointSize = (int)(ptSize / 10);
}
else
{
m_pointSize = wxDEFAULT_FONT_SIZE;
}
// examine the spacing: if the font is monospaced, assume wxTELETYPE
// family for compatibility with the old code which used it instead of
// IsFixedWidth()
if ( m_nativeFontInfo.GetXFontComponent(wxXLFD_SPACING).Upper() == _T('M') )
{
m_family = wxFONTFAMILY_TELETYPE;
}
else // not monospaceed
{
// don't even try guessing it, it doesn't work for too many fonts
// anyhow
m_family = wxFONTFAMILY_UNKNOWN;
}
// X fonts are never underlined...
m_underlined = FALSE;
// deal with font encoding
wxString
registry = m_nativeFontInfo.GetXFontComponent(wxXLFD_REGISTRY).Upper(),
encoding = m_nativeFontInfo.GetXFontComponent(wxXLFD_ENCODING).Upper();
if ( registry == _T("ISO8859") )
{
int cp;
if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 )
{
m_encoding = (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1);
}
}
else if ( registry == _T("MICROSOFT") )
{
int cp;
if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 )
{
m_encoding = (wxFontEncoding)(wxFONTENCODING_CP1250 + cp);
}
}
else if ( registry == _T("KOI8") )
{
m_encoding = wxFONTENCODING_KOI8;
}
else // unknown encoding
{
// may be give a warning here? or use wxFontMapper?
m_encoding = wxFONTENCODING_SYSTEM;
}
#endif // Pango/X11
}
wxFontRefData::wxFontRefData( const wxFontRefData& data )
: wxObjectRefData()
{
m_pointSize = data.m_pointSize;
m_family = data.m_family;
m_style = data.m_style;
m_weight = data.m_weight;
m_underlined = data.m_underlined;
m_faceName = data.m_faceName;
m_encoding = data.m_encoding;
m_noAA = data.m_noAA;
m_nativeFontInfo = data.m_nativeFontInfo;
}
wxFontRefData::wxFontRefData(int size, int family, int style,
int weight, bool underlined,
const wxString& faceName,
wxFontEncoding encoding)
{
Init(size, family, style, weight, underlined, faceName, encoding);
}
wxFontRefData::wxFontRefData(const wxString& fontname)
{
// VZ: FromString() should really work in both cases, doesn't it?
#if wxUSE_UNICODE
m_nativeFontInfo.FromString( fontname );
#else
m_nativeFontInfo.SetXFontName(fontname);
#endif
InitFromNative();
}
void wxFontRefData::ClearX11Fonts()
{
#if wxUSE_UNICODE
#else
wxNode* node = m_fonts.First();
while (node)
{
@@ -179,21 +432,119 @@ wxFontRefData::~wxFontRefData()
node = node->Next();
}
m_fonts.Clear();
#endif
}
wxFontRefData::~wxFontRefData()
{
ClearX11Fonts();
}
// ----------------------------------------------------------------------------
// wxFontRefData SetXXX()
// ----------------------------------------------------------------------------
void wxFontRefData::SetPointSize(int pointSize)
{
m_pointSize = pointSize;
#if wxUSE_UNICODE
// Get native info
PangoFontDescription *desc = m_nativeFontInfo.description;
pango_font_description_set_size( desc, m_pointSize * PANGO_SCALE );
#endif
}
void wxFontRefData::SetFamily(int family)
{
m_family = family;
// TODO: what are we supposed to do with m_nativeFontInfo here?
}
void wxFontRefData::SetStyle(int style)
{
m_style = style;
#if wxUSE_UNICODE
// Get native info
PangoFontDescription *desc = m_nativeFontInfo.description;
switch ( style )
{
case wxFONTSTYLE_ITALIC:
pango_font_description_set_style( desc, PANGO_STYLE_ITALIC );
break;
case wxFONTSTYLE_SLANT:
pango_font_description_set_style( desc, PANGO_STYLE_OBLIQUE );
break;
default:
wxFAIL_MSG( _T("unknown font style") );
// fall through
case wxFONTSTYLE_NORMAL:
pango_font_description_set_style( desc, PANGO_STYLE_NORMAL );
break;
}
#endif
}
void wxFontRefData::SetWeight(int weight)
{
m_weight = weight;
}
void wxFontRefData::SetUnderlined(bool underlined)
{
m_underlined = underlined;
// the XLFD doesn't have "underlined" field anyhow
}
void wxFontRefData::SetFaceName(const wxString& facename)
{
m_faceName = facename;
}
void wxFontRefData::SetEncoding(wxFontEncoding encoding)
{
m_encoding = encoding;
}
void wxFontRefData::SetNativeFontInfo(const wxNativeFontInfo& info)
{
// previously cached fonts shouldn't be used
ClearX11Fonts();
m_nativeFontInfo = info;
// set all the other font parameters from the native font info
InitFromNative();
}
// ----------------------------------------------------------------------------
// wxFont
// ----------------------------------------------------------------------------
void wxFont::Init()
{
}
wxFont::wxFont(const wxNativeFontInfo& info)
{
Init();
(void)Create(info.GetXFontName());
}
void wxFont::Init()
{
#if wxUSE_UNICODE
Create( info.GetPointSize(),
info.GetFamily(),
info.GetStyle(),
info.GetWeight(),
info.GetUnderlined(),
info.GetFaceName(),
info.GetEncoding() );
#else
(void) Create(info.GetXFontName());
#endif
}
bool wxFont::Create(int pointSize,
@@ -205,14 +556,15 @@ bool wxFont::Create(int pointSize,
wxFontEncoding encoding)
{
UnRef();
m_refData = new wxFontRefData(pointSize, family, style, weight,
underlined, faceName, encoding);
RealizeResource();
return TRUE;
}
#if wxUSE_UNICODE
#else
bool wxFont::Create(const wxString& fontname, wxFontEncoding enc)
{
if( !fontname )
@@ -315,6 +667,7 @@ bool wxFont::Create(const wxString& fontname, wxFontEncoding enc)
}
return TRUE;
}
#endif
wxFont::~wxFont()
{
@@ -339,90 +692,14 @@ void wxFont::Unshare()
}
}
void wxFont::SetPointSize(int pointSize)
{
Unshare();
M_FONTDATA->m_pointSize = pointSize;
M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
RealizeResource();
}
void wxFont::SetFamily(int family)
{
Unshare();
M_FONTDATA->m_family = family;
M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
RealizeResource();
}
void wxFont::SetStyle(int style)
{
Unshare();
M_FONTDATA->m_style = style;
M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
RealizeResource();
}
void wxFont::SetWeight(int weight)
{
Unshare();
M_FONTDATA->m_weight = weight;
M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
RealizeResource();
}
void wxFont::SetFaceName(const wxString& faceName)
{
Unshare();
M_FONTDATA->m_faceName = faceName;
M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
RealizeResource();
}
void wxFont::SetUnderlined(bool underlined)
{
Unshare();
M_FONTDATA->m_underlined = underlined;
RealizeResource();
}
void wxFont::SetEncoding(wxFontEncoding encoding)
{
Unshare();
M_FONTDATA->m_encoding = encoding;
M_FONTDATA->m_nativeFontInfo.GetXFontName().Clear(); // invalid now
RealizeResource();
}
void wxFont::SetNativeFontInfo(const wxNativeFontInfo& info)
{
Unshare();
M_FONTDATA->m_nativeFontInfo = info;
}
// ----------------------------------------------------------------------------
// query font attributes
// accessors
// ----------------------------------------------------------------------------
int wxFont::GetPointSize() const
{
wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
return M_FONTDATA->m_pointSize;
}
@@ -430,7 +707,7 @@ wxString wxFont::GetFaceName() const
{
wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
return M_FONTDATA->m_faceName ;
return M_FONTDATA->m_faceName;
}
int wxFont::GetFamily() const
@@ -468,18 +745,117 @@ wxFontEncoding wxFont::GetEncoding() const
return M_FONTDATA->m_encoding;
}
bool wxFont::GetNoAntiAliasing()
{
wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
return M_FONTDATA->m_noAA;
}
wxNativeFontInfo *wxFont::GetNativeFontInfo() const
{
wxCHECK_MSG( Ok(), (wxNativeFontInfo *)NULL, wxT("invalid font") );
if(M_FONTDATA->m_nativeFontInfo.GetXFontName().IsEmpty())
#if wxUSE_UNICODE
#else
if ( M_FONTDATA->m_nativeFontInfo.GetXFontName().empty() )
GetInternalFont();
#endif
return new wxNativeFontInfo(M_FONTDATA->m_nativeFontInfo);
}
bool wxFont::IsFixedWidth() const
{
wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
#if wxUSE_UNICODE
#else
if ( M_FONTDATA->HasNativeFont() )
{
// the monospace fonts are supposed to have "M" in the spacing field
wxString spacing = M_FONTDATA->
m_nativeFontInfo.GetXFontComponent(wxXLFD_SPACING);
return spacing.Upper() == _T('M');
}
#endif
return wxFontBase::IsFixedWidth();
}
// ----------------------------------------------------------------------------
// real implementation
// change font attributes
// ----------------------------------------------------------------------------
void wxFont::SetPointSize(int pointSize)
{
Unshare();
M_FONTDATA->SetPointSize(pointSize);
}
void wxFont::SetFamily(int family)
{
Unshare();
M_FONTDATA->SetFamily(family);
}
void wxFont::SetStyle(int style)
{
Unshare();
M_FONTDATA->SetStyle(style);
}
void wxFont::SetWeight(int weight)
{
Unshare();
M_FONTDATA->SetWeight(weight);
}
void wxFont::SetFaceName(const wxString& faceName)
{
Unshare();
M_FONTDATA->SetFaceName(faceName);
}
void wxFont::SetUnderlined(bool underlined)
{
Unshare();
M_FONTDATA->SetUnderlined(underlined);
}
void wxFont::SetEncoding(wxFontEncoding encoding)
{
Unshare();
M_FONTDATA->SetEncoding(encoding);
}
void wxFont::SetNativeFontInfo( const wxNativeFontInfo& info )
{
Unshare();
M_FONTDATA->SetNativeFontInfo( info );
}
void wxFont::SetNoAntiAliasing( bool no )
{
Unshare();
M_FONTDATA->SetNoAntiAliasing( no );
}
#if wxUSE_UNICODE
#else
// ----------------------------------------------------------------------------
// X11 implementation
// ----------------------------------------------------------------------------
// Find an existing, or create a new, XFontStruct
@@ -536,3 +912,4 @@ WXFontStructPtr wxFont::GetFontStruct(double scale, WXDisplay* display) const
return (f ? f->m_fontStruct : (WXFontStructPtr) 0);
}
#endif

276
src/x11/pangox11.cpp Normal file
View File

@@ -0,0 +1,276 @@
/**
* This file gets included from dcclient.cpp and implements
* the X11 interface to Pango.
* Copyright (C) Owen Taylor and Robert Roebling.
*/
/* Declaration */
void
x11_draw_glyphs( Drawable drawable,
GC gc,
PangoFont *font,
int x,
int y,
PangoGlyphString *glyphs);
void
x11_draw_layout_line_with_colors( Drawable drawable,
GC gc,
int x,
int y,
PangoLayoutLine *line,
XColor *foreground,
XColor *background);
void
x11_draw_layout_with_colors( Drawable drawable,
GC gc,
int x,
int y,
PangoLayout *layout,
XColor *foreground,
XColor *background);
void
x11_draw_layout( Drawable drawable,
GC gc,
int x,
int y,
PangoLayout *layout);
void
x11_pango_get_item_properties( PangoItem *item,
PangoUnderline *uline,
gboolean *strikethrough,
gint *rise,
PangoColor *fg_color,
gboolean *fg_set,
PangoColor *bg_color,
gboolean *bg_set,
gboolean *shape_set,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect);
/* Implementation */
void
x11_draw_glyphs( Drawable drawable,
GC gc,
PangoFont *font,
int x,
int y,
PangoGlyphString *glyphs)
{
if (PANGO_XFT_IS_FONT (font))
{
pango_xft_picture_render( wxGlobalDisplay(), drawable, drawable, font, glyphs, x, y );
}
else
{
pango_x_render( wxGlobalDisplay(), drawable, gc, font, glyphs, x, y );
}
}
void
x11_draw_layout_line_with_colors( Drawable drawable,
GC gc,
int x,
int y,
PangoLayoutLine *line,
XColor *foreground,
XColor *background)
{
PangoRectangle overall_rect;
PangoRectangle logical_rect;
PangoRectangle ink_rect;
PangoContext *context;
gint x_off = 0;
gint rise = 0;
context = pango_layout_get_context (line->layout);
pango_layout_line_get_extents (line,NULL, &overall_rect);
GSList *tmp_list = line->runs;
while (tmp_list)
{
PangoUnderline uline = PANGO_UNDERLINE_NONE;
PangoLayoutRun *run = (PangoLayoutRun *) tmp_list->data;
PangoColor fg_color, bg_color;
gboolean strike, fg_set, bg_set, shape_set;
gint risen_y;
tmp_list = tmp_list->next;
x11_pango_get_item_properties (run->item, &uline,
&strike, &rise, &fg_color, &fg_set, &bg_color, &bg_set,
&shape_set, &ink_rect, &logical_rect);
/* we subtract the rise because X coordinates are upside down */
risen_y = y - rise / PANGO_SCALE;
if (!shape_set)
{
if (uline == PANGO_UNDERLINE_NONE)
pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect);
else
pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect);
}
#if 0
XDrawRectangle( drawable, gc, TRUE,
x + (x_off + logical_rect.x) / PANGO_SCALE,
risen_y + overall_rect.y / PANGO_SCALE,
logical_rect.width / PANGO_SCALE,
overall_rect.height / PANGO_SCALE);
#endif
if (!shape_set)
{
int gx = x + x_off / PANGO_SCALE;
int gy = risen_y;
x11_draw_glyphs( drawable, gc, run->item->analysis.font, gx, gy, run->glyphs);
}
if (uline == PANGO_UNDERLINE_SINGLE)
{
XDrawLine( wxGlobalDisplay(), drawable, gc,
x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
risen_y + 1,
x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
risen_y + 1);
}
x_off += logical_rect.width;
}
}
void
x11_draw_layout_with_colors( Drawable drawable,
GC gc,
int x,
int y,
PangoLayout *layout,
XColor *foreground,
XColor *background)
{
PangoLayoutIter *iter = pango_layout_get_iter (layout);
do
{
PangoLayoutLine *line = pango_layout_iter_get_line (iter);
PangoRectangle logical_rect;
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
int baseline = pango_layout_iter_get_baseline (iter);
x11_draw_layout_line_with_colors( drawable, gc,
x + logical_rect.x / PANGO_SCALE,
y + baseline / PANGO_SCALE,
line,
foreground,
background);
} while (pango_layout_iter_next_line (iter));
pango_layout_iter_free (iter);
}
void
x11_draw_layout( Drawable drawable,
GC gc,
int x,
int y,
PangoLayout *layout)
{
wxCHECK_RET( layout, wxT("No layout") );
x11_draw_layout_with_colors (drawable, gc, x, y, layout, NULL, NULL);
}
void
x11_pango_get_item_properties( PangoItem *item,
PangoUnderline *uline,
gboolean *strikethrough,
gint *rise,
PangoColor *fg_color,
gboolean *fg_set,
PangoColor *bg_color,
gboolean *bg_set,
gboolean *shape_set,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect)
{
GSList *tmp_list = item->analysis.extra_attrs;
if (strikethrough)
*strikethrough = FALSE;
if (fg_set)
*fg_set = FALSE;
if (bg_set)
*bg_set = FALSE;
if (shape_set)
*shape_set = FALSE;
if (rise)
*rise = 0;
while (tmp_list)
{
PangoAttribute *attr = (PangoAttribute *) tmp_list->data;
switch (attr->klass->type)
{
case PANGO_ATTR_UNDERLINE:
if (uline)
*uline = (PangoUnderline) ((PangoAttrInt *)attr)->value;
break;
case PANGO_ATTR_STRIKETHROUGH:
if (strikethrough)
*strikethrough = ((PangoAttrInt *)attr)->value;
break;
case PANGO_ATTR_FOREGROUND:
if (fg_color)
*fg_color = ((PangoAttrColor *)attr)->color;
if (fg_set)
*fg_set = TRUE;
break;
case PANGO_ATTR_BACKGROUND:
if (bg_color)
*bg_color = ((PangoAttrColor *)attr)->color;
if (bg_set)
*bg_set = TRUE;
break;
case PANGO_ATTR_SHAPE:
if (shape_set)
*shape_set = TRUE;
if (logical_rect)
*logical_rect = ((PangoAttrShape *)attr)->logical_rect;
if (ink_rect)
*ink_rect = ((PangoAttrShape *)attr)->ink_rect;
break;
case PANGO_ATTR_RISE:
if (rise)
*rise = ((PangoAttrInt *)attr)->value;
break;
default:
break;
}
tmp_list = tmp_list->next;
}
}

View File

@@ -40,6 +40,7 @@
#include "wx/module.h"
#include "wx/menuitem.h"
#include "wx/log.h"
#include "wx/fontutil.h"
#include "wx/univ/renderer.h"
#if wxUSE_DRAG_AND_DROP
@@ -987,6 +988,17 @@ int wxWindowX11::GetCharHeight() const
{
wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
#if wxUSE_UNICODE
// There should be an easier way.
PangoLayout *layout = pango_layout_new( wxTheApp->GetPangoContext() );
pango_layout_set_font_description( layout, GetFont().GetNativeFontInfo()->description );
pango_layout_set_text(layout, "H", 1 );
int w,h;
pango_layout_get_pixel_size(layout, &w, &h);
g_object_unref( G_OBJECT( layout ) );
return h;
#else
WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, wxGlobalDisplay());
int direction, ascent, descent;
@@ -996,12 +1008,24 @@ int wxWindowX11::GetCharHeight() const
// return (overall.ascent + overall.descent);
return (ascent + descent);
#endif
}
int wxWindowX11::GetCharWidth() const
{
wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
#if wxUSE_UNICODE
// There should be an easier way.
PangoLayout *layout = pango_layout_new( wxTheApp->GetPangoContext() );
pango_layout_set_font_description( layout, GetFont().GetNativeFontInfo()->description );
pango_layout_set_text(layout, "H", 1 );
int w,h;
pango_layout_get_pixel_size(layout, &w, &h);
g_object_unref( G_OBJECT( layout ) );
return w;
#else
WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, wxGlobalDisplay());
int direction, ascent, descent;
@@ -1010,6 +1034,7 @@ int wxWindowX11::GetCharWidth() const
&descent, &overall);
return overall.width;
#endif
}
void wxWindowX11::GetTextExtent(const wxString& string,
@@ -1022,18 +1047,45 @@ void wxWindowX11::GetTextExtent(const wxString& string,
wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
if (string.IsEmpty())
{
if (x) (*x) = 0;
if (y) (*y) = 0;
return;
}
#if wxUSE_UNICODE
PangoLayout *layout = pango_layout_new( wxTheApp->GetPangoContext() );
PangoFontDescription *desc = fontToUse.GetNativeFontInfo()->description;
pango_layout_set_font_description(layout, desc);
const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data;
PangoRectangle rect;
pango_layout_line_get_extents(line, NULL, &rect);
if (x) (*x) = (wxCoord) (rect.width / PANGO_SCALE);
if (y) (*y) = (wxCoord) (rect.height / PANGO_SCALE);
if (descent)
{
// Do something about metrics here
(*descent) = 0;
}
if (externalLeading) (*externalLeading) = 0; // ??
g_object_unref( G_OBJECT( layout ) );
#else
WXFontStructPtr pFontStruct = fontToUse.GetFontStruct(1.0, wxGlobalDisplay());
int direction, ascent, descent2;
XCharStruct overall;
int slen = string.Len();
#if 0
if (use16)
XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *) (char*) (const char*) string, slen, &direction,
&ascent, &descent2, &overall);
#endif
XTextExtents((XFontStruct*) pFontStruct, (char*) string.c_str(), slen,
&direction, &ascent, &descent2, &overall);
@@ -1045,7 +1097,7 @@ void wxWindowX11::GetTextExtent(const wxString& string,
*descent = descent2;
if (externalLeading)
*externalLeading = 0;
#endif
}
// ----------------------------------------------------------------------------
@@ -1477,7 +1529,9 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window WXUNUSED(win
// id may be WXK_xxx code - these are outside ASCII range, so we
// can't just use toupper() on id
if (id >= 'a' && id <= 'z')
id = toupper(id);
{
id = id + 'A' - 'a';
}
wxevent.m_shiftDown = XKeyEventShiftIsDown(xevent);
wxevent.m_controlDown = XKeyEventCtrlIsDown(xevent);