• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 
28 #include <wx/defs.h>
29 #include <wx/gdicmn.h>
30 #include <wx/font.h>
31 #include <wx/fontutil.h>
32 #include "fontprops.h"
33 #include "non-kerned-drawing.h"
34 
35 #include <gdk/gdk.h>
36 
37 #include <cairo.h>
38 #include <pango/pango.h>
39 #include <pango/pangocairo.h>
40 
wxFontProperties(wxFont * font)41 wxFontProperties::wxFontProperties(wxFont* font):
42 m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
43 {
44     ASSERT(font && font->Ok());
45 
46 #if USE(WXGC)
47     cairo_font_extents_t font_extents;
48     cairo_text_extents_t text_extents;
49     cairo_scaled_font_t* scaled_font = WebCore::createScaledFontForFont(font);
50 
51     cairo_scaled_font_extents(scaled_font, &font_extents);
52     m_ascent = static_cast<int>(font_extents.ascent);
53     m_descent = static_cast<int>(font_extents.descent);
54     m_lineSpacing = static_cast<int>(font_extents.height);
55     cairo_scaled_font_text_extents(scaled_font, "x", &text_extents);
56     m_xHeight = text_extents.height;
57     cairo_scaled_font_text_extents(scaled_font, " ", &text_extents);
58     m_lineGap = m_lineSpacing - m_ascent - m_descent;
59 
60     cairo_scaled_font_destroy(scaled_font);
61 #else
62     PangoContext* context = gdk_pango_context_get_for_screen( gdk_screen_get_default() );
63     PangoLayout* layout = pango_layout_new(context);
64     // and use it if it's valid
65     if ( font && font->Ok() )
66     {
67         pango_layout_set_font_description
68         (
69             layout,
70             font->GetNativeFontInfo()->description
71         );
72     }
73 
74     PangoFontMetrics* metrics = pango_context_get_metrics (context, font->GetNativeFontInfo()->description, NULL);
75 
76     int height = font->GetPixelSize().GetHeight();
77 
78     m_ascent = PANGO_PIXELS(pango_font_metrics_get_ascent(metrics));
79     m_descent = PANGO_PIXELS(pango_font_metrics_get_descent(metrics));
80 
81     int h;
82 
83     const char* x = "x";
84     pango_layout_set_text( layout, x, strlen(x) );
85     pango_layout_get_pixel_size( layout, NULL, &h );
86 
87     m_xHeight = h;
88     m_lineGap = (m_ascent + m_descent) / 4; // FIXME: How can we calculate this via Pango?
89     m_lineSpacing = m_ascent + m_descent;
90 
91     pango_font_metrics_unref(metrics);
92 #endif
93 }
94 
GetTextExtent(const wxFont & font,const wxString & str,wxCoord * width,wxCoord * height,wxCoord * descent,wxCoord * externalLeading)95 void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height,
96                             wxCoord *descent, wxCoord *externalLeading )
97 {
98     if ( width )
99         *width = 0;
100     if ( height )
101         *height = 0;
102     if ( descent )
103         *descent = 0;
104     if ( externalLeading )
105         *externalLeading = 0;
106 
107     if (str.empty())
108         return;
109 
110 // FIXME: Doesn't support height, descent or external leading, though we don't need this for WebKit
111 // it will need to be implemented before merging into wx unless we craft a new API.
112 #if USE(WXGC)
113     PangoFont* pangoFont = WebCore::createPangoFontForFont(&font);
114     PangoContext* pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(WebCore::pangoFontMap()));
115     PangoGlyph pangoGlyph = WebCore::pango_font_get_glyph(pangoFont, pangoContext, (gunichar)g_utf8_get_char(str.ToUTF8()));
116     cairo_glyph_t cglyph = { pangoGlyph, 0, 0 };
117     cairo_text_extents_t extents;
118     cairo_scaled_font_t* scaled_font = WebCore::createScaledFontForFont(&font);
119     cairo_scaled_font_glyph_extents(scaled_font, &cglyph, 1, &extents);
120 
121     if (cairo_scaled_font_status(scaled_font) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
122         *width = (wxCoord)extents.x_advance;
123 
124     cairo_scaled_font_destroy(scaled_font);
125     g_object_unref(pangoContext);
126     g_object_unref(pangoFont);
127 #else
128     PangoContext* context = gdk_pango_context_get_for_screen( gdk_screen_get_default() );
129     PangoLayout* m_layout = pango_layout_new(context);
130     // and use it if it's valid
131     if ( font && font->IsOk() )
132     {
133         pango_layout_set_font_description
134         (
135             m_layout,
136             font->GetNativeFontInfo()->description
137         );
138     }
139 
140     // Set layout's text
141     const wxCharBuffer dataUTF8 = wxConvUTF8.cWX2MB(str);
142     if ( !dataUTF8 )
143     {
144         // hardly ideal, but what else can we do if conversion failed?
145         return;
146     }
147 
148     pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) );
149 
150     int h = 0;
151     pango_layout_get_pixel_size( m_layout, width, &h );
152 
153     if (descent)
154     {
155         PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
156         int baseline = pango_layout_iter_get_baseline(iter);
157         pango_layout_iter_free(iter);
158         *descent = h - PANGO_PIXELS(baseline);
159     }
160 
161     if (height)
162         *height = (wxCoord) h;
163 #endif
164 }
165 
166