Magellan Linux

Contents of /trunk/mozilla-firefox/patches/mozilla-firefox-1.0.7-pango-render.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 153 - (show annotations) (download)
Tue May 8 20:52:56 2007 UTC (17 years ago) by niro
File size: 101086 byte(s)
-import

1 --- mozilla/config/autoconf.mk.in.foo 2004-03-20 21:31:17.000000000 -0500
2 +++ mozilla/config/autoconf.mk.in 2004-10-18 22:49:40.000000000 -0400
3 @@ -376,6 +376,10 @@
4 MOZ_XFT_LIBS = @MOZ_XFT_LIBS@
5 MOZ_ENABLE_COREXFONTS = @MOZ_ENABLE_COREXFONTS@
6
7 +MOZ_ENABLE_PANGO = @MOZ_ENABLE_PANGO@
8 +MOZ_PANGO_CFLAGS = @MOZ_PANGO_CFLAGS@
9 +MOZ_PANGO_LIBS = @MOZ_PANGO_LIBS@
10 +
11 MOZ_EXTRA_X11CONVERTERS = @MOZ_EXTRA_X11CONVERTERS@
12
13 MOZ_ENABLE_XINERAMA = @MOZ_ENABLE_XINERAMA@
14 --- mozilla/gfx/src/gtk/nsGfxFactoryGTK.cpp.foo 2003-09-07 18:20:38.000000000 -0400
15 +++ mozilla/gfx/src/gtk/nsGfxFactoryGTK.cpp 2004-10-18 22:49:40.000000000 -0400
16 @@ -62,6 +62,9 @@
17 #ifdef NATIVE_THEME_SUPPORT
18 #include "nsNativeThemeGTK.h"
19 #endif
20 +#ifdef MOZ_ENABLE_PANGO
21 +#include "nsFontMetricsPango.h"
22 +#endif
23 #ifdef MOZ_ENABLE_XFT
24 #include "nsFontMetricsXft.h"
25 #endif
26 @@ -112,6 +115,13 @@
27 if (aOuter)
28 return NS_ERROR_NO_AGGREGATION;
29
30 +#ifdef MOZ_ENABLE_PANGO
31 + if (NS_IsPangoEnabled()) {
32 + result = new nsFontMetricsPango();
33 + if (!result)
34 + return NS_ERROR_OUT_OF_MEMORY;
35 + } else {
36 +#endif
37 #ifdef MOZ_ENABLE_XFT
38 if (NS_IsXftEnabled()) {
39 result = new nsFontMetricsXft();
40 @@ -127,6 +137,9 @@
41 #ifdef MOZ_ENABLE_XFT
42 }
43 #endif
44 +#ifdef MOZ_ENABLE_PANGO
45 + }
46 +#endif
47
48 NS_ADDREF(result);
49 nsresult rv = result->QueryInterface(aIID, aResult);
50 @@ -148,6 +161,13 @@
51 if (aOuter)
52 return NS_ERROR_NO_AGGREGATION;
53
54 +#ifdef MOZ_ENABLE_PANGO
55 + if (NS_IsPangoEnabled()) {
56 + result = new nsFontEnumeratorPango();
57 + if (!result)
58 + return NS_ERROR_OUT_OF_MEMORY;
59 + } else {
60 +#endif
61 #ifdef MOZ_ENABLE_XFT
62 if (NS_IsXftEnabled()) {
63 result = new nsFontEnumeratorXft();
64 @@ -163,6 +183,9 @@
65 #ifdef MOZ_ENABLE_XFT
66 }
67 #endif
68 +#ifdef MOZ_ENABLE_PANGO
69 + }
70 +#endif
71
72 NS_ADDREF(result);
73 nsresult rv = result->QueryInterface(aIID, aResult);
74 --- /dev/null 2004-02-18 10:26:44.000000000 -0500
75 +++ mozilla/gfx/src/gtk/mozilla-decoder.h 2004-10-18 22:49:40.000000000 -0400
76 @@ -0,0 +1,72 @@
77 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
78 +/* vim:expandtab:shiftwidth=4:tabstop=4:
79 + */
80 +/* ***** BEGIN LICENSE BLOCK *****
81 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
82 + *
83 + * The contents of this file are subject to the Mozilla Public License Version
84 + * 1.1 (the "License"); you may not use this file except in compliance with
85 + * the License. You may obtain a copy of the License at
86 + * http://www.mozilla.org/MPL/
87 + *
88 + * Software distributed under the License is distributed on an "AS IS" basis,
89 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
90 + * for the specific language governing rights and limitations under the
91 + * License.
92 + *
93 + * The Original Code is mozilla.org code.
94 + *
95 + * The Initial Developer of the Original Code is Christopher Blizzard
96 + * <blizzard@mozilla.org>. Portions created by the Initial Developer
97 + * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
98 + *
99 + * Contributor(s):
100 + *
101 + * Alternatively, the contents of this file may be used under the terms of
102 + * either the GNU General Public License Version 2 or later (the "GPL"), or
103 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
104 + * in which case the provisions of the GPL or the LGPL are applicable instead
105 + * of those above. If you wish to allow use of your version of this file only
106 + * under the terms of either the GPL or the LGPL, and not to allow others to
107 + * use your version of this file under the terms of the MPL, indicate your
108 + * decision by deleting the provisions above and replace them with the notice
109 + * and other provisions required by the GPL or the LGPL. If you do not delete
110 + * the provisions above, a recipient may use your version of this file under
111 + * the terms of any one of the MPL, the GPL or the LGPL.
112 + *
113 + * ***** END LICENSE BLOCK ***** */
114 +
115 +#ifndef _MOZILLA_DECODER_H
116 +#define _MOZILLA_DECODER_H
117 +
118 +#include <pango/pangofc-decoder.h>
119 +
120 +G_BEGIN_DECLS
121 +
122 +#define MOZILLA_TYPE_DECODER (mozilla_decoder_get_type())
123 +#define MOZILLA_DECODER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOZILLA_TYPE_DECODER, MozillaDecoder))
124 +#define MOZILLA_IS_DECODER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOZILLA_TYPE_DECODER))
125 +
126 +typedef struct _MozillaDecoder MozillaDecoder;
127 +typedef struct _MozillaDecoderClass MozillaDecoderClass;
128 +
129 +#define MOZILLA_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOZILLA_TYPE_DECODER, MozillaDecoderClass))
130 +#define MOZILLA_IS_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOZILLA_TYPE_DECODER))
131 +#define MOZILLA_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_TYPE_DECODER, MozillaDecoderClass))
132 +
133 +struct _MozillaDecoder
134 +{
135 + PangoFcDecoder parent_instance;
136 +};
137 +
138 +struct _MozillaDecoderClass
139 +{
140 + PangoFcDecoderClass parent_class;
141 +};
142 +
143 +GType mozilla_decoder_get_type (void);
144 +int mozilla_decoders_init (void);
145 +
146 +G_END_DECLS
147 +
148 +#endif /*_MOZILLA_DECODER_H */
149 --- /dev/null 2004-02-18 10:26:44.000000000 -0500
150 +++ mozilla/gfx/src/gtk/mozilla-decoder.cpp 2004-10-18 22:49:40.000000000 -0400
151 @@ -0,0 +1,376 @@
152 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
153 +/* vim:expandtab:shiftwidth=4:tabstop=4:
154 + */
155 +/* ***** BEGIN LICENSE BLOCK *****
156 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
157 + *
158 + * The contents of this file are subject to the Mozilla Public License Version
159 + * 1.1 (the "License"); you may not use this file except in compliance with
160 + * the License. You may obtain a copy of the License at
161 + * http://www.mozilla.org/MPL/
162 + *
163 + * Software distributed under the License is distributed on an "AS IS" basis,
164 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
165 + * for the specific language governing rights and limitations under the
166 + * License.
167 + *
168 + * The Original Code is mozilla.org code.
169 + *
170 + * The Initial Developer of the Original Code is Christopher Blizzard
171 + * <blizzard@mozilla.org>. Portions created by the Initial Developer
172 + * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
173 + *
174 + * Contributor(s):
175 + *
176 + * Alternatively, the contents of this file may be used under the terms of
177 + * either the GNU General Public License Version 2 or later (the "GPL"), or
178 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
179 + * in which case the provisions of the GPL or the LGPL are applicable instead
180 + * of those above. If you wish to allow use of your version of this file only
181 + * under the terms of either the GPL or the LGPL, and not to allow others to
182 + * use your version of this file under the terms of the MPL, indicate your
183 + * decision by deleting the provisions above and replace them with the notice
184 + * and other provisions required by the GPL or the LGPL. If you do not delete
185 + * the provisions above, a recipient may use your version of this file under
186 + * the terms of any one of the MPL, the GPL or the LGPL.
187 + *
188 + * ***** END LICENSE BLOCK ***** */
189 +
190 +#define PANGO_ENABLE_BACKEND
191 +#define PANGO_ENABLE_ENGINE
192 +
193 +#include "mozilla-decoder.h"
194 +#include <pango/pangoxft.h>
195 +#include <pango/pangofc-fontmap.h>
196 +#include <pango/pangofc-font.h>
197 +#include <gdk/gdkx.h>
198 +
199 +#include "nsString.h"
200 +#include "nsIPersistentProperties2.h"
201 +#include "nsNetUtil.h"
202 +#include "nsReadableUtils.h"
203 +#include "nsICharsetConverterManager.h"
204 +#include "nsICharRepresentable.h"
205 +#include "nsCompressedCharMap.h"
206 +
207 +#undef DEBUG_CUSTOM_ENCODER
208 +
209 +G_DEFINE_TYPE (MozillaDecoder, mozilla_decoder, PANGO_TYPE_FC_DECODER)
210 +
211 +MozillaDecoder *mozilla_decoder_new (void);
212 +
213 +static FcCharSet *mozilla_decoder_get_charset (PangoFcDecoder *decoder,
214 + PangoFcFont *fcfont);
215 +static PangoGlyph mozilla_decoder_get_glyph (PangoFcDecoder *decoder,
216 + PangoFcFont *fcfont,
217 + guint32 wc);
218 +
219 +static PangoFcDecoder *mozilla_find_decoder (FcPattern *pattern,
220 + gpointer user_data);
221 +
222 +typedef struct _MozillaDecoderPrivate MozillaDecoderPrivate;
223 +
224 +#define MOZILLA_DECODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MOZILLA_TYPE_DECODER, MozillaDecoderPrivate))
225 +
226 +struct _MozillaDecoderPrivate {
227 + char *family;
228 + char *encoder;
229 + char *cmap;
230 + gboolean is_wide;
231 + FcCharSet *charset;
232 + nsCOMPtr<nsIUnicodeEncoder> uEncoder;
233 +};
234 +
235 +static nsICharsetConverterManager *gCharsetManager = NULL;
236 +
237 +static NS_DEFINE_CID(kCharsetConverterManagerCID,
238 + NS_ICHARSETCONVERTERMANAGER_CID);
239 +
240 +// Hash tables that hold the custom encodings and custom cmaps used in
241 +// various fonts.
242 +GHashTable *encoder_hash = NULL;
243 +GHashTable *cmap_hash = NULL;
244 +GHashTable *wide_hash = NULL;
245 +
246 +void
247 +mozilla_decoder_init (MozillaDecoder *decoder)
248 +{
249 +}
250 +
251 +void
252 +mozilla_decoder_class_init (MozillaDecoderClass *klass)
253 +{
254 + GObjectClass *object_class = G_OBJECT_CLASS(klass);
255 + PangoFcDecoderClass *parent_class = PANGO_FC_DECODER_CLASS (klass);
256 +
257 + /* object_class->finalize = test_finalize; */
258 +
259 + parent_class->get_charset = mozilla_decoder_get_charset;
260 + parent_class->get_glyph = mozilla_decoder_get_glyph;
261 +
262 + g_type_class_add_private (object_class, sizeof (MozillaDecoderPrivate));
263 +}
264 +
265 +MozillaDecoder *
266 +mozilla_decoder_new(void)
267 +{
268 + return (MozillaDecoder *)g_object_new(MOZILLA_TYPE_DECODER, NULL);
269 +}
270 +
271 +#ifdef DEBUG_CUSTOM_ENCODER
272 +void
273 +dump_hash(char *key, char *val, void *arg)
274 +{
275 + printf("%s -> %s\n", key, val);
276 +}
277 +#endif
278 +
279 +/**
280 + * mozilla_decoders_init:
281 + *
282 + * #mozilla_decoders_init:
283 + *
284 + * This initializes all of the application-specific custom decoders
285 + * that Mozilla uses. This should only be called once during the
286 + * lifetime of the application.
287 + *
288 + * Return value: zero on success, not zero on failure.
289 + *
290 + **/
291 +
292 +int
293 +mozilla_decoders_init(void)
294 +{
295 + static PRBool initialized = PR_FALSE;
296 + if (initialized)
297 + return 0;
298 +
299 + encoder_hash = g_hash_table_new(g_str_hash, g_str_equal);
300 + cmap_hash = g_hash_table_new(g_str_hash, g_str_equal);
301 + wide_hash = g_hash_table_new(g_str_hash, g_str_equal);
302 +
303 + PRBool dumb = PR_FALSE;
304 + nsCOMPtr<nsIPersistentProperties> props;
305 + nsCOMPtr<nsISimpleEnumerator> encodeEnum;
306 +
307 + NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(props),
308 + NS_LITERAL_CSTRING("resource://gre/res/fonts/pangoFontEncoding.properties"));
309 +
310 + if (!props)
311 + goto loser;
312 +
313 + // Enumerate the properties in this file and figure out all of the
314 + // fonts for which we have custom encodings.
315 + props->Enumerate(getter_AddRefs(encodeEnum));
316 + if (!encodeEnum)
317 + goto loser;
318 +
319 + while (encodeEnum->HasMoreElements(&dumb), dumb) {
320 + nsCOMPtr<nsIPropertyElement> prop;
321 + encodeEnum->GetNext(getter_AddRefs(prop));
322 + if (!prop)
323 + goto loser;
324 +
325 + nsCAutoString name;
326 + prop->GetKey(name);
327 + nsAutoString value;
328 + prop->GetValue(value);
329 +
330 + if (!StringBeginsWith(name, NS_LITERAL_CSTRING("encoding."))) {
331 + printf("string doesn't begin with encoding?\n");
332 + continue;
333 + }
334 +
335 + name = Substring(name, 9);
336 +
337 + if (StringEndsWith(name, NS_LITERAL_CSTRING(".ttf"))) {
338 + name = Substring(name, 0, name.Length() - 4);
339 +
340 + // Strip off a .wide if it's there.
341 + if (StringEndsWith(value, NS_LITERAL_STRING(".wide"))) {
342 + g_hash_table_insert(wide_hash, g_strdup(name.get()),
343 + g_strdup("wide"));
344 + value = Substring(value, 0, name.Length() - 5);
345 + }
346 +
347 + g_hash_table_insert(encoder_hash,
348 + g_strdup(name.get()),
349 + g_strdup(NS_ConvertUTF16toUTF8(value).get()));
350 + }
351 + else if (StringEndsWith(name, NS_LITERAL_CSTRING(".ftcmap"))) {
352 + name = Substring(name, 0, name.Length() - 7);
353 + g_hash_table_insert(cmap_hash,
354 + g_strdup(name.get()),
355 + g_strdup(NS_ConvertUTF16toUTF8(value).get()));
356 + }
357 + else {
358 + printf("unknown suffix used for mapping\n");
359 + }
360 + }
361 +
362 + pango_fc_font_map_add_decoder_find_func(PANGO_FC_FONT_MAP(pango_xft_get_font_map(GDK_DISPLAY(),gdk_x11_get_default_screen())),
363 + mozilla_find_decoder,
364 + NULL,
365 + NULL);
366 +
367 + initialized = PR_TRUE;
368 +
369 +#ifdef DEBUG_CUSTOM_ENCODER
370 + printf("*** encoders\n");
371 + g_hash_table_foreach(encoder_hash, (GHFunc)dump_hash, NULL);
372 +
373 + printf("*** cmaps\n");
374 + g_hash_table_foreach(cmap_hash, (GHFunc)dump_hash, NULL);
375 +#endif
376 +
377 + return 0;
378 +
379 + loser:
380 + return -1;
381 +}
382 +
383 +FcCharSet *
384 +mozilla_decoder_get_charset (PangoFcDecoder *decoder,
385 + PangoFcFont *fcfont)
386 +{
387 + MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder);
388 +
389 + if (priv->charset)
390 + return priv->charset;
391 +
392 + // First time this has been accessed. Populate the charset.
393 + priv->charset = FcCharSetCreate();
394 +
395 + if (!gCharsetManager) {
396 + nsServiceManager::GetService(kCharsetConverterManagerCID,
397 + NS_GET_IID(nsICharsetConverterManager), (nsISupports**)&gCharsetManager);
398 + }
399 +
400 + nsCOMPtr<nsIUnicodeEncoder> encoder;
401 + nsCOMPtr<nsICharRepresentable> represent;
402 +
403 + if (!gCharsetManager)
404 + goto end;
405 +
406 + gCharsetManager->GetUnicodeEncoderRaw(priv->encoder, getter_AddRefs(encoder));
407 + if (!encoder)
408 + goto end;
409 +
410 + encoder->SetOutputErrorBehavior(encoder->kOnError_Replace, nsnull, '?');
411 +
412 + priv->uEncoder = encoder;
413 +
414 + represent = do_QueryInterface(encoder);
415 + if (!represent)
416 + goto end;
417 +
418 + PRUint32 map[UCS2_MAP_LEN];
419 + memset(map, 0, sizeof(map));
420 +
421 + represent->FillInfo(map);
422 +
423 + for (int i = 0; i < NUM_UNICODE_CHARS; i++) {
424 + if (IS_REPRESENTABLE(map, i))
425 + FcCharSetAddChar(priv->charset, i);
426 + }
427 +
428 + end:
429 + return priv->charset;
430 +}
431 +
432 +PangoGlyph
433 +mozilla_decoder_get_glyph (PangoFcDecoder *decoder,
434 + PangoFcFont *fcfont,
435 + guint32 wc)
436 +{
437 + MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder);
438 +
439 + PangoGlyph retval = 0;
440 + PRUnichar inchar = wc;
441 + PRInt32 inlen = 1;
442 + char outchar[2] = {0,0};
443 + PRInt32 outlen = 2;
444 +
445 + priv->uEncoder->Convert(&inchar, &inlen, outchar, &outlen);
446 + if (outlen != 1) {
447 + printf("Warning: mozilla_decoder_get_glyph doesn't support more than one character conversions.\n");
448 + return 0;
449 + }
450 +
451 + FT_Face face = pango_fc_font_lock_face(fcfont);
452 +
453 +#ifdef DEBUG_CUSTOM_ENCODER
454 + char *filename;
455 + FcPatternGetString(fcfont->font_pattern, FC_FILE, 0, (FcChar8 **)&filename);
456 + printf("filename is %s\n", filename);
457 +#endif
458 +
459 + // Make sure to set the right charmap before trying to get the
460 + // glyph
461 + if (priv->cmap) {
462 + if (!strcmp(priv->cmap, "mac_roman")) {
463 + FT_Select_Charmap(face, ft_encoding_apple_roman);
464 + }
465 + else if (!strcmp(priv->cmap, "unicode")) {
466 + FT_Select_Charmap(face, ft_encoding_unicode);
467 + }
468 + else {
469 + printf("Warning: Invalid charmap entry for family %s\n",
470 + priv->family);
471 + }
472 + }
473 +
474 + // Standard 8 bit to glyph translation
475 + if (!priv->is_wide) {
476 + FcChar32 blah = PRUint8(outchar[0]);
477 + retval = FT_Get_Char_Index(face, blah);
478 +#ifdef DEBUG_CUSTOM_ENCODER
479 + printf("wc 0x%x outchar[0] 0x%x index 0x%x retval 0x%x face %p\n",
480 + wc, outchar[0], blah, retval, (void *)face);
481 +#endif
482 + }
483 + else {
484 + printf("Warning: We don't support .wide fonts!\n");
485 + retval = 0;
486 + }
487 +
488 + pango_fc_font_unlock_face(fcfont);
489 +
490 + return retval;
491 +}
492 +
493 +PangoFcDecoder *
494 +mozilla_find_decoder (FcPattern *pattern, gpointer user_data)
495 +{
496 + // Compare the family name of the font that's been opened to see
497 + // if we have a custom decoder.
498 + const char *orig = NULL;
499 + FcPatternGetString(pattern, FC_FAMILY, 0, (FcChar8 **)&orig);
500 +
501 + nsCAutoString family;
502 + family.Assign(orig);
503 +
504 + family.StripWhitespace();
505 + ToLowerCase(family);
506 +
507 + char *encoder = (char *)g_hash_table_lookup(encoder_hash, family.get());
508 + if (!encoder)
509 + return NULL;
510 +
511 + MozillaDecoder *decoder = mozilla_decoder_new();
512 +
513 + MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder);
514 +
515 + priv->family = g_strdup(family.get());
516 + priv->encoder = g_strdup(encoder);
517 +
518 + char *cmap = (char *)g_hash_table_lookup(cmap_hash, family.get());
519 + if (cmap)
520 + priv->cmap = g_strdup(cmap);
521 +
522 + char *wide = (char *)g_hash_table_lookup(wide_hash, family.get());
523 + if (wide)
524 + priv->is_wide = TRUE;
525 +
526 + return PANGO_FC_DECODER(decoder);
527 +}
528 --- mozilla/gfx/src/gtk/gfxgtk.pkg.foo 2004-01-06 20:21:35.000000000 -0500
529 +++ mozilla/gfx/src/gtk/gfxgtk.pkg 2004-10-18 22:49:40.000000000 -0400
530 @@ -7,3 +7,6 @@
531 #if MOZ_ENABLE_XFT
532 dist/bin/res/fonts/fontEncoding.properties
533 #endif
534 +#if MOZ_ENABLE_PANGO
535 +dist/bin/res/fonts/pangoFontEncoding.properties
536 +#endif
537 --- mozilla/gfx/src/gtk/nsFontMetricsXft.cpp.foo 2004-04-05 15:18:43.000000000 -0400
538 +++ mozilla/gfx/src/gtk/nsFontMetricsXft.cpp 2004-10-18 22:49:40.000000000 -0400
539 @@ -238,7 +238,7 @@
540
541 static int CalculateSlant (PRUint8 aStyle);
542 static int CalculateWeight (PRUint16 aWeight);
543 -static void AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup);
544 +/* static */ void AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup);
545 static void AddFFRE (FcPattern *aPattern, nsCString *aFamily,
546 PRBool aWeak);
547 static void FFREToFamily (nsACString &aFFREName, nsACString &oFamily);
548 @@ -449,7 +449,7 @@
549 // Make sure that the pixel size is at least greater than zero
550 if (mPixelSize < 1) {
551 #ifdef DEBUG
552 - printf("*** Warning: nsFontMetricsXft was passed a pixel size of %d\n",
553 + printf("*** Warning: nsFontMetricsXft was passed a pixel size of %f\n",
554 mPixelSize);
555 #endif
556 mPixelSize = 1;
557 @@ -474,6 +474,26 @@
558 if (NS_FAILED(RealizeFont()))
559 return NS_ERROR_FAILURE;
560
561 +#ifdef DEBUG_foo
562 + printf("%i\n", mXHeight);
563 + printf("%i\n", mSuperscriptOffset);
564 + printf("%i\n", mSubscriptOffset);
565 + printf("%i\n", mStrikeoutOffset);
566 + printf("%i\n", mStrikeoutSize);
567 + printf("%i\n", mUnderlineOffset);
568 + printf("%i\n", mUnderlineSize);
569 + printf("%i\n", mMaxHeight);
570 + printf("%i\n", mLeading);
571 + printf("%i\n", mEmHeight);
572 + printf("%i\n", mEmAscent);
573 + printf("%i\n", mEmDescent);
574 + printf("%i\n", mMaxAscent);
575 + printf("%i\n", mMaxDescent);
576 + printf("%i\n", mMaxAdvance);
577 + printf("%i\n", mSpaceWidth);
578 + printf("%i\n", mAveCharWidth);
579 +#endif /* DEBUG_foo */
580 +
581 return NS_OK;
582 }
583
584 @@ -530,6 +550,10 @@
585 f = mDeviceContext->DevUnitsToAppUnits();
586 aWidth = NSToCoordRound(glyphInfo.xOff * f);
587
588 +#ifdef DEBUG_foo
589 + printf("GetWidth (char *) %d\n", aWidth);
590 +#endif
591 +
592 return NS_OK;
593 }
594
595 @@ -553,6 +577,10 @@
596 if (aFontID)
597 *aFontID = 0;
598
599 +#ifdef DEBUG_foo
600 + printf("GetWidth %d\n", aWidth);
601 +#endif
602 +
603 return NS_OK;
604 }
605
606 @@ -586,6 +614,11 @@
607 if (nsnull != aFontID)
608 *aFontID = 0;
609
610 +#ifdef DEBUG_foo
611 + printf("GetTextDimensions %d %d %d\n", aDimensions.width,
612 + aDimensions.ascent, aDimensions.descent);
613 +#endif
614 +
615 return NS_OK;
616 }
617
618 @@ -645,6 +678,10 @@
619 nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
620 data.drawBuffer = &drawBuffer;
621
622 +#ifdef DEBUG_foo
623 + printf("DrawString (char *)\n");
624 +#endif
625 +
626 return EnumerateGlyphs(aString, aLength,
627 &nsFontMetricsXft::DrawStringCallback, &data);
628 }
629 @@ -675,6 +712,10 @@
630 nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
631 data.drawBuffer = &drawBuffer;
632
633 +#ifdef DEBUG_foo
634 + printf("DrawString\n");
635 +#endif
636 +
637 return EnumerateGlyphs(aString, aLength,
638 &nsFontMetricsXft::DrawStringCallback, &data);
639 }
640 @@ -714,6 +755,15 @@
641 aBoundingMetrics.ascent = NSToCoordRound(aBoundingMetrics.ascent * P2T);
642 aBoundingMetrics.descent = NSToCoordRound(aBoundingMetrics.descent * P2T);
643
644 +#ifdef DEBUG_foo
645 + printf("GetBoundingMetrics (char *)%d %d %d %d %d\n",
646 + aBoundingMetrics.leftBearing,
647 + aBoundingMetrics.rightBearing,
648 + aBoundingMetrics.width,
649 + aBoundingMetrics.ascent,
650 + aBoundingMetrics.descent);
651 +#endif
652 +
653 return NS_OK;
654 }
655
656 @@ -755,6 +805,15 @@
657 if (nsnull != aFontID)
658 *aFontID = 0;
659
660 +#ifdef DEBUG_foo
661 + printf("GetBoundingMetrics %d %d %d %d %d\n",
662 + aBoundingMetrics.leftBearing,
663 + aBoundingMetrics.rightBearing,
664 + aBoundingMetrics.width,
665 + aBoundingMetrics.ascent,
666 + aBoundingMetrics.descent);
667 +#endif
668 +
669 return NS_OK;
670 }
671
672 @@ -766,6 +825,12 @@
673 return nsnull;
674 }
675
676 +nsresult
677 +nsFontMetricsXft::SetRightToLeftText(PRBool aIsRTL)
678 +{
679 + return NS_OK;
680 +}
681 +
682 PRUint32
683 nsFontMetricsXft::GetHints(void)
684 {
685 --- mozilla/gfx/src/gtk/Makefile.in.foo 2003-11-10 07:24:51.000000000 -0500
686 +++ mozilla/gfx/src/gtk/Makefile.in 2004-10-18 22:51:01.000000000 -0400
687 @@ -102,6 +102,12 @@
688 nsFontMetricsXft.cpp
689 endif
690
691 +ifdef MOZ_ENABLE_PANGO
692 +CPPSRCS += \
693 + nsFontMetricsPango.cpp \
694 + mozilla-decoder.cpp
695 +endif
696 +
697 ifdef MOZ_ENABLE_GTK
698 CPPSRCS += \
699 nsRegionGTK.cpp \
700 @@ -155,10 +161,10 @@
701 endif
702
703 ifdef MOZ_ENABLE_XFT
704 -libs:: fontEncoding.properties
705 +libs:: fontEncoding.properties pangoFontEncoding.properties
706 $(INSTALL) $^ $(DIST)/bin/res/fonts
707
708 -install:: fontEncoding.properties
709 +install:: fontEncoding.properties pangoFontEncoding.properties
710 $(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/res/fonts
711 endif
712
713 --- /dev/null 2004-02-18 10:26:44.000000000 -0500
714 +++ mozilla/gfx/src/gtk/pangoFontEncoding.properties 2004-10-18 22:49:40.000000000 -0400
715 @@ -0,0 +1,120 @@
716 +# ***** BEGIN LICENSE BLOCK *****
717 +# Version: MPL 1.1/GPL 2.0/LGPL 2.1
718 +#
719 +# The contents of this file are subject to the Mozilla Public License Version
720 +# 1.1 (the "License"); you may not use this file except in compliance with
721 +# the License. You may obtain a copy of the License at
722 +# http://www.mozilla.org/MPL/
723 +#
724 +# Software distributed under the License is distributed on an "AS IS" basis,
725 +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
726 +# for the specific language governing rights and limitations under the
727 +# License.
728 +#
729 +# The Original Code is Mozilla MathML Project.
730 +#
731 +# The Initial Developer of the Original Code is
732 +# The University of Queensland.
733 +# Portions created by the Initial Developer are Copyright (C) 2001
734 +# the Initial Developer. All Rights Reserved.
735 +#
736 +# Contributor(s):
737 +# Roger B. Sidje <rbs@maths.uq.edu.au>
738 +# Jungshik Shin <jshin@mailaps.org>
739 +# Christopher Blizzard <blizzard@mozilla.org>
740 +#
741 +# Alternatively, the contents of this file may be used under the terms of
742 +# either the GNU General Public License Version 2 or later (the "GPL"), or
743 +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
744 +# in which case the provisions of the GPL or the LGPL are applicable instead
745 +# of those above. If you wish to allow use of your version of this file only
746 +# under the terms of either the GPL or the LGPL, and not to allow others to
747 +# use your version of this file under the terms of the MPL, indicate your
748 +# decision by deleting the provisions above and replace them with the notice
749 +# and other provisions required by the GPL or the LGPL. If you do not delete
750 +# the provisions above, a recipient may use your version of this file under
751 +# the terms of any one of the MPL, the GPL or the LGPL.
752 +#
753 +# ***** END LICENSE BLOCK *****
754 +
755 +# LOCALIZATION NOTE: FILE
756 +# Do not translate anything in this file
757 +
758 +# This file contains supported custom encodings for pango font
759 +# rendering. For information about the specific encodings, look at
760 +# fontEncoding.properties. It contains a lot more verbiage than you
761 +# will find here. There are a lot of encodings supported in the old
762 +# encoding file that pango supports directly, so there should be
763 +# little reason to use those custom encodings. The pango custom code
764 +# doesn't support .wide fonts, so consider yourself warned!
765 +#
766 +
767 +# To be honest, we basically support mathml and that's about it.
768 +
769 +encoding.cmr10.ttf = x-ttf-cmr
770 +encoding.cmmi10.ttf = x-ttf-cmmi
771 +encoding.cmsy10.ttf = x-ttf-cmsy
772 +encoding.cmex10.ttf = x-ttf-cmex
773 +
774 +encoding.cmr10.ftcmap = unicode
775 +encoding.cmmi10.ftcmap = unicode
776 +encoding.cmsy10.ftcmap = unicode
777 +encoding.cmex10.ftcmap = unicode
778 +
779 +encoding.math1.ttf = x-mathematica1
780 +encoding.math1-bold.ttf = x-mathematica1
781 +encoding.math1mono.ttf = x-mathematica1
782 +encoding.math1mono-bold.ttf = x-mathematica1
783 +
784 +encoding.math2.ttf = x-mathematica2
785 +encoding.math2-bold.ttf = x-mathematica2
786 +encoding.math2mono.ttf = x-mathematica2
787 +encoding.math2mono-bold.ttf = x-mathematica2
788 +
789 +encoding.math3.ttf = x-mathematica3
790 +encoding.math3-bold.ttf = x-mathematica3
791 +encoding.math3mono.ttf = x-mathematica3
792 +encoding.math3mono-bold.ttf = x-mathematica3
793 +
794 +encoding.math4.ttf = x-mathematica4
795 +encoding.math4-bold.ttf = x-mathematica4
796 +encoding.math4mono.ttf = x-mathematica4
797 +encoding.math4mono-bold.ttf = x-mathematica4
798 +
799 +encoding.math5.ttf = x-mathematica5
800 +encoding.math5-bold.ttf = x-mathematica5
801 +encoding.math5bold.ttf = x-mathematica5
802 +encoding.math5mono.ttf = x-mathematica5
803 +encoding.math5mono-bold.ttf = x-mathematica5
804 +encoding.math5monobold.ttf = x-mathematica5
805 +
806 +encoding.math1.ftcmap = mac_roman
807 +encoding.math1-bold.ftcmap = mac_roman
808 +encoding.math1mono.ftcmap = mac_roman
809 +encoding.math1mono-bold.ftcmap = mac_roman
810 +
811 +encoding.math2.ftcmap = mac_roman
812 +encoding.math2-bold.ftcmap = mac_roman
813 +encoding.math2mono.ftcmap = mac_roman
814 +encoding.math2mono-bold.ftcmap = mac_roman
815 +
816 +encoding.math3.ftcmap = mac_roman
817 +encoding.math3-bold.ftcmap = mac_roman
818 +encoding.math3mono.ftcmap = mac_roman
819 +encoding.math3mono-bold.ftcmap = mac_roman
820 +
821 +encoding.math4.ftcmap = mac_roman
822 +encoding.math4-bold.ftcmap = mac_roman
823 +encoding.math4mono.ftcmap = mac_roman
824 +encoding.math4mono-bold.ftcmap = mac_roman
825 +
826 +encoding.math5.ftcmap = mac_roman
827 +encoding.math5-bold.ftcmap = mac_roman
828 +encoding.math5bold.ftcmap = mac_roman
829 +encoding.math5mono.ftcmap = mac_roman
830 +encoding.math5mono-bold.ftcmap = mac_roman
831 +encoding.math5monobold.ftcmap = mac_roman
832 +
833 +encoding.mtextra.ttf = x-mtextra
834 +encoding.mtextra.ftcmap = mac_roman
835 +
836 --- mozilla/gfx/src/gtk/nsFontMetricsUtils.cpp.foo 2002-10-11 22:03:32.000000000 -0400
837 +++ mozilla/gfx/src/gtk/nsFontMetricsUtils.cpp 2004-10-18 22:51:32.000000000 -0400
838 @@ -50,11 +50,20 @@
839 #include "nsFontMetricsGTK.h"
840 #endif
841
842 +#ifdef MOZ_ENABLE_PANGO
843 +#include "nsFontMetricsPango.h"
844 +#endif
845 +
846 #include "nsFontMetricsUtils.h"
847
848 PRUint32
849 NS_FontMetricsGetHints(void)
850 {
851 +#ifdef MOZ_ENABLE_PANGO
852 + if (NS_IsPangoEnabled()) {
853 + return nsFontMetricsPango::GetHints();
854 + }
855 +#endif
856 #ifdef MOZ_ENABLE_XFT
857 if (NS_IsXftEnabled()) {
858 return nsFontMetricsXft::GetHints();
859 @@ -69,6 +78,11 @@
860 nsresult
861 NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice, const nsString &aName)
862 {
863 +#ifdef MOZ_ENABLE_PANGO
864 + if (NS_IsPangoEnabled()) {
865 + return nsFontMetricsPango::FamilyExists(aDevice, aName);
866 + }
867 +#endif
868 #ifdef MOZ_ENABLE_XFT
869 // try to fall through to the core fonts if xft fails
870 if (NS_IsXftEnabled()) {
871 @@ -121,3 +135,17 @@
872 }
873
874 #endif /* MOZ_ENABLE_XFT */
875 +
876 +#ifdef MOZ_ENABLE_PANGO
877 +
878 +PRBool
879 +NS_IsPangoEnabled(void)
880 +{
881 + char *val = PR_GetEnv("MOZ_ENABLE_PANGO");
882 + if (val)
883 + return TRUE;
884 +
885 + return FALSE;
886 +}
887 +
888 +#endif
889 --- /dev/null 2004-02-18 10:26:44.000000000 -0500
890 +++ mozilla/gfx/src/gtk/nsFontMetricsPango.cpp 2004-10-18 22:49:40.000000000 -0400
891 @@ -0,0 +1,1662 @@
892 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
893 +/* vim:expandtab:shiftwidth=4:tabstop=4:
894 + */
895 +/* ***** BEGIN LICENSE BLOCK *****
896 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
897 + *
898 + * The contents of this file are subject to the Mozilla Public License Version
899 + * 1.1 (the "License"); you may not use this file except in compliance with
900 + * the License. You may obtain a copy of the License at
901 + * http://www.mozilla.org/MPL/
902 + *
903 + * Software distributed under the License is distributed on an "AS IS" basis,
904 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
905 + * for the specific language governing rights and limitations under the
906 + * License.
907 + *
908 + * The Original Code is mozilla.org code.
909 + *
910 + * The Initial Developer of the Original Code is Christopher Blizzard
911 + * <blizzard@mozilla.org>. Portions created by the Initial Developer
912 + * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
913 + *
914 + * Contributor(s):
915 + *
916 + * Alternatively, the contents of this file may be used under the terms of
917 + * either the GNU General Public License Version 2 or later (the "GPL"), or
918 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
919 + * in which case the provisions of the GPL or the LGPL are applicable instead
920 + * of those above. If you wish to allow use of your version of this file only
921 + * under the terms of either the GPL or the LGPL, and not to allow others to
922 + * use your version of this file under the terms of the MPL, indicate your
923 + * decision by deleting the provisions above and replace them with the notice
924 + * and other provisions required by the GPL or the LGPL. If you do not delete
925 + * the provisions above, a recipient may use your version of this file under
926 + * the terms of any one of the MPL, the GPL or the LGPL.
927 + *
928 + * ***** END LICENSE BLOCK ***** */
929 +
930 +#include "nsFont.h"
931 +#include "nsIDeviceContext.h"
932 +#include "nsICharsetConverterManager.h"
933 +#include "nsIPref.h"
934 +#include "nsIServiceManagerUtils.h"
935 +
936 +#define PANGO_ENABLE_BACKEND
937 +#define PANGO_ENABLE_ENGINE
938 +
939 +#include "nsFontMetricsPango.h"
940 +#include "nsRenderingContextGTK.h"
941 +#include "nsDeviceContextGTK.h"
942 +
943 +#include "nsUnicharUtils.h"
944 +#include "nsQuickSort.h"
945 +
946 +#include <pango/pangoxft.h>
947 +#include <fontconfig/fontconfig.h>
948 +#include <gdk/gdk.h>
949 +#include <gdk/gdkx.h>
950 +#include <freetype/tttables.h>
951 +
952 +#include "mozilla-decoder.h"
953 +
954 +#define FORCE_PR_LOG
955 +#include "prlog.h"
956 +
957 +// Globals
958 +
959 +static PRLogModuleInfo *gPangoFontLog;
960 +static int gNumInstances;
961 +
962 +// Defines
963 +
964 +// This is the scaling factor that we keep fonts limited to against
965 +// the display size. If a pixel size is requested that is more than
966 +// this factor larger than the height of the display, it's clamped to
967 +// that value instead of the requested size.
968 +#define FONT_MAX_FONT_SCALE 2
969 +
970 +static NS_DEFINE_CID(kCharsetConverterManagerCID,
971 + NS_ICHARSETCONVERTERMANAGER_CID);
972 +
973 +struct MozPangoLangGroup {
974 + const char *mozLangGroup;
975 + const char *PangoLang;
976 +};
977 +
978 +static const MozPangoLangGroup MozPangoLangGroups[] = {
979 + { "x-western", "en" },
980 + { "x-central-euro", "pl" },
981 + { "x-cyrillic", "ru" },
982 + { "x-baltic", "lv" },
983 + { "x-devanagari", "hi" },
984 + { "x-tamil", "ta" },
985 + { "x-unicode", 0 },
986 + { "x-user-def", 0 },
987 +};
988 +
989 +#define NUM_PANGO_LANG_GROUPS (sizeof (MozPangoLangGroups) / \
990 + sizeof (MozPangoLangGroups[0]))
991 +
992 +#ifdef DEBUG
993 +#define DUMP_PRUNICHAR(ustr, ulen) for (PRUint32 llen=0;llen<ulen;llen++) \
994 + printf("0x%x ", ustr[llen]); \
995 + printf("\n");
996 +#endif
997 +
998 +// rounding and truncation functions for a Freetype floating point number
999 +// (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer
1000 +// part and low 6 bits for the fractional part.
1001 +#define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1
1002 +#define MOZ_FT_TRUNC(x) ((x) >> 6)
1003 +#define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \
1004 + MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s))))
1005 +
1006 +// Static function decls
1007 +
1008 +static PRBool IsASCIIFontName (const nsString& aName);
1009 +static int FFRECountHyphens (nsACString &aFFREName);
1010 +
1011 +static PangoLanguage *GetPangoLanguage(nsIAtom *aLangGroup);
1012 +static const MozPangoLangGroup* FindPangoLangGroup (nsACString &aLangGroup);
1013 +
1014 +static void FreeGlobals (void);
1015 +
1016 +static PangoStyle CalculateStyle (PRUint8 aStyle);
1017 +static PangoWeight CalculateWeight (PRUint16 aWeight);
1018 +
1019 +static nsresult EnumFontsPango (nsIAtom* aLangGroup, const char* aGeneric,
1020 + PRUint32* aCount, PRUnichar*** aResult);
1021 +static int CompareFontNames (const void* aArg1, const void* aArg2,
1022 + void* aClosure);
1023 +
1024 +extern void AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup);
1025 +
1026 +nsFontMetricsPango::nsFontMetricsPango()
1027 +{
1028 + if (!gPangoFontLog)
1029 + gPangoFontLog = PR_NewLogModule("PangoFont");
1030 +
1031 + gNumInstances++;
1032 +
1033 + mPangoFontDesc = nsnull;
1034 + mPangoContext = nsnull;
1035 + mLTRPangoContext = nsnull;
1036 + mRTLPangoContext = nsnull;
1037 + mPangoAttrList = nsnull;
1038 + mIsRTL = PR_FALSE;
1039 +
1040 + static PRBool initialized = PR_FALSE;
1041 + if (initialized)
1042 + return;
1043 +
1044 + // Initialized the custom decoders
1045 + if (!mozilla_decoders_init())
1046 + initialized = PR_TRUE;
1047 +}
1048 +
1049 +nsFontMetricsPango::~nsFontMetricsPango()
1050 +{
1051 + delete mFont;
1052 +
1053 + if (mDeviceContext)
1054 + mDeviceContext->FontMetricsDeleted(this);
1055 +
1056 + if (mPangoFontDesc)
1057 + pango_font_description_free(mPangoFontDesc);
1058 +
1059 + if (mLTRPangoContext)
1060 + g_object_unref(mLTRPangoContext);
1061 +
1062 + if (mRTLPangoContext)
1063 + g_object_unref(mRTLPangoContext);
1064 +
1065 + if (mPangoAttrList)
1066 + pango_attr_list_unref(mPangoAttrList);
1067 +
1068 + // XXX clean up all the pango objects
1069 +
1070 + if (--gNumInstances == 0)
1071 + FreeGlobals();
1072 +}
1073 +
1074 +
1075 +NS_IMPL_ISUPPORTS1(nsFontMetricsPango, nsIFontMetrics)
1076 +
1077 +// nsIFontMetrics impl
1078 +
1079 +NS_IMETHODIMP
1080 +nsFontMetricsPango::Init(const nsFont& aFont, nsIAtom* aLangGroup,
1081 + nsIDeviceContext *aContext)
1082 +{
1083 + mFont = new nsFont(aFont);
1084 + mLangGroup = aLangGroup;
1085 +
1086 + // Hang on to the device context
1087 + mDeviceContext = aContext;
1088 +
1089 + mPointSize = NSTwipsToFloatPoints(mFont->size);
1090 +
1091 + // Make sure to clamp the pixel size to something reasonable so we
1092 + // don't make the X server blow up.
1093 + nscoord screenPixels = gdk_screen_height();
1094 + mPointSize = PR_MIN(screenPixels * FONT_MAX_FONT_SCALE, mPointSize);
1095 +
1096 + // enumerate over the font names passed in
1097 + mFont->EnumerateFamilies(nsFontMetricsPango::EnumFontCallback, this);
1098 +
1099 + nsCOMPtr<nsIPref> prefService;
1100 + prefService = do_GetService(NS_PREF_CONTRACTID);
1101 + if (!prefService)
1102 + return NS_ERROR_FAILURE;
1103 +
1104 + nsXPIDLCString value;
1105 +
1106 + // Set up the default font name if it's not set
1107 + if (!mGenericFont) {
1108 + prefService->CopyCharPref("font.default", getter_Copies(value));
1109 +
1110 + if (value.get())
1111 + mDefaultFont = value.get();
1112 + else
1113 + mDefaultFont = "serif";
1114 +
1115 + mGenericFont = &mDefaultFont;
1116 + }
1117 +
1118 + // set up the minimum sizes for fonts
1119 + if (mLangGroup) {
1120 + nsCAutoString name("font.min-size.");
1121 +
1122 + if (mGenericFont->Equals("monospace"))
1123 + name.Append("fixed");
1124 + else
1125 + name.Append("variable");
1126 +
1127 + name.Append(char('.'));
1128 +
1129 + const char* langGroup;
1130 + mLangGroup->GetUTF8String(&langGroup);
1131 +
1132 + name.Append(langGroup);
1133 +
1134 + PRInt32 minimumInt = 0;
1135 + float minimum;
1136 + nsresult res;
1137 + res = prefService->GetIntPref(name.get(), &minimumInt);
1138 + if (NS_FAILED(res))
1139 + prefService->GetDefaultIntPref(name.get(), &minimumInt);
1140 +
1141 + if (minimumInt < 0)
1142 + minimumInt = 0;
1143 +
1144 + minimum = minimumInt;
1145 +
1146 + // The minimum size is specified in pixels, not in points.
1147 + // Convert the size from pixels to points.
1148 + minimum = NSTwipsToFloatPoints(NSFloatPixelsToTwips(minimum, mDeviceContext->DevUnitsToAppUnits()));
1149 + if (mPointSize < minimum)
1150 + mPointSize = minimum;
1151 + }
1152 +
1153 + // Make sure that the pixel size is at least greater than zero
1154 + if (mPointSize < 1) {
1155 +#ifdef DEBUG
1156 + printf("*** Warning: nsFontMetricsPango created with point size %f\n",
1157 + mPointSize);
1158 +#endif
1159 + mPointSize = 1;
1160 + }
1161 +
1162 + nsresult rv = RealizeFont();
1163 + if (NS_FAILED(rv))
1164 + return rv;
1165 +
1166 + // Cache font metrics for the 'x' character
1167 + return CacheFontMetrics();
1168 +}
1169 +
1170 +nsresult
1171 +nsFontMetricsPango::CacheFontMetrics(void)
1172 +{
1173 + // Get our scale factor
1174 + float f;
1175 + float val;
1176 + f = mDeviceContext->DevUnitsToAppUnits();
1177 +
1178 + mPangoAttrList = pango_attr_list_new();
1179 +
1180 + GList *items = pango_itemize(mPangoContext,
1181 + "a", 0, 1, mPangoAttrList, NULL);
1182 +
1183 + if (!items)
1184 + return NS_ERROR_FAILURE;
1185 +
1186 + guint nitems = g_list_length(items);
1187 + if (nitems != 1)
1188 + return NS_ERROR_FAILURE;
1189 +
1190 + PangoItem *item = (PangoItem *)items->data;
1191 + PangoFcFont *fcfont = PANGO_FC_FONT(item->analysis.font);
1192 + if (!fcfont)
1193 + return NS_ERROR_FAILURE;
1194 +
1195 + // Get our font face
1196 + FT_Face face;
1197 + TT_OS2 *os2;
1198 + XftFont *xftFont = pango_xft_font_get_font(PANGO_FONT(fcfont));
1199 + if (!xftFont)
1200 + return NS_ERROR_NOT_AVAILABLE;
1201 +
1202 + face = XftLockFace(xftFont);
1203 + os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1204 +
1205 + // mEmHeight (size in pixels of EM height)
1206 + int size;
1207 + if (FcPatternGetInteger(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) !=
1208 + FcResultMatch) {
1209 + size = 12;
1210 + }
1211 + mEmHeight = PR_MAX(1, nscoord(size * f));
1212 +
1213 + // mMaxAscent
1214 + mMaxAscent = nscoord(xftFont->ascent * f);
1215 +
1216 + // mMaxDescent
1217 + mMaxDescent = nscoord(xftFont->descent * f);
1218 +
1219 + nscoord lineHeight = mMaxAscent + mMaxDescent;
1220 +
1221 + // mLeading (needs ascent and descent and EM height)
1222 + if (lineHeight > mEmHeight)
1223 + mLeading = lineHeight - mEmHeight;
1224 + else
1225 + mLeading = 0;
1226 +
1227 + // mMaxHeight (needs ascent and descent)
1228 + mMaxHeight = lineHeight;
1229 +
1230 + // mEmAscent (needs maxascent, EM height, ascent and descent)
1231 + mEmAscent = nscoord(mMaxAscent * mEmHeight / lineHeight);
1232 +
1233 + // mEmDescent (needs EM height and EM ascent
1234 + mEmDescent = mEmHeight - mEmAscent;
1235 +
1236 + // mMaxAdvance
1237 + mMaxAdvance = nscoord(xftFont->max_advance_width * f);
1238 +
1239 + // mSpaceWidth (width of a space)
1240 + nscoord tmpWidth;
1241 + GetWidth(" ", 1, tmpWidth, NULL);
1242 + mSpaceWidth = tmpWidth;
1243 +
1244 + // mAveCharWidth (width of an 'average' char)
1245 + // XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents);
1246 + //rawWidth = extents.width;
1247 + //mAveCharWidth = NSToCoordRound(rawWidth * f);
1248 + GetWidth("x", 1, tmpWidth, NULL);
1249 + mAveCharWidth = tmpWidth;
1250 +
1251 + // mXHeight (height of an 'x' character)
1252 + PRUnichar xUnichar('x');
1253 + XGlyphInfo extents;
1254 + if (FcCharSetHasChar(xftFont->charset, xUnichar)) {
1255 + XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents);
1256 + mXHeight = extents.height;
1257 + }
1258 + else {
1259 + // 56% of ascent, best guess for non-true type or asian fonts
1260 + mXHeight = nscoord(((float)mMaxAscent) * 0.56);
1261 + }
1262 + mXHeight = nscoord(mXHeight * f);
1263 +
1264 + // mUnderlineOffset (offset for underlines)
1265 + val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position,
1266 + face->size->metrics.y_scale);
1267 + if (val) {
1268 + mUnderlineOffset = NSToIntRound(val * f);
1269 + }
1270 + else {
1271 + mUnderlineOffset =
1272 + -NSToIntRound(PR_MAX(1, floor(0.1 * xftFont->height + 0.5)) * f);
1273 + }
1274 +
1275 + // mUnderlineSize (thickness of an underline)
1276 + val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness,
1277 + face->size->metrics.y_scale);
1278 + if (val) {
1279 + mUnderlineSize = nscoord(PR_MAX(f, NSToIntRound(val * f)));
1280 + }
1281 + else {
1282 + mUnderlineSize =
1283 + NSToIntRound(PR_MAX(1, floor(0.05 * xftFont->height + 0.5)) * f);
1284 + }
1285 +
1286 + // mSuperscriptOffset
1287 + if (os2 && os2->ySuperscriptYOffset) {
1288 + val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySuperscriptYOffset,
1289 + face->size->metrics.y_scale);
1290 + mSuperscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f)));
1291 + }
1292 + else {
1293 + mSuperscriptOffset = mXHeight;
1294 + }
1295 +
1296 + // mSubscriptOffset
1297 + if (os2 && os2->ySubscriptYOffset) {
1298 + val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySubscriptYOffset,
1299 + face->size->metrics.y_scale);
1300 + // some fonts have the incorrect sign.
1301 + val = (val < 0) ? -val : val;
1302 + mSubscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f)));
1303 + }
1304 + else {
1305 + mSubscriptOffset = mXHeight;
1306 + }
1307 +
1308 + // mStrikeoutOffset
1309 + mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0);
1310 +
1311 + // mStrikeoutSize
1312 + mStrikeoutSize = mUnderlineSize;
1313 +
1314 + XftUnlockFace(xftFont);
1315 +
1316 + /*
1317 + printf("%i\n", mXHeight);
1318 + printf("%i\n", mSuperscriptOffset);
1319 + printf("%i\n", mSubscriptOffset);
1320 + printf("%i\n", mStrikeoutOffset);
1321 + printf("%i\n", mStrikeoutSize);
1322 + printf("%i\n", mUnderlineOffset);
1323 + printf("%i\n", mUnderlineSize);
1324 + printf("%i\n", mMaxHeight);
1325 + printf("%i\n", mLeading);
1326 + printf("%i\n", mEmHeight);
1327 + printf("%i\n", mEmAscent);
1328 + printf("%i\n", mEmDescent);
1329 + printf("%i\n", mMaxAscent);
1330 + printf("%i\n", mMaxDescent);
1331 + printf("%i\n", mMaxAdvance);
1332 + printf("%i\n", mSpaceWidth);
1333 + printf("%i\n", mAveCharWidth);
1334 + */
1335 +
1336 + return NS_OK;
1337 +}
1338 +
1339 +NS_IMETHODIMP
1340 +nsFontMetricsPango::Destroy()
1341 +{
1342 + mDeviceContext = nsnull;
1343 + return NS_OK;
1344 +}
1345 +
1346 +NS_IMETHODIMP
1347 +nsFontMetricsPango::GetFont(const nsFont *&aFont)
1348 +{
1349 + aFont = mFont;
1350 + return NS_OK;
1351 +}
1352 +
1353 +NS_IMETHODIMP
1354 +nsFontMetricsPango::GetLangGroup(nsIAtom** aLangGroup)
1355 +{
1356 + *aLangGroup = mLangGroup;
1357 + NS_IF_ADDREF(*aLangGroup);
1358 +
1359 + return NS_OK;
1360 +}
1361 +
1362 +NS_IMETHODIMP
1363 +nsFontMetricsPango::GetFontHandle(nsFontHandle &aHandle)
1364 +{
1365 + return NS_ERROR_NOT_IMPLEMENTED;
1366 +}
1367 +
1368 +// nsIFontMetricsPango impl
1369 +
1370 +nsresult
1371 +nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength,
1372 + nscoord& aWidth,
1373 + nsRenderingContextGTK *aContext)
1374 +{
1375 + PangoLayout *layout = pango_layout_new(mPangoContext);
1376 +
1377 + pango_layout_set_text(layout, aString, aLength);
1378 +
1379 + int width, height;
1380 +
1381 + pango_layout_get_size(layout, &width, &height);
1382 +
1383 + width /= PANGO_SCALE;
1384 +
1385 + g_object_unref(layout);
1386 +
1387 + float f;
1388 + f = mDeviceContext->DevUnitsToAppUnits();
1389 + aWidth = NSToCoordRound(width * f);
1390 +
1391 + // printf("GetWidth (char *) %d\n", aWidth);
1392 +
1393 + return NS_OK;
1394 +}
1395 +
1396 +nsresult
1397 +nsFontMetricsPango::GetWidth(const PRUnichar* aString, PRUint32 aLength,
1398 + nscoord& aWidth, PRInt32 *aFontID,
1399 + nsRenderingContextGTK *aContext)
1400 +{
1401 + nsresult rv = NS_OK;
1402 + PangoLayout *layout = pango_layout_new(mPangoContext);
1403 +
1404 + gchar *text = g_utf16_to_utf8(aString, aLength,
1405 + NULL, NULL, NULL);
1406 +
1407 + if (!text) {
1408 + aWidth = 0;
1409 +#ifdef DEBUG
1410 + NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
1411 + DUMP_PRUNICHAR(aString, aLength)
1412 +#endif
1413 + rv = NS_ERROR_FAILURE;
1414 + goto loser;
1415 + }
1416 +
1417 + gint width, height;
1418 +
1419 + pango_layout_set_text(layout, text, strlen(text));
1420 + pango_layout_get_size(layout, &width, &height);
1421 +
1422 + width /= PANGO_SCALE;
1423 +
1424 + float f;
1425 + f = mDeviceContext->DevUnitsToAppUnits();
1426 + aWidth = NSToCoordRound(width * f);
1427 +
1428 + // printf("GetWidth %d\n", aWidth);
1429 +
1430 + loser:
1431 + g_free(text);
1432 + g_object_unref(layout);
1433 +
1434 + return rv;
1435 +}
1436 +
1437 +
1438 +nsresult
1439 +nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
1440 + PRUint32 aLength,
1441 + nsTextDimensions& aDimensions,
1442 + PRInt32* aFontID,
1443 + nsRenderingContextGTK *aContext)
1444 +{
1445 + nsresult rv = NS_OK;
1446 +
1447 + PangoLayout *layout = pango_layout_new(mPangoContext);
1448 +
1449 + gchar *text = g_utf16_to_utf8(aString, aLength,
1450 + NULL, NULL, NULL);
1451 +
1452 + if (!text) {
1453 +#ifdef DEBUG
1454 + NS_WARNING("nsFontMetricsPango::GetTextDimensions invalid unicode to follow");
1455 + DUMP_PRUNICHAR(aString, aLength)
1456 +#endif
1457 + aDimensions.width = 0;
1458 + aDimensions.ascent = 0;
1459 + aDimensions.descent = 0;
1460 +
1461 + rv = NS_ERROR_FAILURE;
1462 + goto loser;
1463 + }
1464 +
1465 +
1466 + pango_layout_set_text(layout, text, strlen(text));
1467 +
1468 + // Get the logical extents
1469 + PangoLayoutLine *line;
1470 + if (pango_layout_get_line_count(layout) != 1) {
1471 + printf("Warning: more than one line!\n");
1472 + }
1473 + line = pango_layout_get_line(layout, 0);
1474 +
1475 + PangoRectangle rect;
1476 + pango_layout_line_get_extents(line, NULL, &rect);
1477 +
1478 + float P2T;
1479 + P2T = mDeviceContext->DevUnitsToAppUnits();
1480 +
1481 + aDimensions.width = NSToCoordRound(rect.width / PANGO_SCALE * P2T);
1482 + aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(rect) / PANGO_SCALE * P2T);
1483 + aDimensions.descent = NSToCoordRound(PANGO_DESCENT(rect) / PANGO_SCALE * P2T);
1484 +
1485 + // printf("GetTextDimensions %d %d %d\n", aDimensions.width,
1486 + //aDimensions.ascent, aDimensions.descent);
1487 +
1488 + loser:
1489 + g_free(text);
1490 + g_object_unref(layout);
1491 +
1492 + return rv;
1493 +}
1494 +
1495 +nsresult
1496 +nsFontMetricsPango::GetTextDimensions(const char* aString,
1497 + PRInt32 aLength,
1498 + PRInt32 aAvailWidth,
1499 + PRInt32* aBreaks,
1500 + PRInt32 aNumBreaks,
1501 + nsTextDimensions& aDimensions,
1502 + PRInt32& aNumCharsFit,
1503 + nsTextDimensions& aLastWordDimensions,
1504 + PRInt32* aFontID,
1505 + nsRenderingContextGTK *aContext)
1506 +{
1507 +
1508 + return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks,
1509 + aNumBreaks, aDimensions, aNumCharsFit,
1510 + aLastWordDimensions, aContext);
1511 +
1512 +}
1513 +
1514 +nsresult
1515 +nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
1516 + PRInt32 aLength,
1517 + PRInt32 aAvailWidth,
1518 + PRInt32* aBreaks,
1519 + PRInt32 aNumBreaks,
1520 + nsTextDimensions& aDimensions,
1521 + PRInt32& aNumCharsFit,
1522 + nsTextDimensions& aLastWordDimensions,
1523 + PRInt32* aFontID,
1524 + nsRenderingContextGTK *aContext)
1525 +{
1526 + nsresult rv = NS_OK;
1527 + PRInt32 curBreak = 0;
1528 + gchar *curChar;
1529 +
1530 + PRInt32 *utf8Breaks = new PRInt32[aNumBreaks];
1531 +
1532 + gchar *text = g_utf16_to_utf8(aString, (PRInt32)aLength,
1533 + NULL, NULL, NULL);
1534 +
1535 + curChar = text;
1536 +
1537 + if (!text) {
1538 +#ifdef DEBUG
1539 + NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
1540 + DUMP_PRUNICHAR(aString, (PRUint32)aLength)
1541 +#endif
1542 + rv = NS_ERROR_FAILURE;
1543 + goto loser;
1544 + }
1545 +
1546 + // Covert the utf16 break offsets to utf8 break offsets
1547 + for (PRInt32 curOffset=0; curOffset < aLength;
1548 + curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
1549 + if (aBreaks[curBreak] == curOffset) {
1550 + utf8Breaks[curBreak] = curChar - text;
1551 + curBreak++;
1552 + }
1553 +
1554 + if (IS_HIGH_SURROGATE(aString[curOffset]))
1555 + curOffset++;
1556 + }
1557 +
1558 + // Always catch the last break
1559 + utf8Breaks[curBreak] = curChar - text;
1560 +
1561 +#if 0
1562 + if (strlen(text) != aLength) {
1563 + printf("Different lengths for utf16 %d and utf8 %d\n", aLength, strlen(text));
1564 + DUMP_PRUNICHAR(aString, aLength)
1565 + DUMP_PRUNICHAR(text, strlen(text))
1566 + for (PRInt32 i = 0; i < aNumBreaks; ++i) {
1567 + printf(" break %d utf16 %d utf8 %d\n", i, aBreaks[i], utf8Breaks[i]);
1568 + }
1569 + }
1570 +#endif
1571 +
1572 + // We'll use curBreak to indicate which of the breaks end up being
1573 + // used for the break point for this line.
1574 + curBreak = 0;
1575 + rv = GetTextDimensionsInternal(text, strlen(text), aAvailWidth, utf8Breaks,
1576 + aNumBreaks, aDimensions, aNumCharsFit,
1577 + aLastWordDimensions, aContext);
1578 +
1579 + // Figure out which of the breaks we ended up using to convert
1580 + // back to utf16 - start from the end.
1581 + for (PRInt32 i = aNumBreaks - 1; i >= 0; --i) {
1582 + if (utf8Breaks[i] == aNumCharsFit) {
1583 + // if (aNumCharsFit != aBreaks[i])
1584 + // printf("Fixing utf8 -> utf16 %d -> %d\n", aNumCharsFit, aBreaks[i]);
1585 + aNumCharsFit = aBreaks[i];
1586 + break;
1587 + }
1588 + }
1589 +
1590 + loser:
1591 + if (text)
1592 + g_free(text);
1593 +
1594 + delete[] utf8Breaks;
1595 +
1596 + return rv;
1597 +}
1598 +
1599 +nsresult
1600 +nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength,
1601 + nscoord aX, nscoord aY,
1602 + const nscoord* aSpacing,
1603 + nsRenderingContextGTK *aContext,
1604 + nsDrawingSurfaceGTK *aSurface)
1605 +{
1606 + PangoLayout *layout = pango_layout_new(mPangoContext);
1607 +
1608 + pango_layout_set_text(layout, aString, aLength);
1609 +
1610 + int x = aX;
1611 + int y = aY;
1612 +
1613 + aContext->GetTranMatrix()->TransformCoord(&x, &y);
1614 +
1615 + PangoLayoutLine *line;
1616 + if (pango_layout_get_line_count(layout) != 1) {
1617 + printf("Warning: more than one line!\n");
1618 + }
1619 + line = pango_layout_get_line(layout, 0);
1620 +
1621 + aContext->UpdateGC();
1622 + GdkGC *gc = aContext->GetGC();
1623 +
1624 + if (aSpacing && *aSpacing) {
1625 + DrawStringSlowly(aString, NULL, aLength, aSurface->GetDrawable(),
1626 + gc, x, y, line, aSpacing);
1627 + }
1628 + else {
1629 + gdk_draw_layout_line(aSurface->GetDrawable(), gc,
1630 + x, y,
1631 + line);
1632 + }
1633 +
1634 + g_object_unref(gc);
1635 + g_object_unref(layout);
1636 +
1637 + // printf("DrawString (char *)\n");
1638 +
1639 + return NS_OK;
1640 +}
1641 +
1642 +nsresult
1643 +nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
1644 + nscoord aX, nscoord aY,
1645 + PRInt32 aFontID,
1646 + const nscoord* aSpacing,
1647 + nsRenderingContextGTK *aContext,
1648 + nsDrawingSurfaceGTK *aSurface)
1649 +{
1650 + nsresult rv = NS_OK;
1651 + int x = aX;
1652 + int y = aY;
1653 +
1654 + aContext->UpdateGC();
1655 + GdkGC *gc = aContext->GetGC();
1656 +
1657 + PangoLayout *layout = pango_layout_new(mPangoContext);
1658 +
1659 + gchar *text = g_utf16_to_utf8(aString, aLength,
1660 + NULL, NULL, NULL);
1661 +
1662 + if (!text) {
1663 +#ifdef DEBUG
1664 + NS_WARNING("nsFontMetricsPango::DrawString invalid unicode to follow");
1665 + DUMP_PRUNICHAR(aString, aLength)
1666 +#endif
1667 + rv = NS_ERROR_FAILURE;
1668 + goto loser;
1669 + }
1670 +
1671 + pango_layout_set_text(layout, text, strlen(text));
1672 +
1673 + aContext->GetTranMatrix()->TransformCoord(&x, &y);
1674 +
1675 + PangoLayoutLine *line;
1676 + if (pango_layout_get_line_count(layout) != 1) {
1677 + printf("Warning: more than one line!\n");
1678 + }
1679 + line = pango_layout_get_line(layout, 0);
1680 +
1681 + if (aSpacing && *aSpacing) {
1682 + DrawStringSlowly(text, aString, aLength, aSurface->GetDrawable(),
1683 + gc, x, y, line, aSpacing);
1684 + }
1685 + else {
1686 + gdk_draw_layout_line(aSurface->GetDrawable(), gc,
1687 + x, y,
1688 + line);
1689 + }
1690 +
1691 + loser:
1692 +
1693 + g_free(text);
1694 + g_object_unref(gc);
1695 + g_object_unref(layout);
1696 +
1697 + // printf("DrawString\n");
1698 +
1699 + return rv;
1700 +}
1701 +
1702 +#ifdef MOZ_MATHML
1703 +nsresult
1704 +nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
1705 + nsBoundingMetrics &aBoundingMetrics,
1706 + nsRenderingContextGTK *aContext)
1707 +{
1708 + printf("GetBoundingMetrics (char *)\n");
1709 + return NS_ERROR_FAILURE;
1710 +}
1711 +
1712 +nsresult
1713 +nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString,
1714 + PRUint32 aLength,
1715 + nsBoundingMetrics &aBoundingMetrics,
1716 + PRInt32 *aFontID,
1717 + nsRenderingContextGTK *aContext)
1718 +{
1719 + nsresult rv = NS_OK;
1720 + PangoLayout *layout = pango_layout_new(mPangoContext);
1721 +
1722 + gchar *text = g_utf16_to_utf8(aString, aLength,
1723 + NULL, NULL, NULL);
1724 +
1725 + if (!text) {
1726 +#ifdef DEBUG
1727 + NS_WARNING("nsFontMetricsPango::GetBoundingMetrics invalid unicode to follow");
1728 + DUMP_PRUNICHAR(aString, aLength)
1729 +#endif
1730 + aBoundingMetrics.leftBearing = 0;
1731 + aBoundingMetrics.rightBearing = 0;
1732 + aBoundingMetrics.width = 0;
1733 + aBoundingMetrics.ascent = 0;
1734 + aBoundingMetrics.descent = 0;
1735 +
1736 + rv = NS_ERROR_FAILURE;
1737 + goto loser;
1738 + }
1739 +
1740 + pango_layout_set_text(layout, text, strlen(text));
1741 +
1742 + // Get the logical extents
1743 + PangoLayoutLine *line;
1744 + if (pango_layout_get_line_count(layout) != 1) {
1745 + printf("Warning: more than one line!\n");
1746 + }
1747 + line = pango_layout_get_line(layout, 0);
1748 +
1749 + // Get the ink extents
1750 + PangoRectangle rect;
1751 + pango_layout_line_get_extents(line, NULL, &rect);
1752 +
1753 + float P2T;
1754 + P2T = mDeviceContext->DevUnitsToAppUnits();
1755 +
1756 + aBoundingMetrics.leftBearing =
1757 + NSToCoordRound(rect.x / PANGO_SCALE * P2T);
1758 + aBoundingMetrics.rightBearing =
1759 + NSToCoordRound(rect.width / PANGO_SCALE * P2T);
1760 + aBoundingMetrics.width = NSToCoordRound((rect.x + rect.width) / PANGO_SCALE * P2T);
1761 + aBoundingMetrics.ascent = NSToCoordRound(rect.y / PANGO_SCALE * P2T);
1762 + aBoundingMetrics.descent = NSToCoordRound(rect.height / PANGO_SCALE * P2T);
1763 +
1764 + loser:
1765 + g_free(text);
1766 + g_object_unref(layout);
1767 +
1768 + return rv;
1769 +}
1770 +
1771 +#endif /* MOZ_MATHML */
1772 +
1773 +GdkFont*
1774 +nsFontMetricsPango::GetCurrentGDKFont(void)
1775 +{
1776 + return nsnull;
1777 +}
1778 +
1779 +nsresult
1780 +nsFontMetricsPango::SetRightToLeftText(PRBool aIsRTL)
1781 +{
1782 + if (aIsRTL) {
1783 + if (!mRTLPangoContext) {
1784 + mRTLPangoContext = pango_xft_get_context(GDK_DISPLAY(), 0);
1785 + pango_context_set_base_dir(mRTLPangoContext, PANGO_DIRECTION_RTL);
1786 +
1787 + gdk_pango_context_set_colormap(mRTLPangoContext, gdk_rgb_get_cmap());
1788 + pango_context_set_language(mRTLPangoContext, GetPangoLanguage(mLangGroup));
1789 + pango_context_set_font_description(mRTLPangoContext, mPangoFontDesc);
1790 + }
1791 + mPangoContext = mRTLPangoContext;
1792 + }
1793 + else {
1794 + mPangoContext = mLTRPangoContext;
1795 + }
1796 +
1797 + mIsRTL = aIsRTL;
1798 + return NS_OK;
1799 +}
1800 +
1801 +/* static */
1802 +PRUint32
1803 +nsFontMetricsPango::GetHints(void)
1804 +{
1805 + return (NS_RENDERING_HINT_BIDI_REORDERING |
1806 + NS_RENDERING_HINT_ARABIC_SHAPING |
1807 + NS_RENDERING_HINT_FAST_MEASURE);
1808 +}
1809 +
1810 +/* static */
1811 +nsresult
1812 +nsFontMetricsPango::FamilyExists(nsIDeviceContext *aDevice,
1813 + const nsString &aName)
1814 +{
1815 + if (!IsASCIIFontName(aName))
1816 + return NS_ERROR_FAILURE;
1817 +
1818 + NS_ConvertUCS2toUTF8 name(aName);
1819 +
1820 + nsresult rv = NS_ERROR_FAILURE;
1821 + PangoContext *context = pango_xft_get_context(GDK_DISPLAY(), 0);
1822 + PangoFontFamily **familyList;
1823 + int n;
1824 +
1825 + pango_context_list_families(context, &familyList, &n);
1826 +
1827 + for (int i=0; i < n; i++) {
1828 + const char *tmpname = pango_font_family_get_name(familyList[i]);
1829 + if (!Compare(nsDependentCString(tmpname), name,
1830 + nsCaseInsensitiveCStringComparator())) {
1831 + rv = NS_OK;
1832 + break;
1833 + }
1834 + }
1835 +
1836 + g_free(familyList);
1837 + g_object_unref(context);
1838 +
1839 + return rv;
1840 +}
1841 +
1842 +// Private Methods
1843 +
1844 +nsresult
1845 +nsFontMetricsPango::RealizeFont(void)
1846 +{
1847 + nsCString familyList;
1848 + // Create and fill out the font description.
1849 + mPangoFontDesc = pango_font_description_new();
1850 +
1851 + // Add CSS names - walk the list of fonts, adding the generic as
1852 + // the last font
1853 + for (int i=0; i < mFontList.Count(); ++i) {
1854 + // if this was a generic name, break out of the loop since we
1855 + // don't want to add it to the pattern yet
1856 + if (mFontIsGeneric[i])
1857 + break;;
1858 +
1859 + nsCString *familyName = mFontList.CStringAt(i);
1860 + familyList.Append(familyName->get());
1861 + familyList.Append(',');
1862 + }
1863 +
1864 + // If there's a generic add a pref for the generic if there's one
1865 + // set.
1866 + if (mGenericFont && !mFont->systemFont) {
1867 + nsCString name;
1868 + name += "font.name.";
1869 + name += mGenericFont->get();
1870 + name += ".";
1871 +
1872 + nsString langGroup;
1873 + mLangGroup->ToString(langGroup);
1874 +
1875 + name.AppendWithConversion(langGroup);
1876 +
1877 + nsCOMPtr<nsIPref> pref;
1878 + pref = do_GetService(NS_PREF_CONTRACTID);
1879 + if (pref) {
1880 + nsresult rv;
1881 + nsXPIDLCString value;
1882 + rv = pref->GetCharPref(name.get(), getter_Copies(value));
1883 +
1884 + // we ignore prefs that have three hypens since they are X
1885 + // style prefs.
1886 + if (FFRECountHyphens(value) < 3) {
1887 + nsCString tmpstr;
1888 + tmpstr.Append(value);
1889 +
1890 + familyList.Append(tmpstr);
1891 + familyList.Append(',');
1892 + }
1893 + }
1894 + }
1895 +
1896 + // Add the generic if there is one.
1897 + if (mGenericFont && !mFont->systemFont) {
1898 + familyList.Append(mGenericFont->get());
1899 + familyList.Append(',');
1900 + }
1901 +
1902 + // Set the family
1903 + pango_font_description_set_family(mPangoFontDesc,
1904 + familyList.get());
1905 +
1906 + // Set the point size
1907 + pango_font_description_set_size(mPangoFontDesc,
1908 + (gint)(mPointSize * PANGO_SCALE));
1909 +
1910 + // Set the style
1911 + pango_font_description_set_style(mPangoFontDesc,
1912 + CalculateStyle(mFont->style));
1913 +
1914 + // Set the weight
1915 + pango_font_description_set_weight(mPangoFontDesc,
1916 + CalculateWeight(mFont->weight));
1917 +
1918 + // Now that we have the font description set up, create the
1919 + // context.
1920 + mLTRPangoContext = pango_xft_get_context(GDK_DISPLAY(), 0);
1921 + mPangoContext = mLTRPangoContext;
1922 +
1923 + // Set the color map so we can draw later.
1924 + gdk_pango_context_set_colormap(mPangoContext, gdk_rgb_get_cmap());
1925 +
1926 + // Set the pango language now that we have a context
1927 + pango_context_set_language(mPangoContext, GetPangoLanguage(mLangGroup));
1928 +
1929 + // And attach the font description to this context
1930 + pango_context_set_font_description(mPangoContext, mPangoFontDesc);
1931 +
1932 + return NS_OK;
1933 +}
1934 +
1935 +/* static */
1936 +PRBool
1937 +nsFontMetricsPango::EnumFontCallback(const nsString &aFamily,
1938 + PRBool aIsGeneric, void *aData)
1939 +{
1940 + // make sure it's an ascii name, if not then return and continue
1941 + // enumerating
1942 + if (!IsASCIIFontName(aFamily))
1943 + return PR_TRUE;
1944 +
1945 + nsCAutoString name;
1946 + name.AssignWithConversion(aFamily.get());
1947 + ToLowerCase(name);
1948 + nsFontMetricsPango *metrics = (nsFontMetricsPango *)aData;
1949 + metrics->mFontList.AppendCString(name);
1950 + metrics->mFontIsGeneric.AppendElement((void *)aIsGeneric);
1951 + if (aIsGeneric) {
1952 + metrics->mGenericFont =
1953 + metrics->mFontList.CStringAt(metrics->mFontList.Count() - 1);
1954 + return PR_FALSE; // stop processing
1955 + }
1956 +
1957 + return PR_TRUE; // keep processing
1958 +}
1959 +
1960 +/*
1961 + * This is only used when there's per-character spacing happening.
1962 + * Well, really it can be either line or character spacing but it's
1963 + * just turtles all the way down!
1964 + */
1965 +
1966 +void
1967 +nsFontMetricsPango::DrawStringSlowly(const gchar *aText,
1968 + const PRUnichar *aOrigString,
1969 + PRUint32 aLength,
1970 + GdkDrawable *aDrawable,
1971 + GdkGC *aGC, gint aX, gint aY,
1972 + PangoLayoutLine *aLine,
1973 + const nscoord *aSpacing)
1974 +{
1975 + float app2dev;
1976 + app2dev = mDeviceContext->AppUnitsToDevUnits();
1977 + gint offset = 0;
1978 +
1979 + /*
1980 + * We walk the list of glyphs returned in each layout run,
1981 + * matching up the glyphs with the characters in the source text.
1982 + * We use the aSpacing argument to figure out where to place those
1983 + * glyphs. It's important to note that since the string we're
1984 + * working with is in UTF-8 while the spacing argument assumes
1985 + * that offset will be part of the UTF-16 string. Logical
1986 + * attributes in pango are in byte offsets in the UTF-8 string, so
1987 + * we need to store the offsets based on the UTF-8 string.
1988 + */
1989 + nscoord *utf8spacing = new nscoord[strlen(aText)];
1990 +
1991 + if (aOrigString) {
1992 + const gchar *curChar = aText;
1993 + bzero(utf8spacing, sizeof(nscoord) * strlen(aText));
1994 +
1995 + // Covert the utf16 spacing offsets to utf8 spacing offsets
1996 + for (PRUint32 curOffset=0; curOffset < aLength;
1997 + curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
1998 + utf8spacing[curChar - aText] = aSpacing[curOffset];
1999 +
2000 + if (IS_HIGH_SURROGATE(aOrigString[curOffset]))
2001 + curOffset++;
2002 + }
2003 + }
2004 + else {
2005 + memcpy(utf8spacing, aSpacing, (sizeof(nscoord *) * aLength));
2006 + }
2007 +
2008 + gint curRun = 0;
2009 +
2010 + for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
2011 + tmpList = tmpList->next, curRun++) {
2012 + PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data;
2013 + gint tmpOffset = 0;
2014 +
2015 + /* printf(" Rendering run %d: \"%s\"\n", curRun,
2016 + &aText[layoutRun->item->offset]); */
2017 +
2018 + for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) {
2019 + /* printf("glyph %d offset %d orig width %d new width %d\n", i,
2020 + * layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset,
2021 + * layoutRun->glyphs->glyphs[i].geometry.width,
2022 + * (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset] * app2dev * PANGO_SCALE));
2023 + */
2024 + gint thisOffset = (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset]
2025 + * app2dev * PANGO_SCALE);
2026 + layoutRun->glyphs->glyphs[i].geometry.width = thisOffset;
2027 + tmpOffset += thisOffset;
2028 + }
2029 +
2030 + /* printf(" rendering at X coord %d\n", aX + offset); */
2031 +
2032 + gdk_draw_glyphs(aDrawable, aGC, layoutRun->item->analysis.font,
2033 + aX + (gint)(offset / PANGO_SCALE), aY, layoutRun->glyphs);
2034 +
2035 + offset += tmpOffset;
2036 + }
2037 +
2038 + delete[] utf8spacing;
2039 +}
2040 +
2041 +nsresult
2042 +nsFontMetricsPango::GetTextDimensionsInternal(const gchar* aString,
2043 + PRInt32 aLength,
2044 + PRInt32 aAvailWidth,
2045 + PRInt32* aBreaks,
2046 + PRInt32 aNumBreaks,
2047 + nsTextDimensions& aDimensions,
2048 + PRInt32& aNumCharsFit,
2049 + nsTextDimensions& aLastWordDimensions,
2050 + nsRenderingContextGTK *aContext)
2051 +{
2052 + NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");
2053 +
2054 + // If we need to back up this state represents the last place
2055 + // we could break. We can use this to avoid remeasuring text
2056 + PRInt32 prevBreakState_BreakIndex = -1; // not known
2057 + // (hasn't been computed)
2058 + nscoord prevBreakState_Width = 0; // accumulated width to this point
2059 +
2060 + // Initialize OUT parameters
2061 + GetMaxAscent(aLastWordDimensions.ascent);
2062 + GetMaxDescent(aLastWordDimensions.descent);
2063 + aLastWordDimensions.width = -1;
2064 + aNumCharsFit = 0;
2065 +
2066 + // Iterate each character in the string and determine which font to use
2067 + nscoord width = 0;
2068 + PRInt32 start = 0;
2069 + nscoord aveCharWidth;
2070 + GetAveCharWidth(aveCharWidth);
2071 +
2072 + while (start < aLength) {
2073 + // Estimate how many characters will fit. Do that by
2074 + // diving the available space by the average character
2075 + // width. Make sure the estimated number of characters is
2076 + // at least 1
2077 + PRInt32 estimatedNumChars = 0;
2078 +
2079 + if (aveCharWidth > 0)
2080 + estimatedNumChars = (aAvailWidth - width) / aveCharWidth;
2081 +
2082 + if (estimatedNumChars < 1)
2083 + estimatedNumChars = 1;
2084 +
2085 + // Find the nearest break offset
2086 + PRInt32 estimatedBreakOffset = start + estimatedNumChars;
2087 + PRInt32 breakIndex;
2088 + nscoord numChars;
2089 +
2090 + // Find the nearest place to break that is less than or equal to
2091 + // the estimated break offset
2092 + if (aLength <= estimatedBreakOffset) {
2093 + // All the characters should fit
2094 + numChars = aLength - start;
2095 + breakIndex = aNumBreaks - 1;
2096 + }
2097 + else {
2098 + breakIndex = prevBreakState_BreakIndex;
2099 + while (((breakIndex + 1) < aNumBreaks) &&
2100 + (aBreaks[breakIndex + 1] <= estimatedBreakOffset)) {
2101 + ++breakIndex;
2102 + }
2103 +
2104 + if (breakIndex == prevBreakState_BreakIndex) {
2105 + ++breakIndex; // make sure we advanced past the
2106 + // previous break index
2107 + }
2108 +
2109 + numChars = aBreaks[breakIndex] - start;
2110 + }
2111 +
2112 + // Measure the text
2113 + nscoord twWidth = 0;
2114 + if ((1 == numChars) && (aString[start] == ' '))
2115 + GetSpaceWidth(twWidth);
2116 + else if (numChars > 0)
2117 + GetWidth(&aString[start], numChars, twWidth, aContext);
2118 +
2119 + // See if the text fits
2120 + PRBool textFits = (twWidth + width) <= aAvailWidth;
2121 +
2122 + // If the text fits then update the width and the number of
2123 + // characters that fit
2124 + if (textFits) {
2125 + aNumCharsFit += numChars;
2126 + width += twWidth;
2127 + start += numChars;
2128 +
2129 + // This is a good spot to back up to if we need to so remember
2130 + // this state
2131 + prevBreakState_BreakIndex = breakIndex;
2132 + prevBreakState_Width = width;
2133 + }
2134 + else {
2135 + // See if we can just back up to the previous saved
2136 + // state and not have to measure any text
2137 + if (prevBreakState_BreakIndex > 0) {
2138 + // If the previous break index is just before the
2139 + // current break index then we can use it
2140 + if (prevBreakState_BreakIndex == (breakIndex - 1)) {
2141 + aNumCharsFit = aBreaks[prevBreakState_BreakIndex];
2142 + width = prevBreakState_Width;
2143 + break;
2144 + }
2145 + }
2146 +
2147 + // We can't just revert to the previous break state
2148 + if (0 == breakIndex) {
2149 + // There's no place to back up to, so even though
2150 + // the text doesn't fit return it anyway
2151 + aNumCharsFit += numChars;
2152 + width += twWidth;
2153 + break;
2154 + }
2155 +
2156 + // Repeatedly back up until we get to where the text
2157 + // fits or we're all the way back to the first word
2158 + width += twWidth;
2159 + while ((breakIndex >= 1) && (width > aAvailWidth)) {
2160 + twWidth = 0;
2161 + start = aBreaks[breakIndex - 1];
2162 + numChars = aBreaks[breakIndex] - start;
2163 +
2164 + if ((1 == numChars) && (aString[start] == ' '))
2165 + GetSpaceWidth(twWidth);
2166 + else if (numChars > 0)
2167 + GetWidth(&aString[start], numChars, twWidth,
2168 + aContext);
2169 + width -= twWidth;
2170 + aNumCharsFit = start;
2171 + breakIndex--;
2172 + }
2173 + break;
2174 + }
2175 + }
2176 +
2177 + aDimensions.width = width;
2178 + GetMaxAscent(aDimensions.ascent);
2179 + GetMaxDescent(aDimensions.descent);
2180 +
2181 + /* printf("aDimensions %d %d %d aLastWordDimensions %d %d %d aNumCharsFit %d\n",
2182 + aDimensions.width, aDimensions.ascent, aDimensions.descent,
2183 + aLastWordDimensions.width, aLastWordDimensions.ascent, aLastWordDimensions.descent,
2184 + aNumCharsFit); */
2185 +
2186 + return NS_OK;
2187 +}
2188 +
2189 +/* static */
2190 +PRBool
2191 +IsASCIIFontName(const nsString& aName)
2192 +{
2193 + PRUint32 len = aName.Length();
2194 + const PRUnichar* str = aName.get();
2195 + for (PRUint32 i = 0; i < len; i++) {
2196 + /*
2197 + * X font names are printable ASCII, ignore others (for now)
2198 + */
2199 + if ((str[i] < 0x20) || (str[i] > 0x7E)) {
2200 + return PR_FALSE;
2201 + }
2202 + }
2203 +
2204 + return PR_TRUE;
2205 +}
2206 +
2207 +/* static */
2208 +int
2209 +FFRECountHyphens (nsACString &aFFREName)
2210 +{
2211 + int h = 0;
2212 + PRInt32 hyphen = 0;
2213 + while ((hyphen = aFFREName.FindChar('-', hyphen)) >= 0) {
2214 + ++h;
2215 + ++hyphen;
2216 + }
2217 + return h;
2218 +}
2219 +
2220 +/* static */
2221 +PangoLanguage *
2222 +GetPangoLanguage(nsIAtom *aLangGroup)
2223 +{
2224 + // Find the FC lang group for this lang group
2225 + nsCAutoString cname;
2226 + aLangGroup->ToUTF8String(cname);
2227 +
2228 + // see if the lang group needs to be translated from mozilla's
2229 + // internal mapping into fontconfig's
2230 + const struct MozPangoLangGroup *langGroup;
2231 + langGroup = FindPangoLangGroup(cname);
2232 +
2233 + // if there's no lang group, just use the lang group as it was
2234 + // passed to us
2235 + //
2236 + // we're casting away the const here for the strings - should be
2237 + // safe.
2238 + if (!langGroup)
2239 + return pango_language_from_string(cname.get());
2240 + else if (langGroup->PangoLang)
2241 + return pango_language_from_string(langGroup->PangoLang);
2242 +
2243 + return pango_language_from_string("en");
2244 +}
2245 +
2246 +/* static */
2247 +const MozPangoLangGroup*
2248 +FindPangoLangGroup (nsACString &aLangGroup)
2249 +{
2250 + for (unsigned int i=0; i < NUM_PANGO_LANG_GROUPS; ++i) {
2251 + if (aLangGroup.Equals(MozPangoLangGroups[i].mozLangGroup,
2252 + nsCaseInsensitiveCStringComparator())) {
2253 + return &MozPangoLangGroups[i];
2254 + }
2255 + }
2256 +
2257 + return nsnull;
2258 +}
2259 +
2260 +/* static */
2261 +void
2262 +FreeGlobals(void)
2263 +{
2264 +}
2265 +
2266 +/* static */
2267 +PangoStyle
2268 +CalculateStyle(PRUint8 aStyle)
2269 +{
2270 + switch(aStyle) {
2271 + case NS_FONT_STYLE_ITALIC:
2272 + return PANGO_STYLE_OBLIQUE;
2273 + break;
2274 + case NS_FONT_STYLE_OBLIQUE:
2275 + return PANGO_STYLE_OBLIQUE;
2276 + break;
2277 + }
2278 +
2279 + return PANGO_STYLE_NORMAL;
2280 +}
2281 +
2282 +/* static */
2283 +PangoWeight
2284 +CalculateWeight (PRUint16 aWeight)
2285 +{
2286 + /*
2287 + * weights come in two parts crammed into one
2288 + * integer -- the "base" weight is weight / 100,
2289 + * the rest of the value is the "offset" from that
2290 + * weight -- the number of steps to move to adjust
2291 + * the weight in the list of supported font weights,
2292 + * this value can be negative or positive.
2293 + */
2294 + PRInt32 baseWeight = (aWeight + 50) / 100;
2295 + PRInt32 offset = aWeight - baseWeight * 100;
2296 +
2297 + /* clip weights to range 0 to 9 */
2298 + if (baseWeight < 0)
2299 + baseWeight = 0;
2300 + if (baseWeight > 9)
2301 + baseWeight = 9;
2302 +
2303 + /* Map from weight value to fcWeights index */
2304 + static int fcWeightLookup[10] = {
2305 + 0, 0, 0, 0, 1, 1, 2, 3, 3, 4,
2306 + };
2307 +
2308 + PRInt32 fcWeight = fcWeightLookup[baseWeight];
2309 +
2310 + /*
2311 + * adjust by the offset value, make sure we stay inside the
2312 + * fcWeights table
2313 + */
2314 + fcWeight += offset;
2315 +
2316 + if (fcWeight < 0)
2317 + fcWeight = 0;
2318 + if (fcWeight > 4)
2319 + fcWeight = 4;
2320 +
2321 + /* Map to final PANGO_WEIGHT value */
2322 + static int fcWeights[5] = {
2323 + 349,
2324 + 499,
2325 + 649,
2326 + 749,
2327 + 999
2328 + };
2329 +
2330 + return (PangoWeight)fcWeights[fcWeight];
2331 +}
2332 +
2333 +/* static */
2334 +nsresult
2335 +EnumFontsPango(nsIAtom* aLangGroup, const char* aGeneric,
2336 + PRUint32* aCount, PRUnichar*** aResult)
2337 +{
2338 + FcPattern *pat = NULL;
2339 + FcObjectSet *os = NULL;
2340 + FcFontSet *fs = NULL;
2341 + nsresult rv = NS_ERROR_FAILURE;
2342 +
2343 + PRUnichar **array = NULL;
2344 + PRUint32 narray = 0;
2345 + PRInt32 serif = 0, sansSerif = 0, monospace = 0, nGenerics;
2346 +
2347 + *aCount = 0;
2348 + *aResult = nsnull;
2349 +
2350 + pat = FcPatternCreate();
2351 + if (!pat)
2352 + goto end;
2353 +
2354 + os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, 0);
2355 + if (!os)
2356 + goto end;
2357 +
2358 + // take the pattern and add the lang group to it
2359 + if (aLangGroup)
2360 + AddLangGroup(pat, aLangGroup);
2361 +
2362 + // get the font list
2363 + fs = FcFontList(0, pat, os);
2364 +
2365 + if (!fs)
2366 + goto end;
2367 +
2368 + if (!fs->nfont) {
2369 + rv = NS_OK;
2370 + goto end;
2371 + }
2372 +
2373 + // Fontconfig supports 3 generic fonts, "serif", "sans-serif", and
2374 + // "monospace", slightly different from CSS's 5.
2375 + if (!aGeneric)
2376 + serif = sansSerif = monospace = 1;
2377 + else if (!strcmp(aGeneric, "serif"))
2378 + serif = 1;
2379 + else if (!strcmp(aGeneric, "sans-serif"))
2380 + sansSerif = 1;
2381 + else if (!strcmp(aGeneric, "monospace"))
2382 + monospace = 1;
2383 + else if (!strcmp(aGeneric, "cursive") || !strcmp(aGeneric, "fantasy"))
2384 + serif = sansSerif = 1;
2385 + else
2386 + NS_NOTREACHED("unexpected generic family");
2387 + nGenerics = serif + sansSerif + monospace;
2388 +
2389 + array = NS_STATIC_CAST(PRUnichar **,
2390 + nsMemory::Alloc((fs->nfont + nGenerics) * sizeof(PRUnichar *)));
2391 + if (!array)
2392 + goto end;
2393 +
2394 + if (serif) {
2395 + PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("serif"));
2396 + if (!name)
2397 + goto end;
2398 + array[narray++] = name;
2399 + }
2400 +
2401 + if (sansSerif) {
2402 + PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("sans-serif"));
2403 + if (!name)
2404 + goto end;
2405 + array[narray++] = name;
2406 + }
2407 +
2408 + if (monospace) {
2409 + PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("monospace"));
2410 + if (!name)
2411 + goto end;
2412 + array[narray++] = name;
2413 + }
2414 +
2415 + for (int i=0; i < fs->nfont; ++i) {
2416 + char *family;
2417 + PRUnichar *name;
2418 +
2419 + // if there's no family, just move to the next iteration
2420 + if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
2421 + (FcChar8 **) &family) != FcResultMatch) {
2422 + continue;
2423 + }
2424 +
2425 + name = NS_STATIC_CAST(PRUnichar *,
2426 + nsMemory::Alloc ((strlen (family) + 1)
2427 + * sizeof (PRUnichar)));
2428 +
2429 + if (!name)
2430 + goto end;
2431 +
2432 + PRUnichar *r = name;
2433 + for (char *f = family; *f; ++f)
2434 + *r++ = *f;
2435 + *r = '\0';
2436 +
2437 + array[narray++] = name;
2438 + }
2439 +
2440 + NS_QuickSort(array + nGenerics, narray - nGenerics, sizeof (PRUnichar*),
2441 + CompareFontNames, nsnull);
2442 +
2443 + *aCount = narray;
2444 + if (narray)
2445 + *aResult = array;
2446 + else
2447 + nsMemory::Free(array);
2448 +
2449 + rv = NS_OK;
2450 +
2451 + end:
2452 + if (NS_FAILED(rv) && array) {
2453 + while (narray)
2454 + nsMemory::Free (array[--narray]);
2455 + nsMemory::Free (array);
2456 + }
2457 + if (pat)
2458 + FcPatternDestroy(pat);
2459 + if (os)
2460 + FcObjectSetDestroy(os);
2461 + if (fs)
2462 + FcFontSetDestroy(fs);
2463 +
2464 + return rv;
2465 +}
2466 +
2467 +/* static */
2468 +int
2469 +CompareFontNames (const void* aArg1, const void* aArg2, void* aClosure)
2470 +{
2471 + const PRUnichar* str1 = *((const PRUnichar**) aArg1);
2472 + const PRUnichar* str2 = *((const PRUnichar**) aArg2);
2473 +
2474 + return nsCRT::strcmp(str1, str2);
2475 +}
2476 +
2477 +
2478 +// nsFontEnumeratorPango class
2479 +
2480 +nsFontEnumeratorPango::nsFontEnumeratorPango()
2481 +{
2482 +}
2483 +
2484 +NS_IMPL_ISUPPORTS1(nsFontEnumeratorPango, nsIFontEnumerator)
2485 +
2486 +NS_IMETHODIMP
2487 +nsFontEnumeratorPango::EnumerateAllFonts(PRUint32 *aCount,
2488 + PRUnichar ***aResult)
2489 +{
2490 + NS_ENSURE_ARG_POINTER(aResult);
2491 + *aResult = nsnull;
2492 + NS_ENSURE_ARG_POINTER(aCount);
2493 + *aCount = 0;
2494 +
2495 + return EnumFontsPango(nsnull, nsnull, aCount, aResult);
2496 +}
2497 +
2498 +NS_IMETHODIMP
2499 +nsFontEnumeratorPango::EnumerateFonts(const char *aLangGroup,
2500 + const char *aGeneric,
2501 + PRUint32 *aCount,
2502 + PRUnichar ***aResult)
2503 +{
2504 + NS_ENSURE_ARG_POINTER(aResult);
2505 + *aResult = nsnull;
2506 + NS_ENSURE_ARG_POINTER(aCount);
2507 + *aCount = 0;
2508 +
2509 + // aLangGroup=null or "" means any (i.e., don't care)
2510 + // aGeneric=null or "" means any (i.e, don't care)
2511 + nsCOMPtr<nsIAtom> langGroup;
2512 + if (aLangGroup && *aLangGroup)
2513 + langGroup = do_GetAtom(aLangGroup);
2514 + const char* generic = nsnull;
2515 + if (aGeneric && *aGeneric)
2516 + generic = aGeneric;
2517 +
2518 + return EnumFontsPango(langGroup, generic, aCount, aResult);
2519 +}
2520 +
2521 +NS_IMETHODIMP
2522 +nsFontEnumeratorPango::HaveFontFor(const char *aLangGroup,
2523 + PRBool *aResult)
2524 +{
2525 + NS_ENSURE_ARG_POINTER(aResult);
2526 + *aResult = PR_FALSE;
2527 + NS_ENSURE_ARG_POINTER(aLangGroup);
2528 +
2529 + *aResult = PR_TRUE; // always return true for now.
2530 + // Finish me - ftang
2531 + return NS_OK;
2532 +}
2533 +
2534 +NS_IMETHODIMP
2535 +nsFontEnumeratorPango::GetDefaultFont(const char *aLangGroup,
2536 + const char *aGeneric,
2537 + PRUnichar **aResult)
2538 +{
2539 + NS_ENSURE_ARG_POINTER(aResult);
2540 + *aResult = nsnull;
2541 +
2542 + // Have a look at nsFontEnumeratorXft::GetDefaultFont for some
2543 + // possible code for this function.
2544 +
2545 + return NS_OK;
2546 +}
2547 +
2548 +NS_IMETHODIMP
2549 +nsFontEnumeratorPango::UpdateFontList(PRBool *_retval)
2550 +{
2551 + *_retval = PR_FALSE; // always return false for now
2552 + return NS_OK;
2553 +}
2554 --- mozilla/gfx/src/gtk/nsRenderingContextGTK.h.foo 2003-02-24 21:38:34.000000000 -0500
2555 +++ mozilla/gfx/src/gtk/nsRenderingContextGTK.h 2004-10-18 22:49:40.000000000 -0400
2556 @@ -194,6 +194,8 @@
2557 const nsRect &aDestBounds, PRUint32 aCopyFlags);
2558 NS_IMETHOD RetrieveCurrentNativeGraphicData(PRUint32 * ngd);
2559
2560 + NS_IMETHOD SetRightToLeftText(PRBool aIsRTL);
2561 +
2562 NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint);
2563 NS_IMETHOD DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect);
2564
2565 --- /dev/null 2004-02-18 10:26:44.000000000 -0500
2566 +++ mozilla/gfx/src/gtk/nsFontMetricsPango.h 2004-10-18 22:49:40.000000000 -0400
2567 @@ -0,0 +1,278 @@
2568 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2569 +/* vim:expandtab:shiftwidth=4:tabstop=4:
2570 + */
2571 +/* ***** BEGIN LICENSE BLOCK *****
2572 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
2573 + *
2574 + * The contents of this file are subject to the Mozilla Public License Version
2575 + * 1.1 (the "License"); you may not use this file except in compliance with
2576 + * the License. You may obtain a copy of the License at
2577 + * http://www.mozilla.org/MPL/
2578 + *
2579 + * Software distributed under the License is distributed on an "AS IS" basis,
2580 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
2581 + * for the specific language governing rights and limitations under the
2582 + * License.
2583 + *
2584 + * The Original Code is mozilla.org code.
2585 + *
2586 + * The Initial Developer of the Original Code Christopher Blizzard
2587 + * <blizzard@mozilla.org>. Portions created by the Initial Developer
2588 + * are Copyright (C) 2002 the Initial Developer. All Rights Reserved.
2589 + *
2590 + * Contributor(s):
2591 + *
2592 + * Alternatively, the contents of this file may be used under the terms of
2593 + * either the GNU General Public License Version 2 or later (the "GPL"), or
2594 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
2595 + * in which case the provisions of the GPL or the LGPL are applicable instead
2596 + * of those above. If you wish to allow use of your version of this file only
2597 + * under the terms of either the GPL or the LGPL, and not to allow others to
2598 + * use your version of this file under the terms of the MPL, indicate your
2599 + * decision by deleting the provisions above and replace them with the notice
2600 + * and other provisions required by the GPL or the LGPL. If you do not delete
2601 + * the provisions above, a recipient may use your version of this file under
2602 + * the terms of any one of the MPL, the GPL or the LGPL.
2603 + *
2604 + * ***** END LICENSE BLOCK ***** */
2605 +
2606 +#include "nsIFontMetrics.h"
2607 +#include "nsIFontEnumerator.h"
2608 +#include "nsCRT.h"
2609 +#include "nsIAtom.h"
2610 +#include "nsString.h"
2611 +#include "nsVoidArray.h"
2612 +#include "nsIFontMetricsGTK.h"
2613 +
2614 +#include <pango/pango.h>
2615 +
2616 +class nsFontMetricsPango : public nsIFontMetricsGTK
2617 +{
2618 +public:
2619 + nsFontMetricsPango();
2620 + virtual ~nsFontMetricsPango();
2621 +
2622 + NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
2623 +
2624 + // nsISupports
2625 + NS_DECL_ISUPPORTS
2626 +
2627 + // nsIFontMetrics
2628 + NS_IMETHOD Init (const nsFont& aFont, nsIAtom* aLangGroup,
2629 + nsIDeviceContext *aContext);
2630 + NS_IMETHOD Destroy();
2631 + NS_IMETHOD GetFont (const nsFont *&aFont);
2632 + NS_IMETHOD GetLangGroup (nsIAtom** aLangGroup);
2633 + NS_IMETHOD GetFontHandle (nsFontHandle &aHandle);
2634 +
2635 + NS_IMETHOD GetXHeight (nscoord& aResult)
2636 + { aResult = mXHeight; return NS_OK; };
2637 +
2638 + NS_IMETHOD GetSuperscriptOffset (nscoord& aResult)
2639 + { aResult = mSuperscriptOffset;
2640 + return NS_OK; };
2641 +
2642 + NS_IMETHOD GetSubscriptOffset (nscoord& aResult)
2643 + { aResult = mSubscriptOffset;
2644 + return NS_OK; };
2645 +
2646 + NS_IMETHOD GetStrikeout (nscoord& aOffset, nscoord& aSize)
2647 + { aOffset = mStrikeoutOffset;
2648 + aSize = mStrikeoutSize;
2649 + return NS_OK; };
2650 +
2651 + NS_IMETHOD GetUnderline (nscoord& aOffset, nscoord& aSize)
2652 + { aOffset = mUnderlineOffset;
2653 + aSize = mUnderlineSize;
2654 + return NS_OK; };
2655 +
2656 + NS_IMETHOD GetHeight (nscoord &aHeight)
2657 + { aHeight = mMaxHeight;
2658 + return NS_OK; };
2659 +
2660 + NS_IMETHOD GetNormalLineHeight (nscoord &aHeight)
2661 + { aHeight = mEmHeight + mLeading;
2662 + return NS_OK; };
2663 +
2664 + NS_IMETHOD GetLeading (nscoord &aLeading)
2665 + { aLeading = mLeading;
2666 + return NS_OK; };
2667 +
2668 + NS_IMETHOD GetEmHeight (nscoord &aHeight)
2669 + { aHeight = mEmHeight;
2670 + return NS_OK; };
2671 +
2672 + NS_IMETHOD GetEmAscent (nscoord &aAscent)
2673 + { aAscent = mEmAscent;
2674 + return NS_OK; };
2675 +
2676 + NS_IMETHOD GetEmDescent (nscoord &aDescent)
2677 + { aDescent = mEmDescent;
2678 + return NS_OK; };
2679 +
2680 + NS_IMETHOD GetMaxHeight (nscoord &aHeight)
2681 + { aHeight = mMaxHeight;
2682 + return NS_OK; };
2683 +
2684 + NS_IMETHOD GetMaxAscent (nscoord &aAscent)
2685 + { aAscent = mMaxAscent;
2686 + return NS_OK; };
2687 +
2688 + NS_IMETHOD GetMaxDescent (nscoord &aDescent)
2689 + { aDescent = mMaxDescent;
2690 + return NS_OK; };
2691 +
2692 + NS_IMETHOD GetMaxAdvance (nscoord &aAdvance)
2693 + { aAdvance = mMaxAdvance;
2694 + return NS_OK; };
2695 +
2696 + NS_IMETHOD GetSpaceWidth (nscoord &aSpaceCharWidth)
2697 + { aSpaceCharWidth = mSpaceWidth;
2698 + return NS_OK; };
2699 +
2700 + NS_IMETHOD GetAveCharWidth (nscoord &aAveCharWidth)
2701 + { aAveCharWidth = mAveCharWidth;
2702 + return NS_OK; };
2703 +
2704 + // nsIFontMetricsGTK (calls from the font rendering layer)
2705 + virtual nsresult GetWidth(const char* aString, PRUint32 aLength,
2706 + nscoord& aWidth,
2707 + nsRenderingContextGTK *aContext);
2708 + virtual nsresult GetWidth(const PRUnichar* aString, PRUint32 aLength,
2709 + nscoord& aWidth, PRInt32 *aFontID,
2710 + nsRenderingContextGTK *aContext);
2711 +
2712 + virtual nsresult GetTextDimensions(const PRUnichar* aString,
2713 + PRUint32 aLength,
2714 + nsTextDimensions& aDimensions,
2715 + PRInt32* aFontID,
2716 + nsRenderingContextGTK *aContext);
2717 + virtual nsresult GetTextDimensions(const char* aString,
2718 + PRInt32 aLength,
2719 + PRInt32 aAvailWidth,
2720 + PRInt32* aBreaks,
2721 + PRInt32 aNumBreaks,
2722 + nsTextDimensions& aDimensions,
2723 + PRInt32& aNumCharsFit,
2724 + nsTextDimensions& aLastWordDimensions,
2725 + PRInt32* aFontID,
2726 + nsRenderingContextGTK *aContext);
2727 + virtual nsresult GetTextDimensions(const PRUnichar* aString,
2728 + PRInt32 aLength,
2729 + PRInt32 aAvailWidth,
2730 + PRInt32* aBreaks,
2731 + PRInt32 aNumBreaks,
2732 + nsTextDimensions& aDimensions,
2733 + PRInt32& aNumCharsFit,
2734 + nsTextDimensions& aLastWordDimensions,
2735 + PRInt32* aFontID,
2736 + nsRenderingContextGTK *aContext);
2737 +
2738 + virtual nsresult DrawString(const char *aString, PRUint32 aLength,
2739 + nscoord aX, nscoord aY,
2740 + const nscoord* aSpacing,
2741 + nsRenderingContextGTK *aContext,
2742 + nsDrawingSurfaceGTK *aSurface);
2743 + virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength,
2744 + nscoord aX, nscoord aY,
2745 + PRInt32 aFontID,
2746 + const nscoord* aSpacing,
2747 + nsRenderingContextGTK *aContext,
2748 + nsDrawingSurfaceGTK *aSurface);
2749 +
2750 +#ifdef MOZ_MATHML
2751 + virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength,
2752 + nsBoundingMetrics &aBoundingMetrics,
2753 + nsRenderingContextGTK *aContext);
2754 + virtual nsresult GetBoundingMetrics(const PRUnichar *aString,
2755 + PRUint32 aLength,
2756 + nsBoundingMetrics &aBoundingMetrics,
2757 + PRInt32 *aFontID,
2758 + nsRenderingContextGTK *aContext);
2759 +#endif /* MOZ_MATHML */
2760 +
2761 + virtual GdkFont* GetCurrentGDKFont(void);
2762 +
2763 + virtual nsresult SetRightToLeftText(PRBool aIsRTL);
2764 +
2765 + // get hints for the font
2766 + static PRUint32 GetHints (void);
2767 +
2768 + // drawing surface methods
2769 + static nsresult FamilyExists (nsIDeviceContext *aDevice,
2770 + const nsString &aName);
2771 +
2772 +private:
2773 +
2774 + // generic font metrics class bits
2775 + nsCStringArray mFontList;
2776 + nsAutoVoidArray mFontIsGeneric;
2777 +
2778 + nsIDeviceContext *mDeviceContext;
2779 + nsCOMPtr<nsIAtom> mLangGroup;
2780 + nsCString *mGenericFont;
2781 + nsFont *mFont;
2782 + float mPointSize;
2783 +
2784 + nsCAutoString mDefaultFont;
2785 +
2786 + // Pango-related items
2787 + PangoFontDescription *mPangoFontDesc;
2788 + PangoContext *mPangoContext;
2789 + PangoContext *mLTRPangoContext;
2790 + PangoContext *mRTLPangoContext;
2791 + PangoAttrList *mPangoAttrList;
2792 + PRBool mIsRTL;
2793 +
2794 + // Cached font metrics
2795 + nscoord mXHeight;
2796 + nscoord mSuperscriptOffset;
2797 + nscoord mSubscriptOffset;
2798 + nscoord mStrikeoutOffset;
2799 + nscoord mStrikeoutSize;
2800 + nscoord mUnderlineOffset;
2801 + nscoord mUnderlineSize;
2802 + nscoord mMaxHeight;
2803 + nscoord mLeading;
2804 + nscoord mEmHeight;
2805 + nscoord mEmAscent;
2806 + nscoord mEmDescent;
2807 + nscoord mMaxAscent;
2808 + nscoord mMaxDescent;
2809 + nscoord mMaxAdvance;
2810 + nscoord mSpaceWidth;
2811 + nscoord mAveCharWidth;
2812 +
2813 + // Private methods
2814 + nsresult RealizeFont(void);
2815 + nsresult CacheFontMetrics(void);
2816 +
2817 + static PRBool EnumFontCallback(const nsString &aFamily,
2818 + PRBool aIsGeneric, void *aData);
2819 +
2820 + void DrawStringSlowly(const gchar *aText,
2821 + const PRUnichar *aOrigString,
2822 + PRUint32 aLength,
2823 + GdkDrawable *aDrawable,
2824 + GdkGC *aGC, gint aX, gint aY,
2825 + PangoLayoutLine *aLine,
2826 + const nscoord *aSpacing);
2827 +
2828 + nsresult GetTextDimensionsInternal(const gchar* aString,
2829 + PRInt32 aLength,
2830 + PRInt32 aAvailWidth,
2831 + PRInt32* aBreaks,
2832 + PRInt32 aNumBreaks,
2833 + nsTextDimensions& aDimensions,
2834 + PRInt32& aNumCharsFit,
2835 + nsTextDimensions& aLastWordDimensions,
2836 + nsRenderingContextGTK *aContext);
2837 +};
2838 +
2839 +class nsFontEnumeratorPango : public nsIFontEnumerator
2840 +{
2841 +public:
2842 + nsFontEnumeratorPango();
2843 + NS_DECL_ISUPPORTS
2844 + NS_DECL_NSIFONTENUMERATOR
2845 +};
2846 --- mozilla/gfx/src/gtk/nsFontMetricsUtils.h.foo 2002-10-11 22:03:32.000000000 -0400
2847 +++ mozilla/gfx/src/gtk/nsFontMetricsUtils.h 2004-10-18 22:49:40.000000000 -0400
2848 @@ -42,9 +42,12 @@
2849 extern PRUint32 NS_FontMetricsGetHints (void);
2850 extern nsresult NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice,
2851 const nsString &aName);
2852 -
2853 #ifdef MOZ_ENABLE_XFT
2854 extern PRBool NS_IsXftEnabled(void);
2855 #endif
2856
2857 +#ifdef MOZ_ENABLE_PANGO
2858 +extern PRBool NS_IsPangoEnabled(void);
2859 +#endif
2860 +
2861 #endif /* __nsFontMetricsUtils_h */
2862 --- mozilla/gfx/src/gtk/nsIFontMetricsGTK.h.foo 2002-10-11 23:00:17.000000000 -0400
2863 +++ mozilla/gfx/src/gtk/nsIFontMetricsGTK.h 2004-10-18 22:49:40.000000000 -0400
2864 @@ -121,6 +121,9 @@
2865 // particular handle.
2866 virtual GdkFont* GetCurrentGDKFont(void) = 0;
2867
2868 + // Set the direction of the text rendering
2869 + virtual nsresult SetRightToLeftText(PRBool aIsRTL) = 0;
2870 +
2871 };
2872
2873 #endif /* __nsIFontMetricsGTK_h */
2874 --- mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp.foo 2004-02-12 11:52:22.000000000 -0500
2875 +++ mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp 2004-10-18 22:49:40.000000000 -0400
2876 @@ -524,6 +524,9 @@
2877
2878 values.foreground.pixel =
2879 gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(mCurrentColor));
2880 + values.foreground.red = (NS_GET_R(mCurrentColor) << 8) | NS_GET_R(mCurrentColor);
2881 + values.foreground.green = (NS_GET_G(mCurrentColor) << 8) | NS_GET_G(mCurrentColor);
2882 + values.foreground.blue = (NS_GET_B(mCurrentColor) << 8) | NS_GET_B(mCurrentColor);
2883 valuesMask = GDK_GC_FOREGROUND;
2884
2885 #ifdef MOZ_ENABLE_COREXFONTS
2886 @@ -1438,6 +1441,11 @@
2887
2888 #endif /* MOZ_MATHML */
2889
2890 +NS_IMETHODIMP nsRenderingContextGTK::SetRightToLeftText(PRBool aIsRTL)
2891 +{
2892 + return mFontMetrics->SetRightToLeftText(aIsRTL);
2893 +}
2894 +
2895 NS_IMETHODIMP nsRenderingContextGTK::DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint)
2896 {
2897 UpdateGC();
2898 --- mozilla/gfx/src/gtk/nsGCCache.cpp.foo 2002-02-02 22:47:15.000000000 -0500
2899 +++ mozilla/gfx/src/gtk/nsGCCache.cpp 2004-10-18 22:49:40.000000000 -0400
2900 @@ -232,98 +232,42 @@
2901 // We have old GC, reuse it and check what
2902 // we have to change
2903
2904 - XGCValues xvalues;
2905 - unsigned long xvalues_mask=0;
2906 + GdkGCValues xvalues;
2907 + int xvalues_mask = 0;
2908
2909 if (entry->clipRegion) {
2910 // set it to none here and then set the clip region with
2911 // gdk_gc_set_clip_region in GetGC()
2912 xvalues.clip_mask = None;
2913 - xvalues_mask |= GCClipMask;
2914 + xvalues_mask |= GDK_GC_CLIP_MASK;
2915 gdk_region_destroy(entry->clipRegion);
2916 entry->clipRegion = NULL;
2917 }
2918
2919 if (entry->gcv.foreground.pixel != gcv->foreground.pixel) {
2920 - xvalues.foreground = gcv->foreground.pixel;
2921 - xvalues_mask |= GCForeground;
2922 + xvalues.foreground.pixel = gcv->foreground.pixel;
2923 + xvalues_mask |= GDK_GC_FOREGROUND;
2924 }
2925
2926 if (entry->gcv.function != gcv->function) {
2927 - switch (gcv->function) {
2928 - case GDK_COPY:
2929 - xvalues.function = GXcopy;
2930 - break;
2931 - case GDK_INVERT:
2932 - xvalues.function = GXinvert;
2933 - break;
2934 - case GDK_XOR:
2935 - xvalues.function = GXxor;
2936 - break;
2937 - case GDK_CLEAR:
2938 - xvalues.function = GXclear;
2939 - break;
2940 - case GDK_AND:
2941 - xvalues.function = GXand;
2942 - break;
2943 - case GDK_AND_REVERSE:
2944 - xvalues.function = GXandReverse;
2945 - break;
2946 - case GDK_AND_INVERT:
2947 - xvalues.function = GXandInverted;
2948 - break;
2949 - case GDK_NOOP:
2950 - xvalues.function = GXnoop;
2951 - break;
2952 - case GDK_OR:
2953 - xvalues.function = GXor;
2954 - break;
2955 - case GDK_EQUIV:
2956 - xvalues.function = GXequiv;
2957 - break;
2958 - case GDK_OR_REVERSE:
2959 - xvalues.function = GXorReverse;
2960 - break;
2961 - case GDK_COPY_INVERT:
2962 - xvalues.function = GXcopyInverted;
2963 - break;
2964 - case GDK_OR_INVERT:
2965 - xvalues.function = GXorInverted;
2966 - break;
2967 - case GDK_NAND:
2968 - xvalues.function = GXnand;
2969 - break;
2970 - case GDK_SET:
2971 - xvalues.function = GXset;
2972 - break;
2973 - }
2974 - xvalues_mask |= GCFunction;
2975 + xvalues.function = gcv->function;
2976 + xvalues_mask |= GDK_GC_FUNCTION;
2977 }
2978
2979 if(entry->gcv.font != gcv->font && flags & GDK_GC_FONT) {
2980 - xvalues.font = ((XFontStruct *)GDK_FONT_XFONT(gcv->font))->fid;
2981 - xvalues_mask |= GCFont;
2982 + xvalues.font = gcv->font;
2983 + xvalues_mask |= GDK_GC_FONT;
2984 }
2985
2986 if (entry->gcv.line_style != gcv->line_style) {
2987 - switch (gcv->line_style) {
2988 - case GDK_LINE_SOLID:
2989 - xvalues.line_style = LineSolid;
2990 - break;
2991 - case GDK_LINE_ON_OFF_DASH:
2992 - xvalues.line_style = LineOnOffDash;
2993 - break;
2994 - case GDK_LINE_DOUBLE_DASH:
2995 - xvalues.line_style = LineDoubleDash;
2996 - break;
2997 - }
2998 - xvalues_mask |= GCLineStyle;
2999 + xvalues.line_style = gcv->line_style;
3000 + xvalues_mask |= GDK_GC_LINE_STYLE;
3001 }
3002
3003 if (xvalues_mask != 0) {
3004 - XChangeGC(GDK_GC_XDISPLAY(entry->gc), GDK_GC_XGC(entry->gc),
3005 - xvalues_mask, &xvalues);
3006 + gdk_gc_set_values(entry->gc, &xvalues, (GdkGCValuesMask)xvalues_mask);
3007 }
3008 +
3009 entry->flags = flags;
3010 entry->gcv = *gcv;
3011 }
3012 --- mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp.foo 2004-03-09 09:14:54.000000000 -0500
3013 +++ mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp 2004-10-18 22:49:40.000000000 -0400
3014 @@ -4600,6 +4600,12 @@
3015 return mCurrentFont->GetGDKFont();
3016 }
3017
3018 +nsresult
3019 +nsFontMetricsGTK::SetRightToLeftText(PRBool aIsRTL)
3020 +{
3021 + return NS_OK;
3022 +}
3023 +
3024 PR_BEGIN_EXTERN_C
3025 static int
3026 CompareSizes(const void* aArg1, const void* aArg2, void *data)
3027 --- mozilla/gfx/src/gtk/nsFontMetricsXft.h.foo 2004-02-23 16:38:52.000000000 -0500
3028 +++ mozilla/gfx/src/gtk/nsFontMetricsXft.h 2004-10-18 22:49:40.000000000 -0400
3029 @@ -202,6 +202,8 @@
3030
3031 virtual GdkFont* GetCurrentGDKFont(void);
3032
3033 + virtual nsresult SetRightToLeftText(PRBool aIsRTL);
3034 +
3035 // get hints for the font
3036 static PRUint32 GetHints (void);
3037
3038 --- mozilla/gfx/src/gtk/nsFontMetricsGTK.h.foo 2004-02-04 20:57:03.000000000 -0500
3039 +++ mozilla/gfx/src/gtk/nsFontMetricsGTK.h 2004-10-18 22:49:40.000000000 -0400
3040 @@ -344,6 +344,8 @@
3041
3042 virtual GdkFont* GetCurrentGDKFont(void);
3043
3044 + virtual nsresult SetRightToLeftText(PRBool aIsRTL);
3045 +
3046 static nsresult FamilyExists(nsIDeviceContext *aDevice, const nsString& aName);
3047 static PRUint32 GetHints(void);
3048
3049 --- mozilla/configure.in.foo 2004-05-25 22:25:16.000000000 -0400
3050 +++ mozilla/configure.in 2004-10-18 22:49:40.000000000 -0400
3051 @@ -3429,6 +3429,34 @@
3052 AC_SUBST(MOZ_XFT_LIBS)
3053
3054 dnl ========================================================
3055 +dnl = pango font rendering
3056 +dnl ========================================================
3057 +MOZ_ARG_ENABLE_BOOL(pango,
3058 +[ --enable-pango Enable Pango font rendering support],
3059 + MOZ_ENABLE_PANGO=1,
3060 + MOZ_ENABLE_PANGO=)
3061 +
3062 +if test "$MOZ_ENABLE_PANGO"
3063 +then
3064 + AC_DEFINE(MOZ_ENABLE_PANGO)
3065 + PKG_CHECK_MODULES(MOZ_PANGO, pango >= 1.5.0)
3066 +
3067 + dnl Make sure that the pango version is _actually_ new enough
3068 + _SAVE_CFLAGS=$CFLAGS
3069 + _SAVE_LDFLAGS=$LDFLAGS
3070 + CFLAGS="$MOZ_PANGO_CFLAGS $CFLAGS"
3071 + LDFLAGS="$MOZ_PANGO_LIBS $LDFLAGS"
3072 + AC_CHECK_LIB(pangoft2-1.0, pango_fc_font_map_add_decoder_find_func,,
3073 + AC_MSG_ERROR([Your Pango is too old. Sorry.]))
3074 + CFLAGS=$_SAVE_CFLAGS
3075 + LDFLAGS=$_SAVE_LDFLAGS
3076 +
3077 + AC_SUBST(MOZ_ENABLE_PANGO)
3078 + AC_SUBST(MOZ_PANGO_CFLAGS)
3079 + AC_SUBST(MOZ_PANGO_LIBS)
3080 +fi
3081 +
3082 +dnl ========================================================
3083 dnl = disabling x11 core support, enabled by default
3084 dnl ========================================================
3085 MOZ_ENABLE_COREXFONTS=${MOZ_ENABLE_COREXFONTS-1}