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// this needs to be included before fontprops.h for UChar* to be defined. 28#include <wtf/unicode/Unicode.h> 29 30#include <wx/defs.h> 31#include <wx/gdicmn.h> 32#include <wx/font.h> 33#include <wx/fontutil.h> 34#include "fontprops.h" 35#include "non-kerned-drawing.h" 36 37#include <gdk/gdk.h> 38 39#include <cairo.h> 40#include <pango/pango.h> 41#include <pango/pangocairo.h> 42 43wxFontProperties::wxFontProperties(wxFont* font): 44m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0) 45{ 46 ASSERT(font && font->Ok()); 47 48#if USE(WXGC) 49 cairo_font_extents_t font_extents; 50 cairo_text_extents_t text_extents; 51 cairo_scaled_font_t* scaled_font = WebCore::createScaledFontForFont(font); 52 53 cairo_scaled_font_extents(scaled_font, &font_extents); 54 m_ascent = static_cast<int>(font_extents.ascent); 55 m_descent = static_cast<int>(font_extents.descent); 56 m_lineSpacing = static_cast<int>(font_extents.height); 57 cairo_scaled_font_text_extents(scaled_font, "x", &text_extents); 58 m_xHeight = text_extents.height; 59 cairo_scaled_font_text_extents(scaled_font, " ", &text_extents); 60 m_lineGap = m_lineSpacing - m_ascent - m_descent; 61 62 cairo_scaled_font_destroy(scaled_font); 63#else 64 PangoContext* context = gdk_pango_context_get_for_screen( gdk_screen_get_default() ); 65 PangoLayout* layout = pango_layout_new(context); 66 // and use it if it's valid 67 if ( font && font->Ok() ) 68 { 69 pango_layout_set_font_description 70 ( 71 layout, 72 font->GetNativeFontInfo()->description 73 ); 74 } 75 76 PangoFontMetrics* metrics = pango_context_get_metrics (context, font->GetNativeFontInfo()->description, NULL); 77 78 int height = font->GetPixelSize().GetHeight(); 79 80 m_ascent = PANGO_PIXELS(pango_font_metrics_get_ascent(metrics)); 81 m_descent = PANGO_PIXELS(pango_font_metrics_get_descent(metrics)); 82 83 int h; 84 85 const char* x = "x"; 86 pango_layout_set_text( layout, x, strlen(x) ); 87 pango_layout_get_pixel_size( layout, NULL, &h ); 88 89 m_xHeight = h; 90 m_lineGap = (m_ascent + m_descent) / 4; // FIXME: How can we calculate this via Pango? 91 m_lineSpacing = m_ascent + m_descent; 92 93 pango_font_metrics_unref(metrics); 94#endif 95} 96 97bool wxFontContainsCharacters(const wxFont& font, const UChar* characters, int length) 98{ 99 return true; 100} 101 102void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height, 103 wxCoord *descent, wxCoord *externalLeading ) 104{ 105 if ( width ) 106 *width = 0; 107 if ( height ) 108 *height = 0; 109 if ( descent ) 110 *descent = 0; 111 if ( externalLeading ) 112 *externalLeading = 0; 113 114 if (str.empty()) 115 return; 116 117// FIXME: Doesn't support height, descent or external leading, though we don't need this for WebKit 118// it will need to be implemented before merging into wx unless we craft a new API. 119#if USE(WXGC) 120 PangoFont* pangoFont = WebCore::createPangoFontForFont(&font); 121 PangoContext* pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(WebCore::pangoFontMap())); 122 PangoGlyph pangoGlyph = WebCore::pango_font_get_glyph(pangoFont, pangoContext, (gunichar)g_utf8_get_char(str.ToUTF8())); 123 cairo_glyph_t cglyph = { pangoGlyph, 0, 0 }; 124 cairo_text_extents_t extents; 125 cairo_scaled_font_t* scaled_font = WebCore::createScaledFontForFont(&font); 126 cairo_scaled_font_glyph_extents(scaled_font, &cglyph, 1, &extents); 127 128 if (cairo_scaled_font_status(scaled_font) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0) 129 *width = (wxCoord)extents.x_advance; 130 131 cairo_scaled_font_destroy(scaled_font); 132 g_object_unref(pangoContext); 133 g_object_unref(pangoFont); 134#else 135 PangoContext* context = gdk_pango_context_get_for_screen( gdk_screen_get_default() ); 136 PangoLayout* m_layout = pango_layout_new(context); 137 // and use it if it's valid 138 if ( font && font->IsOk() ) 139 { 140 pango_layout_set_font_description 141 ( 142 m_layout, 143 font->GetNativeFontInfo()->description 144 ); 145 } 146 147 // Set layout's text 148 const wxCharBuffer dataUTF8 = wxConvUTF8.cWX2MB(str); 149 if ( !dataUTF8 ) 150 { 151 // hardly ideal, but what else can we do if conversion failed? 152 return; 153 } 154 155 pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) ); 156 157 int h = 0; 158 pango_layout_get_pixel_size( m_layout, width, &h ); 159 160 if (descent) 161 { 162 PangoLayoutIter *iter = pango_layout_get_iter(m_layout); 163 int baseline = pango_layout_iter_get_baseline(iter); 164 pango_layout_iter_free(iter); 165 *descent = h - PANGO_PIXELS(baseline); 166 } 167 168 if (height) 169 *height = (wxCoord) h; 170#endif 171} 172 173