Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 75404
Collapse All | Expand All

(-)mozilla/config/autoconf.mk.in.foo (+4 lines)
Lines 376-381 Link Here
376
MOZ_XFT_LIBS		= @MOZ_XFT_LIBS@
376
MOZ_XFT_LIBS		= @MOZ_XFT_LIBS@
377
MOZ_ENABLE_COREXFONTS	= @MOZ_ENABLE_COREXFONTS@
377
MOZ_ENABLE_COREXFONTS	= @MOZ_ENABLE_COREXFONTS@
378
378
379
MOZ_ENABLE_PANGO        = @MOZ_ENABLE_PANGO@
380
MOZ_PANGO_CFLAGS        = @MOZ_PANGO_CFLAGS@
381
MOZ_PANGO_LIBS          = @MOZ_PANGO_LIBS@
382
379
MOZ_EXTRA_X11CONVERTERS	= @MOZ_EXTRA_X11CONVERTERS@
383
MOZ_EXTRA_X11CONVERTERS	= @MOZ_EXTRA_X11CONVERTERS@
380
384
381
MOZ_ENABLE_XINERAMA	= @MOZ_ENABLE_XINERAMA@
385
MOZ_ENABLE_XINERAMA	= @MOZ_ENABLE_XINERAMA@
(-)mozilla/gfx/src/gtk/nsGfxFactoryGTK.cpp.foo (+23 lines)
Lines 62-67 Link Here
62
#ifdef NATIVE_THEME_SUPPORT
62
#ifdef NATIVE_THEME_SUPPORT
63
#include "nsNativeThemeGTK.h"
63
#include "nsNativeThemeGTK.h"
64
#endif
64
#endif
65
#ifdef MOZ_ENABLE_PANGO
66
#include "nsFontMetricsPango.h"
67
#endif
65
#ifdef MOZ_ENABLE_XFT
68
#ifdef MOZ_ENABLE_XFT
66
#include "nsFontMetricsXft.h"
69
#include "nsFontMetricsXft.h"
67
#endif
70
#endif
Lines 112-117 Link Here
112
  if (aOuter)
115
  if (aOuter)
113
    return NS_ERROR_NO_AGGREGATION;
116
    return NS_ERROR_NO_AGGREGATION;
114
117
118
#ifdef MOZ_ENABLE_PANGO
119
  if (NS_IsPangoEnabled()) {
120
    result = new nsFontMetricsPango();
121
    if (!result)
122
      return NS_ERROR_OUT_OF_MEMORY;
123
  } else {
124
#endif
115
#ifdef MOZ_ENABLE_XFT
125
#ifdef MOZ_ENABLE_XFT
116
  if (NS_IsXftEnabled()) {
126
  if (NS_IsXftEnabled()) {
117
    result = new nsFontMetricsXft();
127
    result = new nsFontMetricsXft();
Lines 127-132 Link Here
127
#ifdef MOZ_ENABLE_XFT
137
#ifdef MOZ_ENABLE_XFT
128
  }
138
  }
129
#endif
139
#endif
140
#ifdef MOZ_ENABLE_PANGO
141
  }
142
#endif
130
143
131
  NS_ADDREF(result);
144
  NS_ADDREF(result);
132
  nsresult rv = result->QueryInterface(aIID, aResult);
145
  nsresult rv = result->QueryInterface(aIID, aResult);
Lines 148-153 Link Here
148
  if (aOuter)
161
  if (aOuter)
149
    return NS_ERROR_NO_AGGREGATION;
162
    return NS_ERROR_NO_AGGREGATION;
150
163
164
#ifdef MOZ_ENABLE_PANGO
165
  if (NS_IsPangoEnabled()) {
166
    result = new nsFontEnumeratorPango();
167
    if (!result)
168
      return NS_ERROR_OUT_OF_MEMORY;
169
  } else {
170
#endif
151
#ifdef MOZ_ENABLE_XFT
171
#ifdef MOZ_ENABLE_XFT
152
  if (NS_IsXftEnabled()) {
172
  if (NS_IsXftEnabled()) {
153
    result = new nsFontEnumeratorXft();
173
    result = new nsFontEnumeratorXft();
Lines 163-168 Link Here
163
#ifdef MOZ_ENABLE_XFT
183
#ifdef MOZ_ENABLE_XFT
164
  }
184
  }
165
#endif
185
#endif
186
#ifdef MOZ_ENABLE_PANGO
187
  }
188
#endif
166
189
167
  NS_ADDREF(result);
190
  NS_ADDREF(result);
168
  nsresult rv = result->QueryInterface(aIID, aResult);
191
  nsresult rv = result->QueryInterface(aIID, aResult);
(-) (+72 lines)
Added Link Here
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* vim:expandtab:shiftwidth=4:tabstop=4:
3
 */
4
/* ***** BEGIN LICENSE BLOCK *****
5
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
 *
7
 * The contents of this file are subject to the Mozilla Public License Version
8
 * 1.1 (the "License"); you may not use this file except in compliance with
9
 * the License. You may obtain a copy of the License at
10
 * http://www.mozilla.org/MPL/
11
 *
12
 * Software distributed under the License is distributed on an "AS IS" basis,
13
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
 * for the specific language governing rights and limitations under the
15
 * License.
16
 *
17
 * The Original Code is mozilla.org code.
18
 *
19
 * The Initial Developer of the Original Code is Christopher Blizzard
20
 * <blizzard@mozilla.org>.  Portions created by the Initial Developer
21
 * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
22
 *
23
 * Contributor(s):
24
 *
25
 * Alternatively, the contents of this file may be used under the terms of
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
29
 * of those above. If you wish to allow use of your version of this file only
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
31
 * use your version of this file under the terms of the MPL, indicate your
32
 * decision by deleting the provisions above and replace them with the notice
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
34
 * the provisions above, a recipient may use your version of this file under
35
 * the terms of any one of the MPL, the GPL or the LGPL.
36
 *
37
 * ***** END LICENSE BLOCK ***** */
38
39
#ifndef _MOZILLA_DECODER_H
40
#define _MOZILLA_DECODER_H
41
42
#include <pango/pangofc-decoder.h>
43
44
G_BEGIN_DECLS
45
46
#define MOZILLA_TYPE_DECODER (mozilla_decoder_get_type())
47
#define MOZILLA_DECODER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOZILLA_TYPE_DECODER, MozillaDecoder))
48
#define MOZILLA_IS_DECODER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOZILLA_TYPE_DECODER))
49
50
typedef struct _MozillaDecoder      MozillaDecoder;
51
typedef struct _MozillaDecoderClass MozillaDecoderClass;
52
53
#define MOZILLA_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOZILLA_TYPE_DECODER, MozillaDecoderClass))
54
#define MOZILLA_IS_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOZILLA_TYPE_DECODER))
55
#define MOZILLA_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_TYPE_DECODER, MozillaDecoderClass))
56
57
struct _MozillaDecoder
58
{
59
  PangoFcDecoder parent_instance;
60
};
61
62
struct _MozillaDecoderClass
63
{
64
  PangoFcDecoderClass parent_class;
65
};
66
67
GType           mozilla_decoder_get_type (void);
68
int             mozilla_decoders_init    (void);
69
70
G_END_DECLS
71
72
#endif /*_MOZILLA_DECODER_H */
(-) (+376 lines)
Added Link Here
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* vim:expandtab:shiftwidth=4:tabstop=4:
3
 */
4
/* ***** BEGIN LICENSE BLOCK *****
5
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
 *
7
 * The contents of this file are subject to the Mozilla Public License Version
8
 * 1.1 (the "License"); you may not use this file except in compliance with
9
 * the License. You may obtain a copy of the License at
10
 * http://www.mozilla.org/MPL/
11
 *
12
 * Software distributed under the License is distributed on an "AS IS" basis,
13
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
 * for the specific language governing rights and limitations under the
15
 * License.
16
 *
17
 * The Original Code is mozilla.org code.
18
 *
19
 * The Initial Developer of the Original Code is Christopher Blizzard
20
 * <blizzard@mozilla.org>.  Portions created by the Initial Developer
21
 * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
22
 *
23
 * Contributor(s):
24
 *
25
 * Alternatively, the contents of this file may be used under the terms of
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
29
 * of those above. If you wish to allow use of your version of this file only
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
31
 * use your version of this file under the terms of the MPL, indicate your
32
 * decision by deleting the provisions above and replace them with the notice
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
34
 * the provisions above, a recipient may use your version of this file under
35
 * the terms of any one of the MPL, the GPL or the LGPL.
36
 *
37
 * ***** END LICENSE BLOCK ***** */
38
39
#define PANGO_ENABLE_BACKEND
40
#define PANGO_ENABLE_ENGINE
41
42
#include "mozilla-decoder.h"
43
#include <pango/pangoxft.h>
44
#include <pango/pangofc-fontmap.h>
45
#include <pango/pangofc-font.h>
46
#include <gdk/gdkx.h>
47
48
#include "nsString.h"
49
#include "nsIPersistentProperties2.h"
50
#include "nsNetUtil.h"
51
#include "nsReadableUtils.h"
52
#include "nsICharsetConverterManager.h"
53
#include "nsICharRepresentable.h"
54
#include "nsCompressedCharMap.h"
55
56
#undef DEBUG_CUSTOM_ENCODER
57
58
G_DEFINE_TYPE (MozillaDecoder, mozilla_decoder, PANGO_TYPE_FC_DECODER)
59
60
MozillaDecoder *mozilla_decoder_new      (void);
61
62
static FcCharSet  *mozilla_decoder_get_charset (PangoFcDecoder *decoder,
63
                                                PangoFcFont    *fcfont);
64
static PangoGlyph  mozilla_decoder_get_glyph   (PangoFcDecoder *decoder,
65
                                                PangoFcFont    *fcfont,
66
                                                guint32         wc);
67
68
static PangoFcDecoder *mozilla_find_decoder    (FcPattern *pattern,
69
                                                gpointer   user_data);
70
71
typedef struct _MozillaDecoderPrivate MozillaDecoderPrivate;
72
73
#define MOZILLA_DECODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MOZILLA_TYPE_DECODER, MozillaDecoderPrivate))
74
75
struct _MozillaDecoderPrivate {
76
    char *family;
77
    char *encoder;
78
    char *cmap;
79
    gboolean is_wide;
80
    FcCharSet *charset;
81
    nsCOMPtr<nsIUnicodeEncoder> uEncoder;
82
};
83
84
static nsICharsetConverterManager *gCharsetManager = NULL;
85
86
static NS_DEFINE_CID(kCharsetConverterManagerCID,
87
                     NS_ICHARSETCONVERTERMANAGER_CID);
88
89
// Hash tables that hold the custom encodings and custom cmaps used in
90
// various fonts.
91
GHashTable *encoder_hash = NULL;
92
GHashTable *cmap_hash = NULL;
93
GHashTable *wide_hash = NULL;
94
95
void
96
mozilla_decoder_init (MozillaDecoder *decoder)
97
{
98
}
99
100
void
101
mozilla_decoder_class_init (MozillaDecoderClass *klass)
102
{
103
    GObjectClass *object_class = G_OBJECT_CLASS(klass);
104
    PangoFcDecoderClass *parent_class = PANGO_FC_DECODER_CLASS (klass);
105
106
    /*   object_class->finalize = test_finalize; */
107
108
    parent_class->get_charset = mozilla_decoder_get_charset;
109
    parent_class->get_glyph = mozilla_decoder_get_glyph;
110
111
    g_type_class_add_private (object_class, sizeof (MozillaDecoderPrivate));
112
}
113
114
MozillaDecoder *
115
mozilla_decoder_new(void)
116
{
117
    return (MozillaDecoder *)g_object_new(MOZILLA_TYPE_DECODER, NULL);
118
}
119
120
#ifdef DEBUG_CUSTOM_ENCODER
121
void
122
dump_hash(char *key, char *val, void *arg)
123
{
124
    printf("%s -> %s\n", key, val);
125
}
126
#endif
127
128
/**
129
 * mozilla_decoders_init:
130
 *
131
 * #mozilla_decoders_init:
132
 *
133
 * This initializes all of the application-specific custom decoders
134
 * that Mozilla uses.  This should only be called once during the
135
 * lifetime of the application.
136
 *
137
 * Return value: zero on success, not zero on failure.
138
 *
139
 **/
140
141
int
142
mozilla_decoders_init(void)
143
{
144
    static PRBool initialized = PR_FALSE;
145
    if (initialized)
146
        return 0;
147
148
    encoder_hash = g_hash_table_new(g_str_hash, g_str_equal);
149
    cmap_hash = g_hash_table_new(g_str_hash, g_str_equal);
150
    wide_hash = g_hash_table_new(g_str_hash, g_str_equal);
151
152
    PRBool dumb = PR_FALSE;
153
    nsCOMPtr<nsIPersistentProperties> props;
154
    nsCOMPtr<nsISimpleEnumerator> encodeEnum;
155
156
    NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(props),
157
        NS_LITERAL_CSTRING("resource://gre/res/fonts/pangoFontEncoding.properties"));
158
159
    if (!props)
160
        goto loser;
161
162
    // Enumerate the properties in this file and figure out all of the
163
    // fonts for which we have custom encodings.
164
    props->Enumerate(getter_AddRefs(encodeEnum));
165
    if (!encodeEnum)
166
        goto loser;
167
168
    while (encodeEnum->HasMoreElements(&dumb), dumb) {
169
        nsCOMPtr<nsIPropertyElement> prop;
170
        encodeEnum->GetNext(getter_AddRefs(prop));
171
        if (!prop)
172
            goto loser;
173
174
        nsCAutoString name;
175
        prop->GetKey(name);
176
        nsAutoString value;
177
        prop->GetValue(value);
178
179
        if (!StringBeginsWith(name, NS_LITERAL_CSTRING("encoding."))) {
180
            printf("string doesn't begin with encoding?\n");
181
            continue;
182
        }
183
184
        name = Substring(name, 9);
185
186
        if (StringEndsWith(name, NS_LITERAL_CSTRING(".ttf"))) {
187
            name = Substring(name, 0, name.Length() - 4);
188
189
            // Strip off a .wide if it's there.
190
            if (StringEndsWith(value, NS_LITERAL_STRING(".wide"))) {
191
                g_hash_table_insert(wide_hash, g_strdup(name.get()),
192
                                    g_strdup("wide"));
193
                value = Substring(value, 0, name.Length() - 5);
194
            }
195
196
            g_hash_table_insert(encoder_hash,
197
                                g_strdup(name.get()),
198
                                g_strdup(NS_ConvertUTF16toUTF8(value).get()));
199
        }
200
        else if (StringEndsWith(name, NS_LITERAL_CSTRING(".ftcmap"))) {
201
            name = Substring(name, 0, name.Length() - 7);
202
            g_hash_table_insert(cmap_hash,
203
                                g_strdup(name.get()),
204
                                g_strdup(NS_ConvertUTF16toUTF8(value).get()));
205
        }
206
        else {
207
            printf("unknown suffix used for mapping\n");
208
        }
209
    }
210
211
    pango_fc_font_map_add_decoder_find_func(PANGO_FC_FONT_MAP(pango_xft_get_font_map(GDK_DISPLAY(),gdk_x11_get_default_screen())),
212
                                            mozilla_find_decoder,
213
                                            NULL,
214
                                            NULL);
215
216
    initialized = PR_TRUE;
217
218
#ifdef DEBUG_CUSTOM_ENCODER
219
    printf("*** encoders\n");
220
    g_hash_table_foreach(encoder_hash, (GHFunc)dump_hash, NULL);
221
222
    printf("*** cmaps\n");
223
    g_hash_table_foreach(cmap_hash, (GHFunc)dump_hash, NULL);
224
#endif
225
226
    return 0;
227
228
 loser:
229
    return -1;
230
}
231
232
FcCharSet *
233
mozilla_decoder_get_charset (PangoFcDecoder *decoder,
234
                             PangoFcFont    *fcfont)
235
{
236
    MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder);
237
238
    if (priv->charset)
239
        return priv->charset;
240
241
    // First time this has been accessed.  Populate the charset.
242
    priv->charset = FcCharSetCreate();
243
244
    if (!gCharsetManager) {
245
        nsServiceManager::GetService(kCharsetConverterManagerCID,
246
        NS_GET_IID(nsICharsetConverterManager), (nsISupports**)&gCharsetManager);
247
    }
248
249
    nsCOMPtr<nsIUnicodeEncoder> encoder;
250
    nsCOMPtr<nsICharRepresentable> represent;
251
252
    if (!gCharsetManager)
253
        goto end;
254
255
    gCharsetManager->GetUnicodeEncoderRaw(priv->encoder, getter_AddRefs(encoder));
256
    if (!encoder)
257
        goto end;
258
    
259
    encoder->SetOutputErrorBehavior(encoder->kOnError_Replace, nsnull, '?');
260
261
    priv->uEncoder = encoder;
262
263
    represent = do_QueryInterface(encoder);
264
    if (!represent)
265
        goto end;
266
267
    PRUint32 map[UCS2_MAP_LEN];
268
    memset(map, 0, sizeof(map));
269
270
    represent->FillInfo(map);
271
272
    for (int i = 0; i < NUM_UNICODE_CHARS; i++) {
273
        if (IS_REPRESENTABLE(map, i))
274
            FcCharSetAddChar(priv->charset, i);
275
    }
276
277
 end:
278
    return priv->charset;
279
}
280
281
PangoGlyph
282
mozilla_decoder_get_glyph   (PangoFcDecoder *decoder,
283
                             PangoFcFont    *fcfont,
284
                             guint32         wc)
285
{
286
    MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder);
287
288
    PangoGlyph retval = 0;
289
    PRUnichar inchar = wc;
290
    PRInt32 inlen = 1;
291
    char outchar[2] = {0,0};
292
    PRInt32 outlen = 2;
293
294
    priv->uEncoder->Convert(&inchar, &inlen, outchar, &outlen);
295
    if (outlen != 1) {
296
        printf("Warning: mozilla_decoder_get_glyph doesn't support more than one character conversions.\n");
297
        return 0;
298
    }
299
300
    FT_Face face = pango_fc_font_lock_face(fcfont);
301
302
#ifdef DEBUG_CUSTOM_ENCODER
303
    char *filename;
304
    FcPatternGetString(fcfont->font_pattern, FC_FILE, 0, (FcChar8 **)&filename);
305
    printf("filename is %s\n", filename);
306
#endif
307
308
    // Make sure to set the right charmap before trying to get the
309
    // glyph
310
    if (priv->cmap) {
311
        if (!strcmp(priv->cmap, "mac_roman")) {
312
            FT_Select_Charmap(face, ft_encoding_apple_roman);
313
        }
314
        else if (!strcmp(priv->cmap, "unicode")) {
315
            FT_Select_Charmap(face, ft_encoding_unicode);
316
        }
317
        else {
318
            printf("Warning: Invalid charmap entry for family %s\n",
319
                   priv->family);
320
        }
321
    }
322
323
    // Standard 8 bit to glyph translation
324
    if (!priv->is_wide) {
325
        FcChar32 blah = PRUint8(outchar[0]);
326
        retval = FT_Get_Char_Index(face, blah);
327
#ifdef DEBUG_CUSTOM_ENCODER
328
        printf("wc 0x%x outchar[0] 0x%x index 0x%x retval 0x%x face %p\n",
329
               wc, outchar[0], blah, retval, (void *)face);
330
#endif
331
    }
332
    else {
333
        printf("Warning: We don't support .wide fonts!\n");
334
        retval = 0;
335
    }
336
337
    pango_fc_font_unlock_face(fcfont);
338
339
    return retval;
340
}
341
342
PangoFcDecoder *
343
mozilla_find_decoder (FcPattern *pattern, gpointer user_data)
344
{
345
    // Compare the family name of the font that's been opened to see
346
    // if we have a custom decoder.
347
    const char *orig = NULL;
348
    FcPatternGetString(pattern, FC_FAMILY, 0, (FcChar8 **)&orig);
349
350
    nsCAutoString family;
351
    family.Assign(orig);
352
353
    family.StripWhitespace();
354
    ToLowerCase(family);
355
356
    char *encoder = (char *)g_hash_table_lookup(encoder_hash, family.get());
357
    if (!encoder)
358
        return NULL;
359
360
    MozillaDecoder *decoder = mozilla_decoder_new();
361
362
    MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder);
363
364
    priv->family = g_strdup(family.get());
365
    priv->encoder = g_strdup(encoder);
366
367
    char *cmap = (char *)g_hash_table_lookup(cmap_hash, family.get());
368
    if (cmap)
369
        priv->cmap = g_strdup(cmap);
370
371
    char *wide = (char *)g_hash_table_lookup(wide_hash, family.get());
372
    if (wide)
373
        priv->is_wide = TRUE;
374
375
    return PANGO_FC_DECODER(decoder);
376
}
(-)mozilla/gfx/src/gtk/gfxgtk.pkg.foo (+3 lines)
Lines 7-9 Link Here
7
#if MOZ_ENABLE_XFT
7
#if MOZ_ENABLE_XFT
8
dist/bin/res/fonts/fontEncoding.properties
8
dist/bin/res/fonts/fontEncoding.properties
9
#endif
9
#endif
10
#if MOZ_ENABLE_PANGO
11
dist/bin/res/fonts/pangoFontEncoding.properties
12
#endif
(-)mozilla/gfx/src/gtk/nsFontMetricsXft.cpp.foo (-2 / +67 lines)
Lines 238-244 Link Here
238
238
239
static int      CalculateSlant   (PRUint8  aStyle);
239
static int      CalculateSlant   (PRUint8  aStyle);
240
static int      CalculateWeight  (PRUint16 aWeight);
240
static int      CalculateWeight  (PRUint16 aWeight);
241
static void     AddLangGroup     (FcPattern *aPattern, nsIAtom *aLangGroup);
241
/* static */ void     AddLangGroup     (FcPattern *aPattern, nsIAtom *aLangGroup);
242
static void     AddFFRE          (FcPattern *aPattern, nsCString *aFamily,
242
static void     AddFFRE          (FcPattern *aPattern, nsCString *aFamily,
243
                                  PRBool aWeak);
243
                                  PRBool aWeak);
244
static void     FFREToFamily     (nsACString &aFFREName, nsACString &oFamily);
244
static void     FFREToFamily     (nsACString &aFFREName, nsACString &oFamily);
Lines 449-455 Link Here
449
    // Make sure that the pixel size is at least greater than zero
449
    // Make sure that the pixel size is at least greater than zero
450
    if (mPixelSize < 1) {
450
    if (mPixelSize < 1) {
451
#ifdef DEBUG
451
#ifdef DEBUG
452
        printf("*** Warning: nsFontMetricsXft was passed a pixel size of %d\n",
452
        printf("*** Warning: nsFontMetricsXft was passed a pixel size of %f\n",
453
               mPixelSize);
453
               mPixelSize);
454
#endif
454
#endif
455
        mPixelSize = 1;
455
        mPixelSize = 1;
Lines 474-479 Link Here
474
    if (NS_FAILED(RealizeFont()))
474
    if (NS_FAILED(RealizeFont()))
475
        return NS_ERROR_FAILURE;
475
        return NS_ERROR_FAILURE;
476
476
477
#ifdef DEBUG_foo
478
    printf("%i\n", mXHeight);
479
    printf("%i\n", mSuperscriptOffset);
480
    printf("%i\n", mSubscriptOffset);
481
    printf("%i\n", mStrikeoutOffset);
482
    printf("%i\n", mStrikeoutSize);
483
    printf("%i\n", mUnderlineOffset);
484
    printf("%i\n", mUnderlineSize);
485
    printf("%i\n", mMaxHeight);
486
    printf("%i\n", mLeading);
487
    printf("%i\n", mEmHeight);
488
    printf("%i\n", mEmAscent);
489
    printf("%i\n", mEmDescent);
490
    printf("%i\n", mMaxAscent);
491
    printf("%i\n", mMaxDescent);
492
    printf("%i\n", mMaxAdvance);
493
    printf("%i\n", mSpaceWidth);
494
    printf("%i\n", mAveCharWidth);
495
#endif /* DEBUG_foo */
496
477
    return NS_OK;
497
    return NS_OK;
478
}
498
}
479
499
Lines 530-535 Link Here
530
    f = mDeviceContext->DevUnitsToAppUnits();
550
    f = mDeviceContext->DevUnitsToAppUnits();
531
    aWidth = NSToCoordRound(glyphInfo.xOff * f);
551
    aWidth = NSToCoordRound(glyphInfo.xOff * f);
532
552
553
#ifdef DEBUG_foo
554
    printf("GetWidth (char *) %d\n", aWidth);
555
#endif
556
533
    return NS_OK;
557
    return NS_OK;
534
}
558
}
535
559
Lines 553-558 Link Here
553
    if (aFontID)
577
    if (aFontID)
554
        *aFontID = 0;
578
        *aFontID = 0;
555
579
580
#ifdef DEBUG_foo
581
    printf("GetWidth %d\n", aWidth);
582
#endif
583
556
    return NS_OK;
584
    return NS_OK;
557
}
585
}
558
586
Lines 586-591 Link Here
586
    if (nsnull != aFontID)
614
    if (nsnull != aFontID)
587
        *aFontID = 0;
615
        *aFontID = 0;
588
616
617
#ifdef DEBUG_foo
618
    printf("GetTextDimensions %d %d %d\n", aDimensions.width,
619
           aDimensions.ascent, aDimensions.descent);
620
#endif
621
589
    return NS_OK;
622
    return NS_OK;
590
}
623
}
591
624
Lines 645-650 Link Here
645
    nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
678
    nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
646
    data.drawBuffer = &drawBuffer;
679
    data.drawBuffer = &drawBuffer;
647
680
681
#ifdef DEBUG_foo
682
    printf("DrawString (char *)\n");
683
#endif
684
648
    return EnumerateGlyphs(aString, aLength,
685
    return EnumerateGlyphs(aString, aLength,
649
                           &nsFontMetricsXft::DrawStringCallback, &data);
686
                           &nsFontMetricsXft::DrawStringCallback, &data);
650
}
687
}
Lines 675-680 Link Here
675
    nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
712
    nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
676
    data.drawBuffer = &drawBuffer;
713
    data.drawBuffer = &drawBuffer;
677
714
715
#ifdef DEBUG_foo
716
    printf("DrawString\n");
717
#endif
718
678
    return EnumerateGlyphs(aString, aLength,
719
    return EnumerateGlyphs(aString, aLength,
679
                           &nsFontMetricsXft::DrawStringCallback, &data);
720
                           &nsFontMetricsXft::DrawStringCallback, &data);
680
}
721
}
Lines 714-719 Link Here
714
    aBoundingMetrics.ascent = NSToCoordRound(aBoundingMetrics.ascent * P2T);
755
    aBoundingMetrics.ascent = NSToCoordRound(aBoundingMetrics.ascent * P2T);
715
    aBoundingMetrics.descent = NSToCoordRound(aBoundingMetrics.descent * P2T);
756
    aBoundingMetrics.descent = NSToCoordRound(aBoundingMetrics.descent * P2T);
716
757
758
#ifdef DEBUG_foo
759
    printf("GetBoundingMetrics (char *)%d %d %d %d %d\n",
760
           aBoundingMetrics.leftBearing,
761
           aBoundingMetrics.rightBearing,
762
           aBoundingMetrics.width,
763
           aBoundingMetrics.ascent,
764
           aBoundingMetrics.descent);
765
#endif
766
717
    return NS_OK;
767
    return NS_OK;
718
}
768
}
719
769
Lines 755-760 Link Here
755
    if (nsnull != aFontID)
805
    if (nsnull != aFontID)
756
        *aFontID = 0;
806
        *aFontID = 0;
757
807
808
#ifdef DEBUG_foo
809
    printf("GetBoundingMetrics %d %d %d %d %d\n",
810
           aBoundingMetrics.leftBearing,
811
           aBoundingMetrics.rightBearing,
812
           aBoundingMetrics.width,
813
           aBoundingMetrics.ascent,
814
           aBoundingMetrics.descent);
815
#endif
816
758
    return NS_OK;
817
    return NS_OK;
759
}
818
}
760
819
Lines 766-771 Link Here
766
    return nsnull;
825
    return nsnull;
767
}
826
}
768
827
828
nsresult
829
nsFontMetricsXft::SetRightToLeftText(PRBool aIsRTL)
830
{
831
    return NS_OK;
832
}
833
769
PRUint32
834
PRUint32
770
nsFontMetricsXft::GetHints(void)
835
nsFontMetricsXft::GetHints(void)
771
{
836
{
(-)mozilla/gfx/src/gtk/Makefile.in.foo (-2 / +8 lines)
Lines 102-107 Link Here
102
		nsFontMetricsXft.cpp
102
		nsFontMetricsXft.cpp
103
endif
103
endif
104
104
105
ifdef MOZ_ENABLE_PANGO
106
CPPSRCS		+= \
107
		nsFontMetricsPango.cpp \
108
		mozilla-decoder.cpp
109
endif
110
105
ifdef MOZ_ENABLE_GTK
111
ifdef MOZ_ENABLE_GTK
106
CPPSRCS 	+= \
112
CPPSRCS 	+= \
107
		nsRegionGTK.cpp \
113
		nsRegionGTK.cpp \
Lines 155-164 Link Here
155
endif
161
endif
156
162
157
ifdef MOZ_ENABLE_XFT
163
ifdef MOZ_ENABLE_XFT
158
libs:: fontEncoding.properties
164
libs:: fontEncoding.properties pangoFontEncoding.properties
159
	$(INSTALL) $^ $(DIST)/bin/res/fonts
165
	$(INSTALL) $^ $(DIST)/bin/res/fonts
160
 
166
 
161
install:: fontEncoding.properties
167
install:: fontEncoding.properties pangoFontEncoding.properties
162
	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/res/fonts
168
	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/res/fonts
163
endif
169
endif
164
170
(-) (+120 lines)
Added Link Here
1
# ***** BEGIN LICENSE BLOCK *****
2
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
3
#
4
# The contents of this file are subject to the Mozilla Public License Version
5
# 1.1 (the "License"); you may not use this file except in compliance with
6
# the License. You may obtain a copy of the License at
7
# http://www.mozilla.org/MPL/
8
#
9
# Software distributed under the License is distributed on an "AS IS" basis,
10
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
# for the specific language governing rights and limitations under the
12
# License.
13
#
14
# The Original Code is Mozilla MathML Project.
15
#
16
# The Initial Developer of the Original Code is
17
# The University of Queensland.
18
# Portions created by the Initial Developer are Copyright (C) 2001
19
# the Initial Developer. All Rights Reserved.
20
#
21
# Contributor(s):
22
#   Roger B. Sidje <rbs@maths.uq.edu.au>
23
#   Jungshik Shin <jshin@mailaps.org>
24
#   Christopher Blizzard <blizzard@mozilla.org>
25
#
26
# Alternatively, the contents of this file may be used under the terms of
27
# either the GNU General Public License Version 2 or later (the "GPL"), or
28
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
# in which case the provisions of the GPL or the LGPL are applicable instead
30
# of those above. If you wish to allow use of your version of this file only
31
# under the terms of either the GPL or the LGPL, and not to allow others to
32
# use your version of this file under the terms of the MPL, indicate your
33
# decision by deleting the provisions above and replace them with the notice
34
# and other provisions required by the GPL or the LGPL. If you do not delete
35
# the provisions above, a recipient may use your version of this file under
36
# the terms of any one of the MPL, the GPL or the LGPL.
37
#
38
# ***** END LICENSE BLOCK *****
39
40
#  LOCALIZATION NOTE: FILE
41
#  Do not translate anything in this file
42
43
# This file contains supported custom encodings for pango font
44
# rendering.  For information about the specific encodings, look at
45
# fontEncoding.properties.  It contains a lot more verbiage than you
46
# will find here.  There are a lot of encodings supported in the old
47
# encoding file that pango supports directly, so there should be
48
# little reason to use those custom encodings.  The pango custom code
49
# doesn't support .wide fonts, so consider yourself warned!
50
#
51
52
# To be honest, we basically support mathml and that's about it.
53
54
encoding.cmr10.ttf  = x-ttf-cmr
55
encoding.cmmi10.ttf = x-ttf-cmmi
56
encoding.cmsy10.ttf = x-ttf-cmsy
57
encoding.cmex10.ttf = x-ttf-cmex
58
59
encoding.cmr10.ftcmap  = unicode
60
encoding.cmmi10.ftcmap = unicode
61
encoding.cmsy10.ftcmap = unicode
62
encoding.cmex10.ftcmap = unicode
63
64
encoding.math1.ttf          = x-mathematica1
65
encoding.math1-bold.ttf     = x-mathematica1
66
encoding.math1mono.ttf      = x-mathematica1
67
encoding.math1mono-bold.ttf = x-mathematica1
68
69
encoding.math2.ttf          = x-mathematica2
70
encoding.math2-bold.ttf     = x-mathematica2
71
encoding.math2mono.ttf      = x-mathematica2
72
encoding.math2mono-bold.ttf = x-mathematica2
73
74
encoding.math3.ttf          = x-mathematica3
75
encoding.math3-bold.ttf     = x-mathematica3
76
encoding.math3mono.ttf      = x-mathematica3
77
encoding.math3mono-bold.ttf = x-mathematica3
78
79
encoding.math4.ttf          = x-mathematica4
80
encoding.math4-bold.ttf     = x-mathematica4
81
encoding.math4mono.ttf      = x-mathematica4
82
encoding.math4mono-bold.ttf = x-mathematica4
83
84
encoding.math5.ttf          = x-mathematica5
85
encoding.math5-bold.ttf     = x-mathematica5
86
encoding.math5bold.ttf      = x-mathematica5
87
encoding.math5mono.ttf      = x-mathematica5
88
encoding.math5mono-bold.ttf = x-mathematica5
89
encoding.math5monobold.ttf  = x-mathematica5
90
91
encoding.math1.ftcmap          = mac_roman
92
encoding.math1-bold.ftcmap     = mac_roman
93
encoding.math1mono.ftcmap      = mac_roman
94
encoding.math1mono-bold.ftcmap = mac_roman
95
96
encoding.math2.ftcmap          = mac_roman
97
encoding.math2-bold.ftcmap     = mac_roman
98
encoding.math2mono.ftcmap      = mac_roman
99
encoding.math2mono-bold.ftcmap = mac_roman
100
101
encoding.math3.ftcmap          = mac_roman
102
encoding.math3-bold.ftcmap     = mac_roman
103
encoding.math3mono.ftcmap      = mac_roman
104
encoding.math3mono-bold.ftcmap = mac_roman
105
106
encoding.math4.ftcmap          = mac_roman
107
encoding.math4-bold.ftcmap     = mac_roman
108
encoding.math4mono.ftcmap      = mac_roman
109
encoding.math4mono-bold.ftcmap = mac_roman
110
111
encoding.math5.ftcmap          = mac_roman
112
encoding.math5-bold.ftcmap     = mac_roman
113
encoding.math5bold.ftcmap      = mac_roman
114
encoding.math5mono.ftcmap      = mac_roman
115
encoding.math5mono-bold.ftcmap = mac_roman
116
encoding.math5monobold.ftcmap  = mac_roman
117
118
encoding.mtextra.ttf = x-mtextra
119
encoding.mtextra.ftcmap = mac_roman
120
(-)mozilla/gfx/src/gtk/nsFontMetricsUtils.cpp.foo (+28 lines)
Lines 50-60 Link Here
50
#include "nsFontMetricsGTK.h"
50
#include "nsFontMetricsGTK.h"
51
#endif
51
#endif
52
52
53
#ifdef MOZ_ENABLE_PANGO
54
#include "nsFontMetricsPango.h"
55
#endif
56
53
#include "nsFontMetricsUtils.h"
57
#include "nsFontMetricsUtils.h"
54
58
55
PRUint32
59
PRUint32
56
NS_FontMetricsGetHints(void)
60
NS_FontMetricsGetHints(void)
57
{
61
{
62
#ifdef MOZ_ENABLE_PANGO
63
    if (NS_IsPangoEnabled()) {
64
        return nsFontMetricsPango::GetHints();
65
    }
66
#endif
58
#ifdef MOZ_ENABLE_XFT
67
#ifdef MOZ_ENABLE_XFT
59
    if (NS_IsXftEnabled()) {
68
    if (NS_IsXftEnabled()) {
60
        return nsFontMetricsXft::GetHints();
69
        return nsFontMetricsXft::GetHints();
Lines 69-74 Link Here
69
nsresult
78
nsresult
70
NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice, const nsString &aName)
79
NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice, const nsString &aName)
71
{
80
{
81
#ifdef MOZ_ENABLE_PANGO
82
    if (NS_IsPangoEnabled()) {
83
        return nsFontMetricsPango::FamilyExists(aDevice, aName);
84
    }
85
#endif
72
#ifdef MOZ_ENABLE_XFT
86
#ifdef MOZ_ENABLE_XFT
73
    // try to fall through to the core fonts if xft fails
87
    // try to fall through to the core fonts if xft fails
74
    if (NS_IsXftEnabled()) {
88
    if (NS_IsXftEnabled()) {
Lines 121-123 Link Here
121
}
135
}
122
136
123
#endif /* MOZ_ENABLE_XFT */
137
#endif /* MOZ_ENABLE_XFT */
138
139
#ifdef MOZ_ENABLE_PANGO
140
141
PRBool
142
NS_IsPangoEnabled(void)
143
{
144
    char *val = PR_GetEnv("MOZ_ENABLE_PANGO");
145
    if (val)
146
        return TRUE;
147
148
    return FALSE;
149
}
150
151
#endif
(-) (+1662 lines)
Added Link Here
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* vim:expandtab:shiftwidth=4:tabstop=4:
3
 */
4
/* ***** BEGIN LICENSE BLOCK *****
5
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
 *
7
 * The contents of this file are subject to the Mozilla Public License Version
8
 * 1.1 (the "License"); you may not use this file except in compliance with
9
 * the License. You may obtain a copy of the License at
10
 * http://www.mozilla.org/MPL/
11
 *
12
 * Software distributed under the License is distributed on an "AS IS" basis,
13
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
 * for the specific language governing rights and limitations under the
15
 * License.
16
 *
17
 * The Original Code is mozilla.org code.
18
 *
19
 * The Initial Developer of the Original Code is Christopher Blizzard
20
 * <blizzard@mozilla.org>.  Portions created by the Initial Developer
21
 * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
22
 *
23
 * Contributor(s):
24
 *
25
 * Alternatively, the contents of this file may be used under the terms of
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
29
 * of those above. If you wish to allow use of your version of this file only
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
31
 * use your version of this file under the terms of the MPL, indicate your
32
 * decision by deleting the provisions above and replace them with the notice
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
34
 * the provisions above, a recipient may use your version of this file under
35
 * the terms of any one of the MPL, the GPL or the LGPL.
36
 *
37
 * ***** END LICENSE BLOCK ***** */
38
39
#include "nsFont.h"
40
#include "nsIDeviceContext.h"
41
#include "nsICharsetConverterManager.h"
42
#include "nsIPref.h"
43
#include "nsIServiceManagerUtils.h"
44
45
#define PANGO_ENABLE_BACKEND
46
#define PANGO_ENABLE_ENGINE
47
48
#include "nsFontMetricsPango.h"
49
#include "nsRenderingContextGTK.h"
50
#include "nsDeviceContextGTK.h"
51
52
#include "nsUnicharUtils.h"
53
#include "nsQuickSort.h"
54
55
#include <pango/pangoxft.h>
56
#include <fontconfig/fontconfig.h>
57
#include <gdk/gdk.h>
58
#include <gdk/gdkx.h>
59
#include <freetype/tttables.h>
60
61
#include "mozilla-decoder.h"
62
63
#define FORCE_PR_LOG
64
#include "prlog.h"
65
66
// Globals
67
68
static PRLogModuleInfo            *gPangoFontLog;
69
static int                         gNumInstances;
70
71
// Defines
72
73
// This is the scaling factor that we keep fonts limited to against
74
// the display size.  If a pixel size is requested that is more than
75
// this factor larger than the height of the display, it's clamped to
76
// that value instead of the requested size.
77
#define FONT_MAX_FONT_SCALE 2
78
79
static NS_DEFINE_CID(kCharsetConverterManagerCID,
80
                     NS_ICHARSETCONVERTERMANAGER_CID);
81
82
struct MozPangoLangGroup {
83
    const char *mozLangGroup;
84
    const char *PangoLang;
85
};
86
87
static const MozPangoLangGroup MozPangoLangGroups[] = {
88
    { "x-western",      "en" },
89
    { "x-central-euro", "pl" },
90
    { "x-cyrillic",     "ru" },
91
    { "x-baltic",       "lv" },
92
    { "x-devanagari",   "hi" },
93
    { "x-tamil",        "ta" },
94
    { "x-unicode",      0    },
95
    { "x-user-def",     0    },
96
};
97
98
#define NUM_PANGO_LANG_GROUPS (sizeof (MozPangoLangGroups) / \
99
                               sizeof (MozPangoLangGroups[0]))
100
101
#ifdef DEBUG
102
#define DUMP_PRUNICHAR(ustr, ulen) for (PRUint32 llen=0;llen<ulen;llen++) \
103
                                      printf("0x%x ", ustr[llen]); \
104
                                   printf("\n");
105
#endif
106
107
// rounding and truncation functions for a Freetype floating point number 
108
// (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer
109
// part and low 6 bits for the fractional part. 
110
#define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1
111
#define MOZ_FT_TRUNC(x) ((x) >> 6)
112
#define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \
113
        MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s))))
114
115
// Static function decls
116
117
static PRBool IsASCIIFontName  (const nsString& aName);
118
static int    FFRECountHyphens (nsACString &aFFREName);
119
120
static PangoLanguage *GetPangoLanguage(nsIAtom *aLangGroup);
121
static const MozPangoLangGroup* FindPangoLangGroup (nsACString &aLangGroup);
122
123
static void   FreeGlobals    (void);
124
125
static PangoStyle  CalculateStyle  (PRUint8 aStyle);
126
static PangoWeight CalculateWeight (PRUint16 aWeight);
127
128
static nsresult    EnumFontsPango   (nsIAtom* aLangGroup, const char* aGeneric,
129
                                     PRUint32* aCount, PRUnichar*** aResult);
130
static int         CompareFontNames (const void* aArg1, const void* aArg2,
131
                                     void* aClosure);
132
133
extern void     AddLangGroup     (FcPattern *aPattern, nsIAtom *aLangGroup);
134
135
nsFontMetricsPango::nsFontMetricsPango()
136
{
137
    if (!gPangoFontLog)
138
        gPangoFontLog = PR_NewLogModule("PangoFont");
139
140
    gNumInstances++;
141
142
    mPangoFontDesc = nsnull;
143
    mPangoContext = nsnull;
144
    mLTRPangoContext = nsnull;
145
    mRTLPangoContext = nsnull;
146
    mPangoAttrList = nsnull;
147
    mIsRTL = PR_FALSE;
148
149
    static PRBool initialized = PR_FALSE;
150
    if (initialized)
151
        return;
152
153
    // Initialized the custom decoders
154
    if (!mozilla_decoders_init())
155
        initialized = PR_TRUE;
156
}
157
158
nsFontMetricsPango::~nsFontMetricsPango()
159
{
160
    delete mFont;
161
162
    if (mDeviceContext)
163
        mDeviceContext->FontMetricsDeleted(this);
164
165
    if (mPangoFontDesc)
166
        pango_font_description_free(mPangoFontDesc);
167
168
    if (mLTRPangoContext)
169
        g_object_unref(mLTRPangoContext);
170
171
    if (mRTLPangoContext)
172
        g_object_unref(mRTLPangoContext);
173
174
    if (mPangoAttrList)
175
        pango_attr_list_unref(mPangoAttrList);
176
177
    // XXX clean up all the pango objects
178
179
    if (--gNumInstances == 0)
180
        FreeGlobals();
181
}
182
183
184
NS_IMPL_ISUPPORTS1(nsFontMetricsPango, nsIFontMetrics)
185
186
// nsIFontMetrics impl
187
188
NS_IMETHODIMP
189
nsFontMetricsPango::Init(const nsFont& aFont, nsIAtom* aLangGroup,
190
                         nsIDeviceContext *aContext)
191
{
192
    mFont = new nsFont(aFont);
193
    mLangGroup = aLangGroup;
194
195
    // Hang on to the device context
196
    mDeviceContext = aContext;
197
    
198
    mPointSize = NSTwipsToFloatPoints(mFont->size);
199
200
    // Make sure to clamp the pixel size to something reasonable so we
201
    // don't make the X server blow up.
202
    nscoord screenPixels = gdk_screen_height();
203
    mPointSize = PR_MIN(screenPixels * FONT_MAX_FONT_SCALE, mPointSize);
204
205
    // enumerate over the font names passed in
206
    mFont->EnumerateFamilies(nsFontMetricsPango::EnumFontCallback, this);
207
208
    nsCOMPtr<nsIPref> prefService;
209
    prefService = do_GetService(NS_PREF_CONTRACTID);
210
    if (!prefService)
211
        return NS_ERROR_FAILURE;
212
        
213
    nsXPIDLCString value;
214
215
    // Set up the default font name if it's not set
216
    if (!mGenericFont) {
217
        prefService->CopyCharPref("font.default", getter_Copies(value));
218
219
        if (value.get())
220
            mDefaultFont = value.get();
221
        else
222
            mDefaultFont = "serif";
223
        
224
        mGenericFont = &mDefaultFont;
225
    }
226
227
    // set up the minimum sizes for fonts
228
    if (mLangGroup) {
229
        nsCAutoString name("font.min-size.");
230
231
        if (mGenericFont->Equals("monospace"))
232
            name.Append("fixed");
233
        else
234
            name.Append("variable");
235
236
        name.Append(char('.'));
237
238
        const char* langGroup;
239
        mLangGroup->GetUTF8String(&langGroup);
240
241
        name.Append(langGroup);
242
243
        PRInt32 minimumInt = 0;
244
        float minimum;
245
        nsresult res;
246
        res = prefService->GetIntPref(name.get(), &minimumInt);
247
        if (NS_FAILED(res))
248
            prefService->GetDefaultIntPref(name.get(), &minimumInt);
249
250
        if (minimumInt < 0)
251
            minimumInt = 0;
252
253
        minimum = minimumInt;
254
255
        // The minimum size is specified in pixels, not in points.
256
        // Convert the size from pixels to points.
257
        minimum = NSTwipsToFloatPoints(NSFloatPixelsToTwips(minimum, mDeviceContext->DevUnitsToAppUnits()));
258
        if (mPointSize < minimum)
259
            mPointSize = minimum;
260
    }
261
262
    // Make sure that the pixel size is at least greater than zero
263
    if (mPointSize < 1) {
264
#ifdef DEBUG
265
        printf("*** Warning: nsFontMetricsPango created with point size %f\n",
266
               mPointSize);
267
#endif
268
        mPointSize = 1;
269
    }
270
271
    nsresult rv = RealizeFont();
272
    if (NS_FAILED(rv))
273
        return rv;
274
275
    // Cache font metrics for the 'x' character
276
    return CacheFontMetrics();
277
}
278
279
nsresult
280
nsFontMetricsPango::CacheFontMetrics(void)
281
{
282
    // Get our scale factor
283
    float f;
284
    float val;
285
    f = mDeviceContext->DevUnitsToAppUnits();
286
287
    mPangoAttrList = pango_attr_list_new();
288
289
    GList *items = pango_itemize(mPangoContext,
290
                                 "a", 0, 1, mPangoAttrList, NULL);
291
292
    if (!items)
293
        return NS_ERROR_FAILURE;
294
295
    guint nitems = g_list_length(items);
296
    if (nitems != 1)
297
        return NS_ERROR_FAILURE;
298
299
    PangoItem *item = (PangoItem *)items->data;
300
    PangoFcFont  *fcfont = PANGO_FC_FONT(item->analysis.font);
301
    if (!fcfont)
302
        return NS_ERROR_FAILURE;
303
304
    // Get our font face
305
    FT_Face face;
306
    TT_OS2 *os2;
307
    XftFont *xftFont = pango_xft_font_get_font(PANGO_FONT(fcfont));
308
    if (!xftFont)
309
        return NS_ERROR_NOT_AVAILABLE;
310
311
    face = XftLockFace(xftFont);
312
    os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
313
314
    // mEmHeight (size in pixels of EM height)
315
    int size;
316
    if (FcPatternGetInteger(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) !=
317
        FcResultMatch) {
318
        size = 12;
319
    }
320
    mEmHeight = PR_MAX(1, nscoord(size * f));
321
322
    // mMaxAscent
323
    mMaxAscent = nscoord(xftFont->ascent * f);
324
325
    // mMaxDescent
326
    mMaxDescent = nscoord(xftFont->descent * f);
327
328
    nscoord lineHeight = mMaxAscent + mMaxDescent;
329
330
    // mLeading (needs ascent and descent and EM height) 
331
    if (lineHeight > mEmHeight)
332
        mLeading = lineHeight - mEmHeight;
333
    else
334
        mLeading = 0;
335
336
    // mMaxHeight (needs ascent and descent)
337
    mMaxHeight = lineHeight;
338
339
    // mEmAscent (needs maxascent, EM height, ascent and descent)
340
    mEmAscent = nscoord(mMaxAscent * mEmHeight / lineHeight);
341
342
    // mEmDescent (needs EM height and EM ascent
343
    mEmDescent = mEmHeight - mEmAscent;
344
345
    // mMaxAdvance
346
    mMaxAdvance = nscoord(xftFont->max_advance_width * f);
347
348
    // mSpaceWidth (width of a space)
349
    nscoord tmpWidth;
350
    GetWidth(" ", 1, tmpWidth, NULL);
351
    mSpaceWidth = tmpWidth;
352
353
    // mAveCharWidth (width of an 'average' char)
354
    //    XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents);
355
    //rawWidth = extents.width;
356
    //mAveCharWidth = NSToCoordRound(rawWidth * f);
357
    GetWidth("x", 1, tmpWidth, NULL);
358
    mAveCharWidth = tmpWidth;
359
360
    // mXHeight (height of an 'x' character)
361
    PRUnichar xUnichar('x');
362
    XGlyphInfo extents;
363
    if (FcCharSetHasChar(xftFont->charset, xUnichar)) {
364
        XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents);
365
        mXHeight = extents.height;
366
    }
367
    else {
368
        // 56% of ascent, best guess for non-true type or asian fonts
369
        mXHeight = nscoord(((float)mMaxAscent) * 0.56);
370
    }
371
    mXHeight = nscoord(mXHeight * f);
372
373
    // mUnderlineOffset (offset for underlines)
374
    val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position,
375
                                         face->size->metrics.y_scale);
376
    if (val) {
377
        mUnderlineOffset = NSToIntRound(val * f);
378
    }
379
    else {
380
        mUnderlineOffset =
381
            -NSToIntRound(PR_MAX(1, floor(0.1 * xftFont->height + 0.5)) * f);
382
    }
383
384
    // mUnderlineSize (thickness of an underline)
385
    val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness,
386
                                         face->size->metrics.y_scale);
387
    if (val) {
388
        mUnderlineSize = nscoord(PR_MAX(f, NSToIntRound(val * f)));
389
    }
390
    else {
391
        mUnderlineSize =
392
            NSToIntRound(PR_MAX(1, floor(0.05 * xftFont->height + 0.5)) * f);
393
    }
394
395
    // mSuperscriptOffset
396
    if (os2 && os2->ySuperscriptYOffset) {
397
        val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySuperscriptYOffset,
398
                                             face->size->metrics.y_scale);
399
        mSuperscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f)));
400
    }
401
    else {
402
        mSuperscriptOffset = mXHeight;
403
    }
404
405
    // mSubscriptOffset
406
    if (os2 && os2->ySubscriptYOffset) {
407
        val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySubscriptYOffset,
408
                                             face->size->metrics.y_scale);
409
        // some fonts have the incorrect sign. 
410
        val = (val < 0) ? -val : val;
411
        mSubscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f)));
412
    }
413
    else {
414
        mSubscriptOffset = mXHeight;
415
    }
416
417
    // mStrikeoutOffset
418
    mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0);
419
420
    // mStrikeoutSize
421
    mStrikeoutSize = mUnderlineSize;
422
423
    XftUnlockFace(xftFont);
424
425
    /*
426
    printf("%i\n", mXHeight);
427
    printf("%i\n", mSuperscriptOffset);
428
    printf("%i\n", mSubscriptOffset);
429
    printf("%i\n", mStrikeoutOffset);
430
    printf("%i\n", mStrikeoutSize);
431
    printf("%i\n", mUnderlineOffset);
432
    printf("%i\n", mUnderlineSize);
433
    printf("%i\n", mMaxHeight);
434
    printf("%i\n", mLeading);
435
    printf("%i\n", mEmHeight);
436
    printf("%i\n", mEmAscent);
437
    printf("%i\n", mEmDescent);
438
    printf("%i\n", mMaxAscent);
439
    printf("%i\n", mMaxDescent);
440
    printf("%i\n", mMaxAdvance);
441
    printf("%i\n", mSpaceWidth);
442
    printf("%i\n", mAveCharWidth);
443
    */
444
445
    return NS_OK;
446
}
447
448
NS_IMETHODIMP
449
nsFontMetricsPango::Destroy()
450
{
451
    mDeviceContext = nsnull;
452
    return NS_OK;
453
}
454
455
NS_IMETHODIMP
456
nsFontMetricsPango::GetFont(const nsFont *&aFont)
457
{
458
    aFont = mFont;
459
    return NS_OK;
460
}
461
462
NS_IMETHODIMP
463
nsFontMetricsPango::GetLangGroup(nsIAtom** aLangGroup)
464
{
465
    *aLangGroup = mLangGroup;
466
    NS_IF_ADDREF(*aLangGroup);
467
468
    return NS_OK;
469
}
470
471
NS_IMETHODIMP
472
nsFontMetricsPango::GetFontHandle(nsFontHandle &aHandle)
473
{
474
    return NS_ERROR_NOT_IMPLEMENTED;
475
}
476
477
// nsIFontMetricsPango impl
478
479
nsresult
480
nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength,
481
                             nscoord& aWidth,
482
                             nsRenderingContextGTK *aContext)
483
{
484
    PangoLayout *layout = pango_layout_new(mPangoContext);
485
486
    pango_layout_set_text(layout, aString, aLength);
487
488
    int width, height;
489
490
    pango_layout_get_size(layout, &width, &height);
491
492
    width /= PANGO_SCALE;
493
494
    g_object_unref(layout);
495
496
    float f;
497
    f = mDeviceContext->DevUnitsToAppUnits();
498
    aWidth = NSToCoordRound(width * f);
499
500
    //    printf("GetWidth (char *) %d\n", aWidth);
501
502
    return NS_OK;
503
}
504
505
nsresult
506
nsFontMetricsPango::GetWidth(const PRUnichar* aString, PRUint32 aLength,
507
                             nscoord& aWidth, PRInt32 *aFontID,
508
                             nsRenderingContextGTK *aContext)
509
{
510
    nsresult rv = NS_OK;
511
    PangoLayout *layout = pango_layout_new(mPangoContext);
512
513
    gchar *text = g_utf16_to_utf8(aString, aLength,
514
                                  NULL, NULL, NULL);
515
516
    if (!text) {
517
        aWidth = 0;
518
#ifdef DEBUG
519
        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
520
        DUMP_PRUNICHAR(aString, aLength)
521
#endif
522
        rv = NS_ERROR_FAILURE;
523
        goto loser;
524
    }
525
526
    gint width, height;
527
528
    pango_layout_set_text(layout, text, strlen(text));
529
    pango_layout_get_size(layout, &width, &height);
530
531
    width /= PANGO_SCALE;
532
533
    float f;
534
    f = mDeviceContext->DevUnitsToAppUnits();
535
    aWidth = NSToCoordRound(width * f);
536
537
    //    printf("GetWidth %d\n", aWidth);
538
539
 loser:
540
    g_free(text);
541
    g_object_unref(layout);
542
543
    return rv;
544
}
545
546
547
nsresult
548
nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
549
                                      PRUint32 aLength,
550
                                      nsTextDimensions& aDimensions, 
551
                                      PRInt32* aFontID,
552
                                      nsRenderingContextGTK *aContext)
553
{
554
    nsresult rv = NS_OK;
555
556
    PangoLayout *layout = pango_layout_new(mPangoContext);
557
558
    gchar *text = g_utf16_to_utf8(aString, aLength,
559
                                  NULL, NULL, NULL);
560
561
    if (!text) {
562
#ifdef DEBUG
563
        NS_WARNING("nsFontMetricsPango::GetTextDimensions invalid unicode to follow");
564
        DUMP_PRUNICHAR(aString, aLength)
565
#endif
566
        aDimensions.width = 0;
567
        aDimensions.ascent = 0;
568
        aDimensions.descent = 0;
569
570
        rv = NS_ERROR_FAILURE;
571
        goto loser;
572
    }
573
        
574
575
    pango_layout_set_text(layout, text, strlen(text));
576
577
    // Get the logical extents
578
    PangoLayoutLine *line;
579
    if (pango_layout_get_line_count(layout) != 1) {
580
        printf("Warning: more than one line!\n");
581
    }
582
    line = pango_layout_get_line(layout, 0);
583
584
    PangoRectangle rect;
585
    pango_layout_line_get_extents(line, NULL, &rect);
586
587
    float P2T;
588
    P2T = mDeviceContext->DevUnitsToAppUnits();
589
590
    aDimensions.width = NSToCoordRound(rect.width / PANGO_SCALE * P2T);
591
    aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(rect) / PANGO_SCALE * P2T);
592
    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(rect) / PANGO_SCALE * P2T);
593
594
    //    printf("GetTextDimensions %d %d %d\n", aDimensions.width,
595
    //aDimensions.ascent, aDimensions.descent);
596
597
 loser:
598
    g_free(text);
599
    g_object_unref(layout);
600
601
    return rv;
602
}
603
604
nsresult
605
nsFontMetricsPango::GetTextDimensions(const char*         aString,
606
                                      PRInt32             aLength,
607
                                      PRInt32             aAvailWidth,
608
                                      PRInt32*            aBreaks,
609
                                      PRInt32             aNumBreaks,
610
                                      nsTextDimensions&   aDimensions,
611
                                      PRInt32&            aNumCharsFit,
612
                                      nsTextDimensions&   aLastWordDimensions,
613
                                      PRInt32*            aFontID,
614
                                      nsRenderingContextGTK *aContext)
615
{
616
617
    return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks,
618
                                     aNumBreaks, aDimensions, aNumCharsFit,
619
                                     aLastWordDimensions, aContext);
620
621
}
622
623
nsresult
624
nsFontMetricsPango::GetTextDimensions(const PRUnichar*    aString,
625
                                      PRInt32             aLength,
626
                                      PRInt32             aAvailWidth,
627
                                      PRInt32*            aBreaks,
628
                                      PRInt32             aNumBreaks,
629
                                      nsTextDimensions&   aDimensions,
630
                                      PRInt32&            aNumCharsFit,
631
                                      nsTextDimensions&   aLastWordDimensions,
632
                                      PRInt32*            aFontID,
633
                                      nsRenderingContextGTK *aContext)
634
{
635
    nsresult rv = NS_OK;
636
    PRInt32 curBreak = 0;
637
    gchar *curChar;
638
639
    PRInt32 *utf8Breaks = new PRInt32[aNumBreaks];
640
641
    gchar *text = g_utf16_to_utf8(aString, (PRInt32)aLength,
642
                                  NULL, NULL, NULL);
643
644
    curChar = text;
645
646
    if (!text) {
647
#ifdef DEBUG
648
        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
649
        DUMP_PRUNICHAR(aString, (PRUint32)aLength)
650
#endif
651
        rv = NS_ERROR_FAILURE;
652
        goto loser;
653
    }
654
655
    // Covert the utf16 break offsets to utf8 break offsets
656
    for (PRInt32 curOffset=0; curOffset < aLength;
657
         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
658
        if (aBreaks[curBreak] == curOffset) {
659
            utf8Breaks[curBreak] = curChar - text;
660
            curBreak++;
661
        }
662
663
        if (IS_HIGH_SURROGATE(aString[curOffset]))
664
            curOffset++;
665
    }
666
667
    // Always catch the last break
668
    utf8Breaks[curBreak] = curChar - text;
669
670
#if 0
671
    if (strlen(text) != aLength) {
672
        printf("Different lengths for utf16 %d and utf8 %d\n", aLength, strlen(text));
673
        DUMP_PRUNICHAR(aString, aLength)
674
        DUMP_PRUNICHAR(text, strlen(text))
675
        for (PRInt32 i = 0; i < aNumBreaks; ++i) {
676
            printf("  break %d utf16 %d utf8 %d\n", i, aBreaks[i], utf8Breaks[i]);
677
        }
678
    }
679
#endif
680
681
    // We'll use curBreak to indicate which of the breaks end up being
682
    // used for the break point for this line.
683
    curBreak = 0;
684
    rv = GetTextDimensionsInternal(text, strlen(text), aAvailWidth, utf8Breaks,
685
                                   aNumBreaks, aDimensions, aNumCharsFit,
686
                                   aLastWordDimensions, aContext);
687
688
    // Figure out which of the breaks we ended up using to convert
689
    // back to utf16 - start from the end.
690
    for (PRInt32 i = aNumBreaks - 1; i >= 0; --i) {
691
        if (utf8Breaks[i] == aNumCharsFit) {
692
            //      if (aNumCharsFit != aBreaks[i])
693
            //                printf("Fixing utf8 -> utf16 %d -> %d\n", aNumCharsFit, aBreaks[i]);
694
            aNumCharsFit = aBreaks[i];
695
            break;
696
        }
697
    }
698
699
 loser:
700
    if (text)
701
        g_free(text);
702
703
    delete[] utf8Breaks;
704
705
    return rv;
706
}
707
708
nsresult
709
nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength,
710
                               nscoord aX, nscoord aY,
711
                               const nscoord* aSpacing,
712
                               nsRenderingContextGTK *aContext,
713
                               nsDrawingSurfaceGTK *aSurface)
714
{
715
    PangoLayout *layout = pango_layout_new(mPangoContext);
716
717
    pango_layout_set_text(layout, aString, aLength);
718
719
    int x = aX;
720
    int y = aY;
721
722
    aContext->GetTranMatrix()->TransformCoord(&x, &y);
723
724
    PangoLayoutLine *line;
725
    if (pango_layout_get_line_count(layout) != 1) {
726
        printf("Warning: more than one line!\n");
727
    }
728
    line = pango_layout_get_line(layout, 0);
729
730
    aContext->UpdateGC();
731
    GdkGC *gc = aContext->GetGC();
732
733
    if (aSpacing && *aSpacing) {
734
        DrawStringSlowly(aString, NULL, aLength, aSurface->GetDrawable(),
735
                         gc, x, y, line, aSpacing);
736
    }
737
    else {
738
        gdk_draw_layout_line(aSurface->GetDrawable(), gc,
739
                             x, y,
740
                             line);
741
    }
742
743
    g_object_unref(gc);
744
    g_object_unref(layout);
745
746
    //    printf("DrawString (char *)\n");
747
748
    return NS_OK;
749
}
750
751
nsresult
752
nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
753
                               nscoord aX, nscoord aY,
754
                               PRInt32 aFontID,
755
                               const nscoord* aSpacing,
756
                               nsRenderingContextGTK *aContext,
757
                               nsDrawingSurfaceGTK *aSurface)
758
{
759
    nsresult rv = NS_OK;
760
    int x = aX;
761
    int y = aY;
762
763
    aContext->UpdateGC();
764
    GdkGC *gc = aContext->GetGC();
765
766
    PangoLayout *layout = pango_layout_new(mPangoContext);
767
768
    gchar *text = g_utf16_to_utf8(aString, aLength,
769
                                  NULL, NULL, NULL);
770
771
    if (!text) {
772
#ifdef DEBUG
773
        NS_WARNING("nsFontMetricsPango::DrawString invalid unicode to follow");
774
        DUMP_PRUNICHAR(aString, aLength)
775
#endif
776
        rv = NS_ERROR_FAILURE;
777
        goto loser;
778
    }
779
780
    pango_layout_set_text(layout, text, strlen(text));
781
782
    aContext->GetTranMatrix()->TransformCoord(&x, &y);
783
784
    PangoLayoutLine *line;
785
    if (pango_layout_get_line_count(layout) != 1) {
786
        printf("Warning: more than one line!\n");
787
    }
788
    line = pango_layout_get_line(layout, 0);
789
790
    if (aSpacing && *aSpacing) {
791
        DrawStringSlowly(text, aString, aLength, aSurface->GetDrawable(),
792
                         gc, x, y, line, aSpacing);
793
    }
794
    else {
795
        gdk_draw_layout_line(aSurface->GetDrawable(), gc,
796
                             x, y,
797
                             line);
798
    }
799
800
 loser:
801
802
    g_free(text);
803
    g_object_unref(gc);
804
    g_object_unref(layout);
805
806
    //    printf("DrawString\n");
807
808
    return rv;
809
}
810
811
#ifdef MOZ_MATHML
812
nsresult
813
nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
814
                                       nsBoundingMetrics &aBoundingMetrics,
815
                                       nsRenderingContextGTK *aContext)
816
{
817
    printf("GetBoundingMetrics (char *)\n");
818
    return NS_ERROR_FAILURE;
819
}
820
821
nsresult
822
nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString,
823
                                       PRUint32 aLength,
824
                                       nsBoundingMetrics &aBoundingMetrics,
825
                                       PRInt32 *aFontID,
826
                                       nsRenderingContextGTK *aContext)
827
{
828
    nsresult rv = NS_OK;
829
    PangoLayout *layout = pango_layout_new(mPangoContext);
830
831
    gchar *text = g_utf16_to_utf8(aString, aLength,
832
                                  NULL, NULL, NULL);
833
834
    if (!text) {
835
#ifdef DEBUG
836
        NS_WARNING("nsFontMetricsPango::GetBoundingMetrics invalid unicode to follow");
837
        DUMP_PRUNICHAR(aString, aLength)
838
#endif
839
        aBoundingMetrics.leftBearing = 0;
840
        aBoundingMetrics.rightBearing = 0;
841
        aBoundingMetrics.width = 0;
842
        aBoundingMetrics.ascent = 0;
843
        aBoundingMetrics.descent = 0;
844
845
        rv = NS_ERROR_FAILURE;
846
        goto loser;
847
    }
848
849
    pango_layout_set_text(layout, text, strlen(text));
850
851
    // Get the logical extents
852
    PangoLayoutLine *line;
853
    if (pango_layout_get_line_count(layout) != 1) {
854
        printf("Warning: more than one line!\n");
855
    }
856
    line = pango_layout_get_line(layout, 0);
857
858
    // Get the ink extents
859
    PangoRectangle rect;
860
    pango_layout_line_get_extents(line, NULL, &rect);
861
862
    float P2T;
863
    P2T = mDeviceContext->DevUnitsToAppUnits();
864
865
    aBoundingMetrics.leftBearing =
866
        NSToCoordRound(rect.x / PANGO_SCALE * P2T);
867
    aBoundingMetrics.rightBearing =
868
        NSToCoordRound(rect.width / PANGO_SCALE * P2T);
869
    aBoundingMetrics.width = NSToCoordRound((rect.x + rect.width) / PANGO_SCALE * P2T);
870
    aBoundingMetrics.ascent = NSToCoordRound(rect.y / PANGO_SCALE * P2T);
871
    aBoundingMetrics.descent = NSToCoordRound(rect.height / PANGO_SCALE * P2T);
872
873
 loser:
874
    g_free(text);
875
    g_object_unref(layout);
876
877
    return rv;
878
}
879
880
#endif /* MOZ_MATHML */
881
882
GdkFont*
883
nsFontMetricsPango::GetCurrentGDKFont(void)
884
{
885
    return nsnull;
886
}
887
888
nsresult
889
nsFontMetricsPango::SetRightToLeftText(PRBool aIsRTL)
890
{
891
    if (aIsRTL) {
892
        if (!mRTLPangoContext) {
893
            mRTLPangoContext = pango_xft_get_context(GDK_DISPLAY(), 0);
894
            pango_context_set_base_dir(mRTLPangoContext, PANGO_DIRECTION_RTL);
895
896
            gdk_pango_context_set_colormap(mRTLPangoContext, gdk_rgb_get_cmap());
897
            pango_context_set_language(mRTLPangoContext, GetPangoLanguage(mLangGroup));
898
            pango_context_set_font_description(mRTLPangoContext, mPangoFontDesc);
899
        }
900
        mPangoContext = mRTLPangoContext;
901
    }
902
    else {
903
        mPangoContext = mLTRPangoContext;
904
    }
905
906
    mIsRTL = aIsRTL;
907
    return NS_OK;
908
}
909
910
/* static */
911
PRUint32
912
nsFontMetricsPango::GetHints(void)
913
{
914
    return (NS_RENDERING_HINT_BIDI_REORDERING |
915
            NS_RENDERING_HINT_ARABIC_SHAPING | 
916
            NS_RENDERING_HINT_FAST_MEASURE);
917
}
918
919
/* static */
920
nsresult
921
nsFontMetricsPango::FamilyExists(nsIDeviceContext *aDevice,
922
                                 const nsString &aName)
923
{
924
    if (!IsASCIIFontName(aName))
925
        return NS_ERROR_FAILURE;
926
927
    NS_ConvertUCS2toUTF8 name(aName);
928
929
    nsresult rv = NS_ERROR_FAILURE;
930
    PangoContext *context = pango_xft_get_context(GDK_DISPLAY(), 0);
931
    PangoFontFamily **familyList;
932
    int n;
933
934
    pango_context_list_families(context, &familyList, &n);
935
936
    for (int i=0; i < n; i++) {
937
        const char *tmpname = pango_font_family_get_name(familyList[i]);
938
        if (!Compare(nsDependentCString(tmpname), name,
939
                     nsCaseInsensitiveCStringComparator())) {
940
            rv = NS_OK;
941
            break;
942
        }
943
    }
944
945
    g_free(familyList);
946
    g_object_unref(context);
947
948
    return rv;
949
}
950
951
// Private Methods
952
953
nsresult
954
nsFontMetricsPango::RealizeFont(void)
955
{
956
    nsCString familyList;
957
    // Create and fill out the font description.
958
    mPangoFontDesc = pango_font_description_new();
959
960
    // Add CSS names - walk the list of fonts, adding the generic as
961
    // the last font
962
    for (int i=0; i < mFontList.Count(); ++i) {
963
        // if this was a generic name, break out of the loop since we
964
        // don't want to add it to the pattern yet
965
        if (mFontIsGeneric[i])
966
            break;;
967
968
        nsCString *familyName = mFontList.CStringAt(i);
969
        familyList.Append(familyName->get());
970
        familyList.Append(',');
971
    }
972
973
    // If there's a generic add a pref for the generic if there's one
974
    // set.
975
    if (mGenericFont && !mFont->systemFont) {
976
        nsCString name;
977
        name += "font.name.";
978
        name += mGenericFont->get();
979
        name += ".";
980
981
        nsString langGroup;
982
        mLangGroup->ToString(langGroup);
983
984
        name.AppendWithConversion(langGroup);
985
986
        nsCOMPtr<nsIPref> pref;
987
        pref = do_GetService(NS_PREF_CONTRACTID);
988
        if (pref) {
989
            nsresult rv;
990
            nsXPIDLCString value;
991
            rv = pref->GetCharPref(name.get(), getter_Copies(value));
992
993
            // we ignore prefs that have three hypens since they are X
994
            // style prefs.
995
            if (FFRECountHyphens(value) < 3) {
996
                nsCString tmpstr;
997
                tmpstr.Append(value);
998
999
                familyList.Append(tmpstr);
1000
                familyList.Append(',');
1001
            }
1002
        }
1003
    }
1004
1005
    // Add the generic if there is one.
1006
    if (mGenericFont && !mFont->systemFont) {
1007
        familyList.Append(mGenericFont->get());
1008
        familyList.Append(',');
1009
    }
1010
1011
    // Set the family
1012
    pango_font_description_set_family(mPangoFontDesc,
1013
                                      familyList.get());
1014
1015
    // Set the point size
1016
    pango_font_description_set_size(mPangoFontDesc,
1017
                                    (gint)(mPointSize * PANGO_SCALE));
1018
1019
    // Set the style
1020
    pango_font_description_set_style(mPangoFontDesc,
1021
                                     CalculateStyle(mFont->style));
1022
1023
    // Set the weight
1024
    pango_font_description_set_weight(mPangoFontDesc,
1025
                                      CalculateWeight(mFont->weight));
1026
1027
    // Now that we have the font description set up, create the
1028
    // context.
1029
    mLTRPangoContext = pango_xft_get_context(GDK_DISPLAY(), 0);
1030
    mPangoContext = mLTRPangoContext;
1031
1032
    // Set the color map so we can draw later.
1033
    gdk_pango_context_set_colormap(mPangoContext, gdk_rgb_get_cmap());
1034
1035
    // Set the pango language now that we have a context
1036
    pango_context_set_language(mPangoContext, GetPangoLanguage(mLangGroup));
1037
1038
    // And attach the font description to this context
1039
    pango_context_set_font_description(mPangoContext, mPangoFontDesc);
1040
1041
    return NS_OK;
1042
}
1043
1044
/* static */
1045
PRBool
1046
nsFontMetricsPango::EnumFontCallback(const nsString &aFamily,
1047
                                     PRBool aIsGeneric, void *aData)
1048
{
1049
    // make sure it's an ascii name, if not then return and continue
1050
    // enumerating
1051
    if (!IsASCIIFontName(aFamily))
1052
        return PR_TRUE;
1053
1054
    nsCAutoString name;
1055
    name.AssignWithConversion(aFamily.get());
1056
    ToLowerCase(name);
1057
    nsFontMetricsPango *metrics = (nsFontMetricsPango *)aData;
1058
    metrics->mFontList.AppendCString(name);
1059
    metrics->mFontIsGeneric.AppendElement((void *)aIsGeneric);
1060
    if (aIsGeneric) {
1061
        metrics->mGenericFont = 
1062
            metrics->mFontList.CStringAt(metrics->mFontList.Count() - 1);
1063
        return PR_FALSE; // stop processing
1064
    }
1065
1066
    return PR_TRUE; // keep processing
1067
}
1068
1069
/*
1070
 * This is only used when there's per-character spacing happening.
1071
 * Well, really it can be either line or character spacing but it's
1072
 * just turtles all the way down!
1073
 */
1074
1075
void
1076
nsFontMetricsPango::DrawStringSlowly(const gchar *aText,
1077
                                     const PRUnichar *aOrigString,
1078
                                     PRUint32 aLength,
1079
                                     GdkDrawable *aDrawable,
1080
                                     GdkGC *aGC, gint aX, gint aY,
1081
                                     PangoLayoutLine *aLine,
1082
                                     const nscoord *aSpacing)
1083
{
1084
    float app2dev;
1085
    app2dev = mDeviceContext->AppUnitsToDevUnits();
1086
    gint offset = 0;
1087
1088
    /*
1089
     * We walk the list of glyphs returned in each layout run,
1090
     * matching up the glyphs with the characters in the source text.
1091
     * We use the aSpacing argument to figure out where to place those
1092
     * glyphs.  It's important to note that since the string we're
1093
     * working with is in UTF-8 while the spacing argument assumes
1094
     * that offset will be part of the UTF-16 string.  Logical
1095
     * attributes in pango are in byte offsets in the UTF-8 string, so
1096
     * we need to store the offsets based on the UTF-8 string.
1097
     */
1098
    nscoord *utf8spacing = new nscoord[strlen(aText)];
1099
1100
    if (aOrigString) {
1101
        const gchar *curChar = aText;
1102
        bzero(utf8spacing, sizeof(nscoord) * strlen(aText));
1103
1104
        // Covert the utf16 spacing offsets to utf8 spacing offsets
1105
        for (PRUint32 curOffset=0; curOffset < aLength;
1106
             curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
1107
            utf8spacing[curChar - aText] = aSpacing[curOffset];
1108
1109
            if (IS_HIGH_SURROGATE(aOrigString[curOffset]))
1110
                curOffset++;
1111
        }
1112
    }
1113
    else {
1114
        memcpy(utf8spacing, aSpacing, (sizeof(nscoord *) * aLength));
1115
    }
1116
1117
    gint curRun = 0;
1118
1119
    for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
1120
         tmpList = tmpList->next, curRun++) {
1121
        PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data;
1122
        gint tmpOffset = 0;
1123
1124
        /*        printf("    Rendering run %d: \"%s\"\n", curRun,
1125
                  &aText[layoutRun->item->offset]); */
1126
1127
        for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) {
1128
            /* printf("glyph %d offset %d orig width %d new width %d\n", i,
1129
             *        layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset,
1130
             *        layoutRun->glyphs->glyphs[i].geometry.width,
1131
             *       (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset] * app2dev * PANGO_SCALE));
1132
             */
1133
            gint thisOffset = (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset]
1134
                                     * app2dev * PANGO_SCALE);
1135
            layoutRun->glyphs->glyphs[i].geometry.width = thisOffset;
1136
            tmpOffset += thisOffset;
1137
        }
1138
1139
        /*        printf("    rendering at X coord %d\n", aX + offset); */
1140
1141
        gdk_draw_glyphs(aDrawable, aGC, layoutRun->item->analysis.font,
1142
                        aX + (gint)(offset / PANGO_SCALE), aY, layoutRun->glyphs);
1143
1144
        offset += tmpOffset;
1145
    }
1146
1147
    delete[] utf8spacing;
1148
}
1149
1150
nsresult
1151
nsFontMetricsPango::GetTextDimensionsInternal(const gchar*        aString,
1152
                                              PRInt32             aLength,
1153
                                              PRInt32             aAvailWidth,
1154
                                              PRInt32*            aBreaks,
1155
                                              PRInt32             aNumBreaks,
1156
                                              nsTextDimensions&   aDimensions,
1157
                                              PRInt32&            aNumCharsFit,
1158
                                              nsTextDimensions&   aLastWordDimensions,
1159
                                              nsRenderingContextGTK *aContext)
1160
{
1161
    NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");
1162
1163
    // If we need to back up this state represents the last place
1164
    // we could break. We can use this to avoid remeasuring text
1165
    PRInt32 prevBreakState_BreakIndex = -1; // not known
1166
                                            // (hasn't been computed)
1167
    nscoord prevBreakState_Width = 0; // accumulated width to this point
1168
1169
    // Initialize OUT parameters
1170
    GetMaxAscent(aLastWordDimensions.ascent);
1171
    GetMaxDescent(aLastWordDimensions.descent);
1172
    aLastWordDimensions.width = -1;
1173
    aNumCharsFit = 0;
1174
1175
    // Iterate each character in the string and determine which font to use
1176
    nscoord width = 0;
1177
    PRInt32 start = 0;
1178
    nscoord aveCharWidth;
1179
    GetAveCharWidth(aveCharWidth);
1180
1181
    while (start < aLength) {
1182
        // Estimate how many characters will fit. Do that by
1183
        // diving the available space by the average character
1184
        // width. Make sure the estimated number of characters is
1185
        // at least 1
1186
        PRInt32 estimatedNumChars = 0;
1187
1188
        if (aveCharWidth > 0)
1189
            estimatedNumChars = (aAvailWidth - width) / aveCharWidth;
1190
1191
        if (estimatedNumChars < 1)
1192
            estimatedNumChars = 1;
1193
1194
        // Find the nearest break offset
1195
        PRInt32 estimatedBreakOffset = start + estimatedNumChars;
1196
        PRInt32 breakIndex;
1197
        nscoord numChars;
1198
1199
        // Find the nearest place to break that is less than or equal to
1200
        // the estimated break offset
1201
        if (aLength <= estimatedBreakOffset) {
1202
            // All the characters should fit
1203
            numChars = aLength - start;
1204
            breakIndex = aNumBreaks - 1;
1205
        } 
1206
        else {
1207
            breakIndex = prevBreakState_BreakIndex;
1208
            while (((breakIndex + 1) < aNumBreaks) &&
1209
                   (aBreaks[breakIndex + 1] <= estimatedBreakOffset)) {
1210
                ++breakIndex;
1211
            }
1212
1213
            if (breakIndex == prevBreakState_BreakIndex) {
1214
                ++breakIndex; // make sure we advanced past the
1215
                // previous break index
1216
            }
1217
1218
            numChars = aBreaks[breakIndex] - start;
1219
        }
1220
1221
        // Measure the text
1222
        nscoord twWidth = 0;
1223
        if ((1 == numChars) && (aString[start] == ' '))
1224
            GetSpaceWidth(twWidth);
1225
        else if (numChars > 0)
1226
            GetWidth(&aString[start], numChars, twWidth, aContext);
1227
1228
        // See if the text fits
1229
        PRBool  textFits = (twWidth + width) <= aAvailWidth;
1230
1231
        // If the text fits then update the width and the number of
1232
        // characters that fit
1233
        if (textFits) {
1234
            aNumCharsFit += numChars;
1235
            width += twWidth;
1236
            start += numChars;
1237
1238
            // This is a good spot to back up to if we need to so remember
1239
            // this state
1240
            prevBreakState_BreakIndex = breakIndex;
1241
            prevBreakState_Width = width;
1242
        }
1243
        else {
1244
            // See if we can just back up to the previous saved
1245
            // state and not have to measure any text
1246
            if (prevBreakState_BreakIndex > 0) {
1247
                // If the previous break index is just before the
1248
                // current break index then we can use it
1249
                if (prevBreakState_BreakIndex == (breakIndex - 1)) {
1250
                    aNumCharsFit = aBreaks[prevBreakState_BreakIndex];
1251
                    width = prevBreakState_Width;
1252
                    break;
1253
                }
1254
            }
1255
1256
            // We can't just revert to the previous break state
1257
            if (0 == breakIndex) {
1258
                // There's no place to back up to, so even though
1259
                // the text doesn't fit return it anyway
1260
                aNumCharsFit += numChars;
1261
                width += twWidth;
1262
                break;
1263
            }
1264
1265
            // Repeatedly back up until we get to where the text
1266
            // fits or we're all the way back to the first word
1267
            width += twWidth;
1268
            while ((breakIndex >= 1) && (width > aAvailWidth)) {
1269
                twWidth = 0;
1270
                start = aBreaks[breakIndex - 1];
1271
                numChars = aBreaks[breakIndex] - start;
1272
1273
                if ((1 == numChars) && (aString[start] == ' '))
1274
                    GetSpaceWidth(twWidth);
1275
                else if (numChars > 0)
1276
                    GetWidth(&aString[start], numChars, twWidth,
1277
                             aContext);
1278
                width -= twWidth;
1279
                aNumCharsFit = start;
1280
                breakIndex--;
1281
            }
1282
            break;
1283
        }
1284
    }
1285
1286
    aDimensions.width = width;
1287
    GetMaxAscent(aDimensions.ascent);
1288
    GetMaxDescent(aDimensions.descent);
1289
1290
    /*    printf("aDimensions %d %d %d aLastWordDimensions %d %d %d aNumCharsFit %d\n",
1291
           aDimensions.width, aDimensions.ascent, aDimensions.descent,
1292
           aLastWordDimensions.width, aLastWordDimensions.ascent, aLastWordDimensions.descent,
1293
           aNumCharsFit); */
1294
1295
    return NS_OK;
1296
}
1297
1298
/* static */
1299
PRBool
1300
IsASCIIFontName(const nsString& aName)
1301
{
1302
    PRUint32 len = aName.Length();
1303
    const PRUnichar* str = aName.get();
1304
    for (PRUint32 i = 0; i < len; i++) {
1305
        /*
1306
         * X font names are printable ASCII, ignore others (for now)
1307
         */
1308
        if ((str[i] < 0x20) || (str[i] > 0x7E)) {
1309
            return PR_FALSE;
1310
        }
1311
    }
1312
  
1313
    return PR_TRUE;
1314
}
1315
1316
/* static */
1317
int
1318
FFRECountHyphens (nsACString &aFFREName)
1319
{
1320
    int h = 0;
1321
    PRInt32 hyphen = 0;
1322
    while ((hyphen = aFFREName.FindChar('-', hyphen)) >= 0) {
1323
        ++h;
1324
        ++hyphen;
1325
    }
1326
    return h;
1327
}
1328
1329
/* static */
1330
PangoLanguage *
1331
GetPangoLanguage(nsIAtom *aLangGroup)
1332
{
1333
    // Find the FC lang group for this lang group
1334
    nsCAutoString cname;
1335
    aLangGroup->ToUTF8String(cname);
1336
1337
    // see if the lang group needs to be translated from mozilla's
1338
    // internal mapping into fontconfig's
1339
    const struct MozPangoLangGroup *langGroup;
1340
    langGroup = FindPangoLangGroup(cname);
1341
1342
    // if there's no lang group, just use the lang group as it was
1343
    // passed to us
1344
    //
1345
    // we're casting away the const here for the strings - should be
1346
    // safe.
1347
    if (!langGroup)
1348
        return pango_language_from_string(cname.get());
1349
    else if (langGroup->PangoLang) 
1350
        return pango_language_from_string(langGroup->PangoLang);
1351
1352
    return pango_language_from_string("en");
1353
}
1354
1355
/* static */
1356
const MozPangoLangGroup*
1357
FindPangoLangGroup (nsACString &aLangGroup)
1358
{
1359
    for (unsigned int i=0; i < NUM_PANGO_LANG_GROUPS; ++i) {
1360
        if (aLangGroup.Equals(MozPangoLangGroups[i].mozLangGroup,
1361
                              nsCaseInsensitiveCStringComparator())) {
1362
            return &MozPangoLangGroups[i];
1363
        }
1364
    }
1365
1366
    return nsnull;
1367
}
1368
1369
/* static */
1370
void
1371
FreeGlobals(void)
1372
{
1373
}
1374
1375
/* static */
1376
PangoStyle
1377
CalculateStyle(PRUint8 aStyle)
1378
{
1379
    switch(aStyle) {
1380
    case NS_FONT_STYLE_ITALIC:
1381
        return PANGO_STYLE_OBLIQUE;
1382
        break;
1383
    case NS_FONT_STYLE_OBLIQUE:
1384
        return PANGO_STYLE_OBLIQUE;
1385
        break;
1386
    }
1387
1388
    return PANGO_STYLE_NORMAL;
1389
}
1390
1391
/* static */
1392
PangoWeight
1393
CalculateWeight (PRUint16 aWeight)
1394
{
1395
    /*
1396
     * weights come in two parts crammed into one
1397
     * integer -- the "base" weight is weight / 100,
1398
     * the rest of the value is the "offset" from that
1399
     * weight -- the number of steps to move to adjust
1400
     * the weight in the list of supported font weights,
1401
     * this value can be negative or positive.
1402
     */
1403
    PRInt32 baseWeight = (aWeight + 50) / 100;
1404
    PRInt32 offset = aWeight - baseWeight * 100;
1405
1406
    /* clip weights to range 0 to 9 */
1407
    if (baseWeight < 0)
1408
        baseWeight = 0;
1409
    if (baseWeight > 9)
1410
        baseWeight = 9;
1411
1412
    /* Map from weight value to fcWeights index */
1413
    static int fcWeightLookup[10] = {
1414
        0, 0, 0, 0, 1, 1, 2, 3, 3, 4,
1415
    };
1416
1417
    PRInt32 fcWeight = fcWeightLookup[baseWeight];
1418
1419
    /*
1420
     * adjust by the offset value, make sure we stay inside the 
1421
     * fcWeights table
1422
     */
1423
    fcWeight += offset;
1424
1425
    if (fcWeight < 0)
1426
        fcWeight = 0;
1427
    if (fcWeight > 4)
1428
        fcWeight = 4;
1429
1430
    /* Map to final PANGO_WEIGHT value */
1431
    static int fcWeights[5] = {
1432
        349,
1433
        499,
1434
        649,
1435
        749,
1436
        999
1437
    };
1438
1439
    return (PangoWeight)fcWeights[fcWeight];
1440
}
1441
1442
/* static */
1443
nsresult
1444
EnumFontsPango(nsIAtom* aLangGroup, const char* aGeneric,
1445
               PRUint32* aCount, PRUnichar*** aResult)
1446
{
1447
    FcPattern   *pat = NULL;
1448
    FcObjectSet *os  = NULL;
1449
    FcFontSet   *fs  = NULL;
1450
    nsresult     rv  = NS_ERROR_FAILURE;
1451
1452
    PRUnichar **array = NULL;
1453
    PRUint32    narray = 0;
1454
    PRInt32     serif = 0, sansSerif = 0, monospace = 0, nGenerics;
1455
1456
    *aCount = 0;
1457
    *aResult = nsnull;
1458
1459
    pat = FcPatternCreate();
1460
    if (!pat)
1461
        goto end;
1462
1463
    os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, 0);
1464
    if (!os)
1465
        goto end;
1466
1467
    // take the pattern and add the lang group to it
1468
    if (aLangGroup)
1469
        AddLangGroup(pat, aLangGroup);
1470
1471
    // get the font list
1472
    fs = FcFontList(0, pat, os);
1473
1474
    if (!fs)
1475
        goto end;
1476
1477
    if (!fs->nfont) {
1478
        rv = NS_OK;
1479
        goto end;
1480
    }
1481
1482
    // Fontconfig supports 3 generic fonts, "serif", "sans-serif", and
1483
    // "monospace", slightly different from CSS's 5.
1484
    if (!aGeneric)
1485
        serif = sansSerif = monospace = 1;
1486
    else if (!strcmp(aGeneric, "serif"))
1487
        serif = 1;
1488
    else if (!strcmp(aGeneric, "sans-serif"))
1489
        sansSerif = 1;
1490
    else if (!strcmp(aGeneric, "monospace"))
1491
        monospace = 1;
1492
    else if (!strcmp(aGeneric, "cursive") || !strcmp(aGeneric, "fantasy"))
1493
        serif = sansSerif =  1;
1494
    else
1495
        NS_NOTREACHED("unexpected generic family");
1496
    nGenerics = serif + sansSerif + monospace;
1497
1498
    array = NS_STATIC_CAST(PRUnichar **,
1499
               nsMemory::Alloc((fs->nfont + nGenerics) * sizeof(PRUnichar *)));
1500
    if (!array)
1501
        goto end;
1502
1503
    if (serif) {
1504
        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("serif"));
1505
        if (!name)
1506
            goto end;
1507
        array[narray++] = name;
1508
    }
1509
1510
    if (sansSerif) {
1511
        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("sans-serif"));
1512
        if (!name)
1513
            goto end;
1514
        array[narray++] = name;
1515
    }
1516
1517
    if (monospace) {
1518
        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("monospace"));
1519
        if (!name)
1520
            goto end;
1521
        array[narray++] = name;
1522
    }
1523
1524
    for (int i=0; i < fs->nfont; ++i) {
1525
        char *family;
1526
        PRUnichar *name;
1527
1528
        // if there's no family, just move to the next iteration
1529
        if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
1530
                                (FcChar8 **) &family) != FcResultMatch) {
1531
            continue;
1532
        }
1533
1534
        name = NS_STATIC_CAST(PRUnichar *,
1535
                              nsMemory::Alloc ((strlen (family) + 1)
1536
                                               * sizeof (PRUnichar)));
1537
1538
        if (!name)
1539
            goto end;
1540
1541
        PRUnichar *r = name;
1542
        for (char *f = family; *f; ++f)
1543
            *r++ = *f;
1544
        *r = '\0';
1545
1546
        array[narray++] = name;
1547
    }
1548
1549
    NS_QuickSort(array + nGenerics, narray - nGenerics, sizeof (PRUnichar*),
1550
                 CompareFontNames, nsnull);
1551
1552
    *aCount = narray;
1553
    if (narray)
1554
        *aResult = array;
1555
    else
1556
        nsMemory::Free(array);
1557
1558
    rv = NS_OK;
1559
1560
 end:
1561
    if (NS_FAILED(rv) && array) {
1562
        while (narray)
1563
            nsMemory::Free (array[--narray]);
1564
        nsMemory::Free (array);
1565
    }
1566
    if (pat)
1567
        FcPatternDestroy(pat);
1568
    if (os)
1569
        FcObjectSetDestroy(os);
1570
    if (fs)
1571
        FcFontSetDestroy(fs);
1572
1573
    return rv;
1574
}
1575
1576
/* static */
1577
int
1578
CompareFontNames (const void* aArg1, const void* aArg2, void* aClosure)
1579
{
1580
    const PRUnichar* str1 = *((const PRUnichar**) aArg1);
1581
    const PRUnichar* str2 = *((const PRUnichar**) aArg2);
1582
1583
    return nsCRT::strcmp(str1, str2);
1584
}
1585
1586
1587
// nsFontEnumeratorPango class
1588
1589
nsFontEnumeratorPango::nsFontEnumeratorPango()
1590
{
1591
}
1592
1593
NS_IMPL_ISUPPORTS1(nsFontEnumeratorPango, nsIFontEnumerator)
1594
1595
NS_IMETHODIMP
1596
nsFontEnumeratorPango::EnumerateAllFonts(PRUint32 *aCount,
1597
                                         PRUnichar ***aResult)
1598
{
1599
    NS_ENSURE_ARG_POINTER(aResult);
1600
    *aResult = nsnull;
1601
    NS_ENSURE_ARG_POINTER(aCount);
1602
    *aCount = 0;
1603
1604
    return EnumFontsPango(nsnull, nsnull, aCount, aResult);
1605
}
1606
1607
NS_IMETHODIMP
1608
nsFontEnumeratorPango::EnumerateFonts(const char *aLangGroup,
1609
                                      const char *aGeneric,
1610
                                      PRUint32 *aCount,
1611
                                      PRUnichar ***aResult)
1612
{
1613
    NS_ENSURE_ARG_POINTER(aResult);
1614
    *aResult = nsnull;
1615
    NS_ENSURE_ARG_POINTER(aCount);
1616
    *aCount = 0;
1617
1618
    // aLangGroup=null or ""  means any (i.e., don't care)
1619
    // aGeneric=null or ""  means any (i.e, don't care)
1620
    nsCOMPtr<nsIAtom> langGroup;
1621
    if (aLangGroup && *aLangGroup)
1622
        langGroup = do_GetAtom(aLangGroup);
1623
    const char* generic = nsnull;
1624
    if (aGeneric && *aGeneric)
1625
        generic = aGeneric;
1626
1627
    return EnumFontsPango(langGroup, generic, aCount, aResult);
1628
}
1629
1630
NS_IMETHODIMP
1631
nsFontEnumeratorPango::HaveFontFor(const char *aLangGroup,
1632
                                   PRBool *aResult)
1633
{
1634
    NS_ENSURE_ARG_POINTER(aResult);
1635
    *aResult = PR_FALSE;
1636
    NS_ENSURE_ARG_POINTER(aLangGroup);
1637
1638
    *aResult = PR_TRUE; // always return true for now.
1639
    // Finish me - ftang
1640
    return NS_OK;
1641
}
1642
1643
NS_IMETHODIMP
1644
nsFontEnumeratorPango::GetDefaultFont(const char *aLangGroup,
1645
                                      const char *aGeneric,
1646
                                      PRUnichar **aResult)
1647
{
1648
    NS_ENSURE_ARG_POINTER(aResult);
1649
    *aResult = nsnull;
1650
1651
    // Have a look at nsFontEnumeratorXft::GetDefaultFont for some
1652
    // possible code for this function.
1653
1654
    return NS_OK;
1655
}
1656
1657
NS_IMETHODIMP
1658
nsFontEnumeratorPango::UpdateFontList(PRBool *_retval)
1659
{
1660
    *_retval = PR_FALSE; // always return false for now
1661
    return NS_OK;
1662
}
(-)mozilla/gfx/src/gtk/nsRenderingContextGTK.h.foo (+2 lines)
Lines 194-199 Link Here
194
                               const nsRect &aDestBounds, PRUint32 aCopyFlags);
194
                               const nsRect &aDestBounds, PRUint32 aCopyFlags);
195
  NS_IMETHOD RetrieveCurrentNativeGraphicData(PRUint32 * ngd);
195
  NS_IMETHOD RetrieveCurrentNativeGraphicData(PRUint32 * ngd);
196
196
197
  NS_IMETHOD SetRightToLeftText(PRBool aIsRTL);
198
197
  NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint);
199
  NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint);
198
  NS_IMETHOD DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect);
200
  NS_IMETHOD DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect);
199
201
(-) (+278 lines)
Added Link Here
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* vim:expandtab:shiftwidth=4:tabstop=4:
3
 */
4
/* ***** BEGIN LICENSE BLOCK *****
5
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
 *
7
 * The contents of this file are subject to the Mozilla Public License Version
8
 * 1.1 (the "License"); you may not use this file except in compliance with
9
 * the License. You may obtain a copy of the License at
10
 * http://www.mozilla.org/MPL/
11
 *
12
 * Software distributed under the License is distributed on an "AS IS" basis,
13
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
 * for the specific language governing rights and limitations under the
15
 * License.
16
 *
17
 * The Original Code is mozilla.org code.
18
 *
19
 * The Initial Developer of the Original Code Christopher Blizzard
20
 * <blizzard@mozilla.org>.  Portions created by the Initial Developer
21
 * are Copyright (C) 2002 the Initial Developer. All Rights Reserved.
22
 *
23
 * Contributor(s):
24
 *
25
 * Alternatively, the contents of this file may be used under the terms of
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
29
 * of those above. If you wish to allow use of your version of this file only
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
31
 * use your version of this file under the terms of the MPL, indicate your
32
 * decision by deleting the provisions above and replace them with the notice
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
34
 * the provisions above, a recipient may use your version of this file under
35
 * the terms of any one of the MPL, the GPL or the LGPL.
36
 *
37
 * ***** END LICENSE BLOCK ***** */
38
39
#include "nsIFontMetrics.h"
40
#include "nsIFontEnumerator.h"
41
#include "nsCRT.h"
42
#include "nsIAtom.h"
43
#include "nsString.h"
44
#include "nsVoidArray.h"
45
#include "nsIFontMetricsGTK.h"
46
47
#include <pango/pango.h>
48
49
class nsFontMetricsPango : public nsIFontMetricsGTK
50
{
51
public:
52
    nsFontMetricsPango();
53
    virtual ~nsFontMetricsPango();
54
55
    NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
56
57
    // nsISupports
58
    NS_DECL_ISUPPORTS
59
60
    // nsIFontMetrics
61
    NS_IMETHOD  Init                 (const nsFont& aFont, nsIAtom* aLangGroup,
62
                                      nsIDeviceContext *aContext);
63
    NS_IMETHOD  Destroy();
64
    NS_IMETHOD  GetFont              (const nsFont *&aFont);
65
    NS_IMETHOD  GetLangGroup         (nsIAtom** aLangGroup);
66
    NS_IMETHOD  GetFontHandle        (nsFontHandle &aHandle);
67
68
    NS_IMETHOD  GetXHeight           (nscoord& aResult)
69
                                     { aResult = mXHeight; return NS_OK; };
70
71
    NS_IMETHOD GetSuperscriptOffset  (nscoord& aResult)
72
                                     { aResult = mSuperscriptOffset;
73
                                       return NS_OK; };
74
75
    NS_IMETHOD GetSubscriptOffset    (nscoord& aResult)
76
                                     { aResult = mSubscriptOffset;
77
                                       return NS_OK; };
78
                              
79
    NS_IMETHOD GetStrikeout          (nscoord& aOffset, nscoord& aSize)
80
                                     { aOffset = mStrikeoutOffset;
81
                                       aSize = mStrikeoutSize; 
82
                                       return NS_OK; };
83
84
    NS_IMETHOD GetUnderline          (nscoord& aOffset, nscoord& aSize)
85
                                     { aOffset = mUnderlineOffset;
86
                                       aSize = mUnderlineSize; 
87
                                       return NS_OK; };
88
89
    NS_IMETHOD GetHeight             (nscoord &aHeight)
90
                                     { aHeight = mMaxHeight; 
91
                                       return NS_OK; };
92
93
    NS_IMETHOD GetNormalLineHeight   (nscoord &aHeight)
94
                                     { aHeight = mEmHeight + mLeading;
95
                                       return NS_OK; };
96
97
    NS_IMETHOD GetLeading            (nscoord &aLeading)
98
                                     { aLeading = mLeading; 
99
                                       return NS_OK; };
100
101
    NS_IMETHOD GetEmHeight           (nscoord &aHeight)
102
                                     { aHeight = mEmHeight; 
103
                                       return NS_OK; };
104
105
    NS_IMETHOD GetEmAscent           (nscoord &aAscent)
106
                                     { aAscent = mEmAscent;
107
                                       return NS_OK; };
108
109
    NS_IMETHOD GetEmDescent          (nscoord &aDescent)
110
                                     { aDescent = mEmDescent;
111
                                       return NS_OK; };
112
113
    NS_IMETHOD GetMaxHeight          (nscoord &aHeight)
114
                                     { aHeight = mMaxHeight;
115
                                       return NS_OK; };
116
117
    NS_IMETHOD GetMaxAscent          (nscoord &aAscent)
118
                                     { aAscent = mMaxAscent;
119
                                       return NS_OK; };
120
121
    NS_IMETHOD GetMaxDescent         (nscoord &aDescent)
122
                                     { aDescent = mMaxDescent;
123
                                       return NS_OK; };
124
125
    NS_IMETHOD GetMaxAdvance         (nscoord &aAdvance)
126
                                     { aAdvance = mMaxAdvance;
127
                                       return NS_OK; };
128
129
    NS_IMETHOD GetSpaceWidth         (nscoord &aSpaceCharWidth)
130
                                     { aSpaceCharWidth = mSpaceWidth;
131
                                       return NS_OK; };
132
133
    NS_IMETHOD GetAveCharWidth       (nscoord &aAveCharWidth)
134
                                     { aAveCharWidth = mAveCharWidth;
135
                                       return NS_OK; };
136
137
    // nsIFontMetricsGTK (calls from the font rendering layer)
138
    virtual nsresult GetWidth(const char* aString, PRUint32 aLength,
139
                              nscoord& aWidth,
140
                              nsRenderingContextGTK *aContext);
141
    virtual nsresult GetWidth(const PRUnichar* aString, PRUint32 aLength,
142
                              nscoord& aWidth, PRInt32 *aFontID,
143
                              nsRenderingContextGTK *aContext);
144
145
    virtual nsresult GetTextDimensions(const PRUnichar* aString,
146
                                       PRUint32 aLength,
147
                                       nsTextDimensions& aDimensions, 
148
                                       PRInt32* aFontID,
149
                                       nsRenderingContextGTK *aContext);
150
    virtual nsresult GetTextDimensions(const char*         aString,
151
                                       PRInt32             aLength,
152
                                       PRInt32             aAvailWidth,
153
                                       PRInt32*            aBreaks,
154
                                       PRInt32             aNumBreaks,
155
                                       nsTextDimensions&   aDimensions,
156
                                       PRInt32&            aNumCharsFit,
157
                                       nsTextDimensions&   aLastWordDimensions,
158
                                       PRInt32*            aFontID,
159
                                       nsRenderingContextGTK *aContext);
160
    virtual nsresult GetTextDimensions(const PRUnichar*    aString,
161
                                       PRInt32             aLength,
162
                                       PRInt32             aAvailWidth,
163
                                       PRInt32*            aBreaks,
164
                                       PRInt32             aNumBreaks,
165
                                       nsTextDimensions&   aDimensions,
166
                                       PRInt32&            aNumCharsFit,
167
                                       nsTextDimensions&   aLastWordDimensions,
168
                                       PRInt32*            aFontID,
169
                                       nsRenderingContextGTK *aContext);
170
171
    virtual nsresult DrawString(const char *aString, PRUint32 aLength,
172
                                nscoord aX, nscoord aY,
173
                                const nscoord* aSpacing,
174
                                nsRenderingContextGTK *aContext,
175
                                nsDrawingSurfaceGTK *aSurface);
176
    virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength,
177
                                nscoord aX, nscoord aY,
178
                                PRInt32 aFontID,
179
                                const nscoord* aSpacing,
180
                                nsRenderingContextGTK *aContext,
181
                                nsDrawingSurfaceGTK *aSurface);
182
183
#ifdef MOZ_MATHML
184
    virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength,
185
                                        nsBoundingMetrics &aBoundingMetrics,
186
                                        nsRenderingContextGTK *aContext);
187
    virtual nsresult GetBoundingMetrics(const PRUnichar *aString,
188
                                        PRUint32 aLength,
189
                                        nsBoundingMetrics &aBoundingMetrics,
190
                                        PRInt32 *aFontID,
191
                                        nsRenderingContextGTK *aContext);
192
#endif /* MOZ_MATHML */
193
194
    virtual GdkFont* GetCurrentGDKFont(void);
195
196
    virtual nsresult SetRightToLeftText(PRBool aIsRTL);
197
198
    // get hints for the font
199
    static PRUint32    GetHints     (void);
200
201
    // drawing surface methods
202
    static nsresult FamilyExists    (nsIDeviceContext *aDevice,
203
                                     const nsString &aName);
204
205
private:
206
207
    // generic font metrics class bits
208
    nsCStringArray       mFontList;
209
    nsAutoVoidArray      mFontIsGeneric;
210
211
    nsIDeviceContext    *mDeviceContext;
212
    nsCOMPtr<nsIAtom>    mLangGroup;
213
    nsCString           *mGenericFont;
214
    nsFont              *mFont;
215
    float                mPointSize;
216
217
    nsCAutoString        mDefaultFont;
218
219
    // Pango-related items
220
    PangoFontDescription *mPangoFontDesc;
221
    PangoContext         *mPangoContext;
222
    PangoContext         *mLTRPangoContext;
223
    PangoContext         *mRTLPangoContext;
224
    PangoAttrList        *mPangoAttrList;
225
    PRBool                mIsRTL;
226
227
    // Cached font metrics
228
    nscoord                  mXHeight;
229
    nscoord                  mSuperscriptOffset;
230
    nscoord                  mSubscriptOffset;
231
    nscoord                  mStrikeoutOffset;
232
    nscoord                  mStrikeoutSize;
233
    nscoord                  mUnderlineOffset;
234
    nscoord                  mUnderlineSize;
235
    nscoord                  mMaxHeight;
236
    nscoord                  mLeading;
237
    nscoord                  mEmHeight;
238
    nscoord                  mEmAscent;
239
    nscoord                  mEmDescent;
240
    nscoord                  mMaxAscent;
241
    nscoord                  mMaxDescent;
242
    nscoord                  mMaxAdvance;
243
    nscoord                  mSpaceWidth;
244
    nscoord                  mAveCharWidth;
245
246
    // Private methods
247
    nsresult RealizeFont(void);
248
    nsresult CacheFontMetrics(void);
249
250
    static PRBool EnumFontCallback(const nsString &aFamily,
251
                                   PRBool aIsGeneric, void *aData);
252
253
    void     DrawStringSlowly(const gchar *aText,
254
                              const PRUnichar *aOrigString,
255
                              PRUint32 aLength,
256
                              GdkDrawable *aDrawable,
257
                              GdkGC *aGC, gint aX, gint aY,
258
                              PangoLayoutLine *aLine,
259
                              const nscoord *aSpacing);
260
261
    nsresult GetTextDimensionsInternal(const gchar*        aString,
262
                                       PRInt32             aLength,
263
                                       PRInt32             aAvailWidth,
264
                                       PRInt32*            aBreaks,
265
                                       PRInt32             aNumBreaks,
266
                                       nsTextDimensions&   aDimensions,
267
                                       PRInt32&            aNumCharsFit,
268
                                       nsTextDimensions&   aLastWordDimensions,
269
                                       nsRenderingContextGTK *aContext);
270
};
271
272
class nsFontEnumeratorPango : public nsIFontEnumerator
273
{
274
public:
275
    nsFontEnumeratorPango();
276
    NS_DECL_ISUPPORTS
277
    NS_DECL_NSIFONTENUMERATOR
278
};
(-)mozilla/gfx/src/gtk/nsFontMetricsUtils.h.foo (-1 / +4 lines)
Lines 42-50 Link Here
42
extern PRUint32 NS_FontMetricsGetHints    (void);
42
extern PRUint32 NS_FontMetricsGetHints    (void);
43
extern nsresult NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice,
43
extern nsresult NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice,
44
                                           const nsString &aName);
44
                                           const nsString &aName);
45
46
#ifdef MOZ_ENABLE_XFT
45
#ifdef MOZ_ENABLE_XFT
47
extern PRBool   NS_IsXftEnabled(void);
46
extern PRBool   NS_IsXftEnabled(void);
48
#endif
47
#endif
49
48
49
#ifdef MOZ_ENABLE_PANGO
50
extern PRBool   NS_IsPangoEnabled(void);
51
#endif
52
50
#endif /* __nsFontMetricsUtils_h */
53
#endif /* __nsFontMetricsUtils_h */
(-)mozilla/gfx/src/gtk/nsIFontMetricsGTK.h.foo (+3 lines)
Lines 121-126 Link Here
121
    // particular handle.
121
    // particular handle.
122
    virtual GdkFont* GetCurrentGDKFont(void) = 0;
122
    virtual GdkFont* GetCurrentGDKFont(void) = 0;
123
123
124
    // Set the direction of the text rendering
125
    virtual nsresult SetRightToLeftText(PRBool aIsRTL) = 0;
126
124
};
127
};
125
128
126
#endif /* __nsIFontMetricsGTK_h */
129
#endif /* __nsIFontMetricsGTK_h */
(-)mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp.foo (+8 lines)
Lines 524-529 Link Here
524
524
525
  values.foreground.pixel =
525
  values.foreground.pixel =
526
    gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(mCurrentColor));
526
    gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(mCurrentColor));
527
  values.foreground.red = (NS_GET_R(mCurrentColor) << 8) | NS_GET_R(mCurrentColor);
528
  values.foreground.green = (NS_GET_G(mCurrentColor) << 8) | NS_GET_G(mCurrentColor);
529
  values.foreground.blue = (NS_GET_B(mCurrentColor) << 8) | NS_GET_B(mCurrentColor);
527
  valuesMask = GDK_GC_FOREGROUND;
530
  valuesMask = GDK_GC_FOREGROUND;
528
531
529
#ifdef MOZ_ENABLE_COREXFONTS
532
#ifdef MOZ_ENABLE_COREXFONTS
Lines 1438-1443 Link Here
1438
1441
1439
#endif /* MOZ_MATHML */
1442
#endif /* MOZ_MATHML */
1440
1443
1444
NS_IMETHODIMP nsRenderingContextGTK::SetRightToLeftText(PRBool aIsRTL)
1445
{
1446
  return mFontMetrics->SetRightToLeftText(aIsRTL);
1447
}
1448
1441
NS_IMETHODIMP nsRenderingContextGTK::DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint)
1449
NS_IMETHODIMP nsRenderingContextGTK::DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint)
1442
{
1450
{
1443
  UpdateGC();
1451
  UpdateGC();
(-)mozilla/gfx/src/gtk/nsGCCache.cpp.foo (-69 / +13 lines)
Lines 232-329 Link Here
232
  // We have old GC, reuse it and check what
232
  // We have old GC, reuse it and check what
233
  // we have to change
233
  // we have to change
234
234
235
  XGCValues xvalues;
235
  GdkGCValues xvalues;
236
  unsigned long xvalues_mask=0;
236
  int xvalues_mask = 0;
237
237
238
  if (entry->clipRegion) {
238
  if (entry->clipRegion) {
239
    // set it to none here and then set the clip region with
239
    // set it to none here and then set the clip region with
240
    // gdk_gc_set_clip_region in GetGC()
240
    // gdk_gc_set_clip_region in GetGC()
241
    xvalues.clip_mask = None;
241
    xvalues.clip_mask = None;
242
    xvalues_mask |= GCClipMask;
242
    xvalues_mask |= GDK_GC_CLIP_MASK;
243
    gdk_region_destroy(entry->clipRegion);
243
    gdk_region_destroy(entry->clipRegion);
244
    entry->clipRegion = NULL;
244
    entry->clipRegion = NULL;
245
  }
245
  }
246
246
247
  if (entry->gcv.foreground.pixel != gcv->foreground.pixel) {
247
  if (entry->gcv.foreground.pixel != gcv->foreground.pixel) {
248
    xvalues.foreground = gcv->foreground.pixel;
248
    xvalues.foreground.pixel = gcv->foreground.pixel;
249
    xvalues_mask |= GCForeground;
249
    xvalues_mask |= GDK_GC_FOREGROUND;
250
  }
250
  }
251
251
252
  if (entry->gcv.function != gcv->function) {
252
  if (entry->gcv.function != gcv->function) {
253
    switch (gcv->function) {
253
    xvalues.function = gcv->function;
254
    case GDK_COPY:
254
    xvalues_mask |= GDK_GC_FUNCTION;
255
      xvalues.function = GXcopy;
256
      break;
257
    case GDK_INVERT:
258
      xvalues.function = GXinvert;
259
      break;
260
    case GDK_XOR:
261
      xvalues.function = GXxor;
262
      break;
263
    case GDK_CLEAR:
264
      xvalues.function = GXclear;
265
      break;
266
    case GDK_AND:
267
      xvalues.function = GXand;
268
      break;
269
    case GDK_AND_REVERSE:
270
      xvalues.function = GXandReverse;
271
      break;
272
    case GDK_AND_INVERT:
273
      xvalues.function = GXandInverted;
274
      break;
275
    case GDK_NOOP:
276
      xvalues.function = GXnoop;
277
      break;
278
    case GDK_OR:
279
      xvalues.function = GXor;
280
      break;
281
    case GDK_EQUIV:
282
      xvalues.function = GXequiv;
283
      break;
284
    case GDK_OR_REVERSE:
285
      xvalues.function = GXorReverse;
286
      break;
287
    case GDK_COPY_INVERT:
288
      xvalues.function = GXcopyInverted;
289
      break;
290
    case GDK_OR_INVERT:
291
      xvalues.function = GXorInverted;
292
      break;
293
    case GDK_NAND:
294
      xvalues.function = GXnand;
295
      break;
296
    case GDK_SET:
297
      xvalues.function = GXset;
298
      break;
299
    }
300
    xvalues_mask |= GCFunction;
301
  }
255
  }
302
256
303
  if(entry->gcv.font != gcv->font && flags & GDK_GC_FONT) {
257
  if(entry->gcv.font != gcv->font && flags & GDK_GC_FONT) {
304
    xvalues.font =  ((XFontStruct *)GDK_FONT_XFONT(gcv->font))->fid;
258
    xvalues.font = gcv->font;
305
    xvalues_mask |= GCFont;
259
    xvalues_mask |= GDK_GC_FONT;
306
  }
260
  }
307
261
308
  if (entry->gcv.line_style != gcv->line_style) {
262
  if (entry->gcv.line_style != gcv->line_style) {
309
    switch (gcv->line_style) {
263
    xvalues.line_style = gcv->line_style;
310
    case GDK_LINE_SOLID:
264
    xvalues_mask |= GDK_GC_LINE_STYLE;
311
      xvalues.line_style = LineSolid;
312
      break;
313
    case GDK_LINE_ON_OFF_DASH:
314
      xvalues.line_style = LineOnOffDash;
315
      break;
316
    case GDK_LINE_DOUBLE_DASH:
317
      xvalues.line_style = LineDoubleDash;
318
      break;
319
    }
320
    xvalues_mask |= GCLineStyle;
321
  }
265
  }
322
266
323
  if (xvalues_mask != 0) {
267
  if (xvalues_mask != 0) {
324
    XChangeGC(GDK_GC_XDISPLAY(entry->gc), GDK_GC_XGC(entry->gc),
268
    gdk_gc_set_values(entry->gc, &xvalues, (GdkGCValuesMask)xvalues_mask);
325
              xvalues_mask, &xvalues);
326
  }
269
  }
270
327
  entry->flags = flags;
271
  entry->flags = flags;
328
  entry->gcv = *gcv;
272
  entry->gcv = *gcv;
329
}
273
}
(-)mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp.foo (+6 lines)
Lines 4600-4605 Link Here
4600
  return mCurrentFont->GetGDKFont();
4600
  return mCurrentFont->GetGDKFont();
4601
}
4601
}
4602
4602
4603
nsresult
4604
nsFontMetricsGTK::SetRightToLeftText(PRBool aIsRTL)
4605
{
4606
    return NS_OK;
4607
}
4608
4603
PR_BEGIN_EXTERN_C
4609
PR_BEGIN_EXTERN_C
4604
static int
4610
static int
4605
CompareSizes(const void* aArg1, const void* aArg2, void *data)
4611
CompareSizes(const void* aArg1, const void* aArg2, void *data)
(-)mozilla/gfx/src/gtk/nsFontMetricsXft.h.foo (+2 lines)
Lines 202-207 Link Here
202
202
203
    virtual GdkFont* GetCurrentGDKFont(void);
203
    virtual GdkFont* GetCurrentGDKFont(void);
204
204
205
    virtual nsresult SetRightToLeftText(PRBool aIsRTL);
206
205
    // get hints for the font
207
    // get hints for the font
206
    static PRUint32    GetHints  (void);
208
    static PRUint32    GetHints  (void);
207
209
(-)mozilla/gfx/src/gtk/nsFontMetricsGTK.h.foo (+2 lines)
Lines 344-349 Link Here
344
344
345
  virtual GdkFont* GetCurrentGDKFont(void);
345
  virtual GdkFont* GetCurrentGDKFont(void);
346
346
347
  virtual nsresult SetRightToLeftText(PRBool aIsRTL);
348
347
  static nsresult FamilyExists(nsIDeviceContext *aDevice, const nsString& aName);
349
  static nsresult FamilyExists(nsIDeviceContext *aDevice, const nsString& aName);
348
  static PRUint32 GetHints(void);
350
  static PRUint32 GetHints(void);
349
351
(-)mozilla/configure.in.foo (+28 lines)
Lines 3429-3434 Link Here
3429
AC_SUBST(MOZ_XFT_LIBS)
3429
AC_SUBST(MOZ_XFT_LIBS)
3430
3430
3431
dnl ========================================================
3431
dnl ========================================================
3432
dnl = pango font rendering
3433
dnl ========================================================
3434
MOZ_ARG_ENABLE_BOOL(pango,
3435
[  --enable-pango          Enable Pango font rendering support],
3436
    MOZ_ENABLE_PANGO=1,
3437
    MOZ_ENABLE_PANGO=)
3438
3439
if test "$MOZ_ENABLE_PANGO"
3440
then
3441
    AC_DEFINE(MOZ_ENABLE_PANGO)
3442
    PKG_CHECK_MODULES(MOZ_PANGO, pango >= 1.5.0)
3443
3444
    dnl Make sure that the pango version is _actually_ new enough
3445
    _SAVE_CFLAGS=$CFLAGS
3446
    _SAVE_LDFLAGS=$LDFLAGS
3447
    CFLAGS="$MOZ_PANGO_CFLAGS $CFLAGS"
3448
    LDFLAGS="$MOZ_PANGO_LIBS $LDFLAGS"
3449
    AC_CHECK_LIB(pangoft2-1.0, pango_fc_font_map_add_decoder_find_func,,
3450
                 AC_MSG_ERROR([Your Pango is too old. Sorry.]))
3451
    CFLAGS=$_SAVE_CFLAGS
3452
    LDFLAGS=$_SAVE_LDFLAGS
3453
3454
    AC_SUBST(MOZ_ENABLE_PANGO)
3455
    AC_SUBST(MOZ_PANGO_CFLAGS)
3456
    AC_SUBST(MOZ_PANGO_LIBS)
3457
fi
3458
3459
dnl ========================================================
3432
dnl = disabling x11 core support, enabled by default
3460
dnl = disabling x11 core support, enabled by default
3433
dnl ========================================================
3461
dnl ========================================================
3434
MOZ_ENABLE_COREXFONTS=${MOZ_ENABLE_COREXFONTS-1}
3462
MOZ_ENABLE_COREXFONTS=${MOZ_ENABLE_COREXFONTS-1}

Return to bug 75404