]> git.pld-linux.org Git - packages/firefox.git/blob - mozilla-firefox-pango-ligatures.patch
- better way to show "Add exception" button directly w/o clicking through stupid...
[packages/firefox.git] / mozilla-firefox-pango-ligatures.patch
1 --- mozilla.back/gfx/src/gtk/nsFontMetricsPango.cpp.orig        2007-06-28 14:44:31.000000000 +0200
2 +++ mozilla.back/gfx/src/gtk/nsFontMetricsPango.cpp     2007-06-28 15:48:04.000000000 +0200
3 @@ -21,6 +21,8 @@
4   * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
5   *
6   * Contributor(s):
7 + *   Christopher Blizzard <blizzard@mozilla.org>
8 + *   Behdad Esfahbod <behdad@behdad.org>
9   *
10   * Alternatively, the contents of this file may be used under the terms of
11   * either the GNU General Public License Version 2 or later (the "GPL"), or
12 @@ -36,6 +38,10 @@
13   *
14   * ***** END LICENSE BLOCK ***** */
15  
16 +#define PANGO_ENABLE_BACKEND
17 +
18 +#include "nsFontMetricsPango.h"
19 +
20  #include <strings.h>
21  #include "nsFont.h"
22  #include "nsIDeviceContext.h"
23 @@ -43,27 +49,37 @@
24  #include "nsIPref.h"
25  #include "nsServiceManagerUtils.h"
26  
27 -#define PANGO_ENABLE_BACKEND
28 -#define PANGO_ENABLE_ENGINE
29 -
30 -#include "nsFontMetricsPango.h"
31 -#include "nsRenderingContextGTK.h"
32 -#include "nsDeviceContextGTK.h"
33  #include "nsFontConfigUtils.h"
34  
35  #include "nsUnicharUtils.h"
36  #include "nsQuickSort.h"
37  #include "nsFontConfigUtils.h"
38 +#include "mozilla-decoder.h"
39 +
40 +#define FORCE_PR_LOG
41 +#include "prlog.h"
42 +
43  
44  #include <fontconfig/fontconfig.h>
45 +#include <freetype/tttables.h>
46 +
47 +#include <pango/pango.h>
48 +#include <pango/pangofc-font.h>
49 +
50 +#ifdef PSPANGO
51 +#include <pango/pangoft2.h>
52 +#include "nsRenderingContextPS.h"
53 +#include "nsDeviceContextPS.h"
54 +#include "nsType1.h"
55 +#else
56  #include <gdk/gdk.h>
57  #include <gdk/gdkx.h>
58 -#include <freetype/tttables.h>
59 +#include "nsRenderingContextGTK.h"
60 +#include "nsDeviceContextGTK.h"
61 +#endif
62 +
63  
64 -#include "mozilla-decoder.h"
65  
66 -#define FORCE_PR_LOG
67 -#include "prlog.h"
68  
69  // Globals
70  
71 @@ -108,6 +124,49 @@ static nsresult    EnumFontsPango   (nsI
72                                       PRUint32* aCount, PRUnichar*** aResult);
73  static int         CompareFontNames (const void* aArg1, const void* aArg2,
74                                       void* aClosure);
75 +static void  utf16_to_utf8 (const PRUnichar* aString, PRUint32 aLength,
76 +                            char *&text, gint &text_len);
77 +
78 +#ifdef PSPANGO
79 +static void
80 +default_substitute (FcPattern *pattern,
81 +                    gpointer   data)
82 +{
83 +  FcPatternDel (pattern, FC_HINTING);
84 +  FcPatternAddBool (pattern, FC_HINTING, 0);
85 +}
86 +#endif
87 +
88 +static PangoFontMap *
89 +get_fontmap (void)
90 +{
91 +  static PangoFontMap               *fontmap = NULL;
92 +
93 +  if (!fontmap) {
94 +#ifdef PSPANGO
95 +    fontmap = pango_ft2_font_map_new ();
96 +    pango_ft2_font_map_set_resolution ((PangoFT2FontMap *)fontmap, 72., 72.);
97 +    pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, default_substitute, NULL, NULL);
98 +#else
99 +    PangoContext* context = gdk_pango_context_get ();
100 +    fontmap = pango_context_get_font_map (context);
101 +    g_object_unref (context);
102 +#endif
103 +  }
104 +
105 +  return fontmap;
106 +}
107 +
108 +static PangoContext *
109 +get_context (void)
110 +{
111 +#ifdef PSPANGO
112 +  return pango_ft2_font_map_create_context ((PangoFT2FontMap *) get_fontmap ());
113 +#else
114 +  return gdk_pango_context_get();
115 +#endif
116 +}
117 +
118  
119  nsFontMetricsPango::nsFontMetricsPango()
120  {
121 @@ -169,15 +228,21 @@
122      mLangGroup = aLangGroup;
123  
124      // Hang on to the device context
125 +#ifdef PSPANGO
126 +    mDeviceContext = (nsDeviceContextPS *)aContext;
127 +#else
128      mDeviceContext = aContext;
129 -    
130 +#endif
131 +
132      mPointSize = NSTwipsToFloatPoints(mFont.size);
133  
134 +#ifndef PSPANGO
135      // Make sure to clamp the pixel size to something reasonable so we
136      // don't make the X server blow up.
137      nscoord screenPixels = gdk_screen_height();
138      mPointSize = PR_MIN((screenPixels - 1) * FONT_MAX_FONT_SCALE, mPointSize);
139      mPointSize = PR_MIN(2000, mPointSize);
140 +#endif
141  
142      // enumerate over the font names passed in
143      mFont.EnumerateFamilies(nsFontMetricsPango::EnumFontCallback, this);
144 @@ -329,7 +394,7 @@ nsFontMetricsPango::CacheFontMetrics(voi
145  
146      // mPangoSpaceWidth
147      PangoLayout *layout = pango_layout_new(mPangoContext);
148 -    pango_layout_set_text(layout, " ", 1);
149 +    pango_layout_set_text(layout, " ", -1);
150      int pswidth, psheight;
151      pango_layout_get_size(layout, &pswidth, &psheight);
152      mPangoSpaceWidth = pswidth;
153 @@ -337,14 +402,14 @@ nsFontMetricsPango::CacheFontMetrics(voi
154  
155      // mSpaceWidth (width of a space)
156      nscoord tmpWidth;
157 -    GetWidth(" ", 1, tmpWidth, NULL);
158 +    GetWidth(" ", 1, tmpWidth CONTEXT_ARG_NULL);
159      mSpaceWidth = tmpWidth;
160  
161      // mAveCharWidth (width of an 'average' char)
162      //    XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents);
163      //rawWidth = extents.width;
164      //mAveCharWidth = NSToCoordRound(rawWidth * f);
165 -    GetWidth("x", 1, tmpWidth, NULL);
166 +    GetWidth("x", 1, tmpWidth CONTEXT_ARG_NULL);
167      mAveCharWidth = tmpWidth;
168  
169      // mXHeight (height of an 'x' character)
170 @@ -460,130 +525,96 @@ nsFontMetricsPango::GetFontHandle(nsFont
171  
172  // nsIFontMetricsPango impl
173  
174 -nsresult
175 -nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength,
176 -                             nscoord& aWidth,
177 -                             nsRenderingContextGTK *aContext)
178 +#ifdef PSPANGO
179 +NS_IMETHODIMP
180 +nsFontMetricsPSPango::GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength)
181  {
182 -    PangoLayout *layout = pango_layout_new(mPangoContext);
183 -
184 -    pango_layout_set_text(layout, aString, aLength);
185 +    return GetWidth (String, (PRUint32) aLength, aWidth CONTEXT_ARG_NULL);
186 +}
187  
188 -    if (mPangoSpaceWidth)
189 -        FixupSpaceWidths(layout, aString);
190 +NS_IMETHODIMP
191 +nsFontMetricsPSPango::GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength)
192 +{
193 +    return GetWidth (aString, (PRUint32)aLength, aWidth, NULL CONTEXT_ARG_NULL);
194 +}
195 +#endif
196  
197 +nsresult
198 +nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength,
199 +                             nscoord& aWidth
200 +                             CONTEXT_ARG_DEF)
201 +{
202      int width, height;
203 -
204 +    PangoLayout *layout = GetLayout(aString, aLength);
205      pango_layout_get_size(layout, &width, &height);
206 -
207      g_object_unref(layout);
208  
209 -    float f;
210 -    f = mDeviceContext->DevUnitsToAppUnits();
211 +    float f = mDeviceContext->DevUnitsToAppUnits();
212      aWidth = NSToCoordRound(width * f / PANGO_SCALE);
213  
214 -    //    printf("GetWidth (char *) %d\n", aWidth);
215 -
216      return NS_OK;
217  }
218  
219  nsresult
220  nsFontMetricsPango::GetWidth(const PRUnichar* aString, PRUint32 aLength,
221 -                             nscoord& aWidth, PRInt32 *aFontID,
222 -                             nsRenderingContextGTK *aContext)
223 +                             nscoord& aWidth, PRInt32 *aFontID
224 +                             CONTEXT_ARG_DEF)
225  {
226 -    nsresult rv = NS_OK;
227 -    PangoLayout *layout = pango_layout_new(mPangoContext);
228 -
229 -    gchar *text = g_utf16_to_utf8(aString, aLength,
230 -                                  NULL, NULL, NULL);
231 -
232 -    if (!text) {
233 -        aWidth = 0;
234 -#ifdef DEBUG
235 -        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
236 -        DUMP_PRUNICHAR(aString, aLength)
237 -#endif
238 -        rv = NS_ERROR_FAILURE;
239 -        goto loser;
240 -    }
241 -
242      gint width, height;
243 -
244 -    pango_layout_set_text(layout, text, strlen(text));
245 -    FixupSpaceWidths(layout, text);
246 +    PangoLayout *layout = GetLayout(aString, aLength);
247      pango_layout_get_size(layout, &width, &height);
248 +    g_object_unref(layout);
249  
250 -    float f;
251 -    f = mDeviceContext->DevUnitsToAppUnits();
252 +    float f = mDeviceContext->DevUnitsToAppUnits();
253      aWidth = NSToCoordRound(width * f / PANGO_SCALE);
254  
255 -    //    printf("GetWidth %d\n", aWidth);
256 -
257 - loser:
258 -    g_free(text);
259 -    g_object_unref(layout);
260 -
261 -    return rv;
262 +    return NS_OK;
263  }
264  
265  
266  nsresult
267 -nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
268 +nsFontMetricsPango::GetTextDimensions(const char* aString,
269                                        PRUint32 aLength,
270 -                                      nsTextDimensions& aDimensions, 
271 -                                      PRInt32* aFontID,
272 -                                      nsRenderingContextGTK *aContext)
273 +                                      nsTextDimensions& aDimensions
274 +                                      CONTEXT_ARG_DEF)
275  {
276 -    nsresult rv = NS_OK;
277 -
278 -    PangoLayout *layout = pango_layout_new(mPangoContext);
279 +    PangoLayout *layout = GetLayout(aString, aLength);
280 +    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
281  
282 -    gchar *text = g_utf16_to_utf8(aString, aLength,
283 -                                  NULL, NULL, NULL);
284 -
285 -    if (!text) {
286 -#ifdef DEBUG
287 -        NS_WARNING("nsFontMetricsPango::GetTextDimensions invalid unicode to follow");
288 -        DUMP_PRUNICHAR(aString, aLength)
289 -#endif
290 -        aDimensions.width = 0;
291 -        aDimensions.ascent = 0;
292 -        aDimensions.descent = 0;
293 -
294 -        rv = NS_ERROR_FAILURE;
295 -        goto loser;
296 -    }
297 -        
298 +    PangoRectangle logical;
299 +    pango_layout_line_get_extents(line, NULL, &logical);
300 +    g_object_unref(layout);
301  
302 -    pango_layout_set_text(layout, text, strlen(text));
303 -    FixupSpaceWidths(layout, text);
304 +    float P2T = mDeviceContext->DevUnitsToAppUnits();
305  
306 -    // Get the logical extents
307 -    PangoLayoutLine *line;
308 -    if (pango_layout_get_line_count(layout) != 1) {
309 -        printf("Warning: more than one line!\n");
310 -    }
311 -    line = pango_layout_get_line(layout, 0);
312 +    aDimensions.ascent  = NSToCoordRound(PANGO_ASCENT(logical)  * P2T / PANGO_SCALE);
313 +    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(logical) * P2T / PANGO_SCALE);
314 +    aDimensions.width   = NSToCoordRound(logical.width          * P2T / PANGO_SCALE);
315  
316 -    PangoRectangle rect;
317 -    pango_layout_line_get_extents(line, NULL, &rect);
318 +    return NS_OK;
319 +}
320  
321 -    float P2T;
322 -    P2T = mDeviceContext->DevUnitsToAppUnits();
323 +nsresult
324 +nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
325 +                                      PRUint32 aLength,
326 +                                      nsTextDimensions& aDimensions, 
327 +                                      PRInt32* aFontID
328 +                                      CONTEXT_ARG_DEF)
329 +{
330 +    PangoLayout *layout = GetLayout(aString, aLength);
331 +    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
332  
333 -    aDimensions.width = NSToCoordRound(rect.width * P2T / PANGO_SCALE);
334 -    aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(rect) * P2T / PANGO_SCALE);
335 -    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(rect) * P2T / PANGO_SCALE);
336 +    PangoRectangle logical;
337 +    pango_layout_line_get_extents(line, NULL, &logical);
338 +    g_object_unref(layout);
339  
340 -    //    printf("GetTextDimensions %d %d %d\n", aDimensions.width,
341 -    //aDimensions.ascent, aDimensions.descent);
342 +    float P2T = mDeviceContext->DevUnitsToAppUnits();
343  
344 - loser:
345 -    g_free(text);
346 -    g_object_unref(layout);
347 +    aDimensions.ascent  = NSToCoordRound(PANGO_ASCENT(logical)  * P2T / PANGO_SCALE);
348 +    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(logical) * P2T / PANGO_SCALE);
349 +    aDimensions.width   = NSToCoordRound(logical.width          * P2T / PANGO_SCALE);
350  
351 -    return rv;
352 +    return NS_OK;
353  }
354  
355  nsresult
356 @@ -595,13 +626,13 @@ nsFontMetricsPango::GetTextDimensions(co
357                                        nsTextDimensions&   aDimensions,
358                                        PRInt32&            aNumCharsFit,
359                                        nsTextDimensions&   aLastWordDimensions,
360 -                                      PRInt32*            aFontID,
361 -                                      nsRenderingContextGTK *aContext)
362 +                                      PRInt32*            aFontID
363 +                                      CONTEXT_ARG_DEF)
364  {
365  
366      return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks,
367                                       aNumBreaks, aDimensions, aNumCharsFit,
368 -                                     aLastWordDimensions, aContext);
369 +                                     aLastWordDimensions CONTEXT_ARG_PASS);
370  
371  }
372  
373 @@ -614,8 +645,8 @@ nsFontMetricsPango::GetTextDimensions(co
374                                        nsTextDimensions&   aDimensions,
375                                        PRInt32&            aNumCharsFit,
376                                        nsTextDimensions&   aLastWordDimensions,
377 -                                      PRInt32*            aFontID,
378 -                                      nsRenderingContextGTK *aContext)
379 +                                      PRInt32*            aFontID
380 +                                      CONTEXT_ARG_DEF)
381  {
382      nsresult rv = NS_OK;
383      PRInt32 curBreak = 0;
384 @@ -623,23 +654,15 @@ nsFontMetricsPango::GetTextDimensions(co
385  
386      PRInt32 *utf8Breaks = new PRInt32[aNumBreaks];
387  
388 -    gchar *text = g_utf16_to_utf8(aString, (PRInt32)aLength,
389 -                                  NULL, NULL, NULL);
390 +    gchar* text;
391 +    gint text_len;
392 +    utf16_to_utf8 (aString, aLength, text, text_len);
393  
394      curChar = text;
395  
396 -    if (!text) {
397 -#ifdef DEBUG
398 -        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
399 -        DUMP_PRUNICHAR(aString, (PRUint32)aLength)
400 -#endif
401 -        rv = NS_ERROR_FAILURE;
402 -        goto loser;
403 -    }
404 -
405      // Covert the utf16 break offsets to utf8 break offsets
406      for (PRInt32 curOffset=0; curOffset < aLength;
407 -         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
408 +         curOffset++, curChar = g_utf8_next_char(curChar)) {
409          if (aBreaks[curBreak] == curOffset) {
410              utf8Breaks[curBreak] = curChar - text;
411              curBreak++;
412 @@ -653,10 +676,10 @@ nsFontMetricsPango::GetTextDimensions(co
413      utf8Breaks[curBreak] = curChar - text;
414  
415  #if 0
416 -    if (strlen(text) != aLength) {
417 -        printf("Different lengths for utf16 %d and utf8 %d\n", aLength, strlen(text));
418 +    if (text_len != aLength) {
419 +        printf("Different lengths for utf16 %d and utf8 %d\n", aLength, text_len);
420          DUMP_PRUNICHAR(aString, aLength)
421 -        DUMP_PRUNICHAR(text, strlen(text))
422 +        DUMP_PRUNICHAR(text, text_len)
423          for (PRInt32 i = 0; i < aNumBreaks; ++i) {
424              printf("  break %d utf16 %d utf8 %d\n", i, aBreaks[i], utf8Breaks[i]);
425          }
426 @@ -666,9 +689,9 @@ nsFontMetricsPango::GetTextDimensions(co
427      // We'll use curBreak to indicate which of the breaks end up being
428      // used for the break point for this line.
429      curBreak = 0;
430 -    rv = GetTextDimensionsInternal(text, strlen(text), aAvailWidth, utf8Breaks,
431 +    rv = GetTextDimensionsInternal(text, text_len, aAvailWidth, utf8Breaks,
432                                     aNumBreaks, aDimensions, aNumCharsFit,
433 -                                   aLastWordDimensions, aContext);
434 +                                   aLastWordDimensions CONTEXT_ARG_PASS);
435  
436      // Figure out which of the breaks we ended up using to convert
437      // back to utf16 - start from the end.
438 @@ -681,200 +704,365 @@ nsFontMetricsPango::GetTextDimensions(co
439          }
440      }
441  
442 - loser:
443 -    if (text)
444 -        g_free(text);
445 +    g_free(text);
446  
447      delete[] utf8Breaks;
448  
449      return rv;
450  }
451  
452 -nsresult
453 -nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength,
454 -                               nscoord aX, nscoord aY,
455 -                               const nscoord* aSpacing,
456 -                               nsRenderingContextGTK *aContext,
457 -                               nsDrawingSurfaceGTK *aSurface)
458 +#ifdef PSPANGO
459 +
460 +typedef struct _nsPSPangoRenderer        nsPSPangoRenderer;
461 +typedef struct _nsPSPangoRendererClass   nsPSPangoRendererClass;
462 +
463 +struct _nsPSPangoRenderer
464  {
465 -    PangoLayout *layout = pango_layout_new(mPangoContext);
466 +  PangoRenderer parent_instance;
467 +  nsRenderingContextPS *psContext;
468 +  nsFontMetricsPSPango *psPangoFontMetrics;
469 +  float zoom;
470 +};
471  
472 -    pango_layout_set_text(layout, aString, aLength);
473 -    FixupSpaceWidths(layout, aString);
474 +struct _nsPSPangoRendererClass
475 +{
476 +  PangoRendererClass parent_class;
477 +};
478  
479 -    int x = aX;
480 -    int y = aY;
481 +#define _PS_TYPE_PANGO_RENDERER            (_ps_pango_renderer_get_type())
482 +#define _PS_PANGO_RENDERER(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRenderer))
483 +#define _PS_IS_PANGO_RENDERER(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), _PS_TYPE_PANGO_RENDERER))
484 +#define _PS_PANGO_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRendererClass))
485 +#define _PS_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), _PS_TYPE_PANGO_RENDERER))
486 +#define _PS_PANGO_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRendererClass))
487  
488 -    aContext->GetTranMatrix()->TransformCoord(&x, &y);
489 +G_DEFINE_TYPE (_nsPSPangoRenderer, _ps_pango_renderer, PANGO_TYPE_RENDERER)
490  
491 -    PangoLayoutLine *line;
492 -    if (pango_layout_get_line_count(layout) != 1) {
493 -        printf("Warning: more than one line!\n");
494 -    }
495 -    line = pango_layout_get_line(layout, 0);
496 +static PangoRenderer *
497 +get_renderer (void)
498 +{
499 +  static PangoRenderer               *renderer = NULL;
500  
501 -    aContext->UpdateGC();
502 -    GdkGC *gc = aContext->GetGC();
503 +  if (!renderer)
504 +    renderer = (PangoRenderer *) g_object_new (_PS_TYPE_PANGO_RENDERER, NULL);
505  
506 -    if (aSpacing && *aSpacing) {
507 -        DrawStringSlowly(aString, NULL, aLength, aSurface->GetDrawable(),
508 -                         gc, x, y, line, aSpacing);
509 -    }
510 -    else {
511 -        gdk_draw_layout_line(aSurface->GetDrawable(), gc,
512 -                             x, y,
513 -                             line);
514 -    }
515 +  return renderer;
516 +}
517  
518 -    g_object_unref(gc);
519 -    g_object_unref(layout);
520 +static void
521 +_ps_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
522 +                              PangoFont        *font,
523 +                              PangoGlyphString *glyphs,
524 +                              int               x,
525 +                              int               y);
526  
527 -    //    printf("DrawString (char *)\n");
528 +static void
529 +_ps_pango_renderer_class_init (nsPSPangoRendererClass *klass)
530 +{
531 +  PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
532 +  
533 +  renderer_class->draw_glyphs = _ps_pango_renderer_draw_glyphs;
534 +}
535  
536 -    return NS_OK;
537 +static void
538 +_ps_pango_renderer_init (nsPSPangoRenderer *renderer)
539 +{
540 +}
541 +
542 +class nsPangoType1Generator : public nsPSFontGenerator {
543 +public:
544 +  nsPangoType1Generator();
545 +  ~nsPangoType1Generator();
546 +  nsresult Init(PangoFont *aFont);
547 +  void  GeneratePSFont(FILE* aFile);
548 +
549 +protected:
550 +  PangoFont *mFont;
551 +};
552 +
553 +nsPangoType1Generator::nsPangoType1Generator()
554 +{
555  }
556  
557  nsresult
558 -nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
559 -                               nscoord aX, nscoord aY,
560 -                               PRInt32 aFontID,
561 -                               const nscoord* aSpacing,
562 -                               nsRenderingContextGTK *aContext,
563 -                               nsDrawingSurfaceGTK *aSurface)
564 +nsPangoType1Generator::Init(PangoFont *aFont)
565 +  {
566 +  NS_ENSURE_TRUE(aFont, NS_ERROR_FAILURE);
567 +  mFont = aFont;
568 +  g_object_ref (mFont);
569 +  return NS_OK;
570 +}
571 +
572 +nsPangoType1Generator::~nsPangoType1Generator()
573  {
574 -    nsresult rv = NS_OK;
575 -    int x = aX;
576 -    int y = aY;
577 +  g_object_unref (mFont);
578 +  mFont = nsnull;
579 +}
580  
581 -    aContext->UpdateGC();
582 -    GdkGC *gc = aContext->GetGC();
583 +void nsPangoType1Generator::GeneratePSFont(FILE* aFile)
584 +{
585 +  FT_Face face = pango_fc_font_lock_face ((PangoFcFont *) mFont);
586  
587 -    PangoLayout *layout = pango_layout_new(mPangoContext);
588 +  if (face == nsnull)
589 +    return;
590  
591 -    gchar *text = g_utf16_to_utf8(aString, aLength,
592 -                                  NULL, NULL, NULL);
593 +  int wmode = 0;
594 +  if (mGlyphSubset->Count())
595 +    FT2SubsetToType1FontSet(face, mGlyphSubset, wmode, aFile);
596  
597 -    if (!text) {
598 -#ifdef DEBUG
599 -        NS_WARNING("nsFontMetricsPango::DrawString invalid unicode to follow");
600 -        DUMP_PRUNICHAR(aString, aLength)
601 -#endif
602 -        rv = NS_ERROR_FAILURE;
603 -        goto loser;
604 -    }
605 + pango_fc_font_unlock_face ((PangoFcFont *) mFont);
606 +}
607  
608 -    pango_layout_set_text(layout, text, strlen(text));
609 -    FixupSpaceWidths(layout, text);
610 +typedef struct
611 +{
612 +  nsCString    *FontNameBase;
613 +  nsCStringKey *key;
614 +  int           font_size;
615 +} PSPangoFontData;
616  
617 -    aContext->GetTranMatrix()->TransformCoord(&x, &y);
618 +static void
619 +ps_pango_font_data_destroy (PSPangoFontData *data)
620 +{
621 +  delete data->key;
622 +  delete data->FontNameBase;
623 +  g_free (data);
624 +}
625  
626 -    PangoLayoutLine *line;
627 -    if (pango_layout_get_line_count(layout) != 1) {
628 -        printf("Warning: more than one line!\n");
629 -    }
630 -    line = pango_layout_get_line(layout, 0);
631 +static void
632 +_ps_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
633 +                              PangoFont        *font,
634 +                              PangoGlyphString *glyphs,
635 +                              int               x,
636 +                              int               y)
637 +{
638 +  if (!glyphs->num_glyphs)
639 +    return;
640  
641 -    if (aSpacing && *aSpacing) {
642 -        DrawStringSlowly(text, aString, aLength, aSurface->GetDrawable(),
643 -                         gc, x, y, line, aSpacing);
644 -    }
645 -    else {
646 -        gdk_draw_layout_line(aSurface->GetDrawable(), gc,
647 -                             x, y,
648 -                             line);
649 -    }
650 +  static GQuark data_quark = 0;
651 +  if (!data_quark)
652 +    data_quark = g_quark_from_static_string ("ps-pango-font-data");
653  
654 - loser:
655 +  PSPangoFontData *data;
656 +  if (!(data = (PSPangoFontData *) g_object_get_qdata (G_OBJECT (font), data_quark)))
657 +    {
658 +      data = g_new (PSPangoFontData, 1);
659  
660 -    g_free(text);
661 -    g_object_unref(gc);
662 -    g_object_unref(layout);
663 +      FT_Face face = pango_fc_font_lock_face ((PangoFcFont *) font);
664 +      if (face == nsnull)
665 +        return;
666 +      int wmode = 0;
667 +      data->FontNameBase = new nsCString ();
668 +      if (NS_FAILED(FT2ToType1FontName(face, wmode, *data->FontNameBase))) {
669 +        g_free (data);
670 +        pango_fc_font_unlock_face ((PangoFcFont *) font);
671 +        return;
672 +      }
673 +      pango_fc_font_unlock_face ((PangoFcFont *) font);
674  
675 -    //    printf("DrawString\n");
676 +      PangoFontDescription *desc = pango_font_describe (font);
677 +      data->font_size = pango_font_description_get_size (desc);
678 +      pango_font_description_free (desc);
679 +
680 +      data->key = new nsCStringKey (*data->FontNameBase);
681 +
682 +      g_object_set_qdata_full (G_OBJECT (font), data_quark, data, (GDestroyNotify) ps_pango_font_data_destroy);
683 +    }
684 +
685 +  nsPSPangoRenderer *ps_renderer = (nsPSPangoRenderer *)renderer;
686 +  nsRenderingContextPS *aContext = ps_renderer->psContext;
687 +  nsFontMetricsPSPango *metrics = ps_renderer->psPangoFontMetrics;
688 +  nsDeviceContextPS* dc = NS_REINTERPRET_CAST (nsDeviceContextPS*, metrics->GetDeviceContext());
689 +  nsPostScriptObj* psObj = aContext->GetPostScriptObj();
690 +  nsHashtable *psFGList = dc->GetPSFontGeneratorList();
691 +  g_return_if_fail (psFGList);
692 +  nsPSFontGenerator* psFontGen = (nsPSFontGenerator*) psFGList->Get(data->key);
693 +  if (!psFontGen) {
694 +    nsresult rv;
695 +    psFontGen = new nsPangoType1Generator;
696 +    g_return_if_fail (psFontGen);
697 +    rv = ((nsPangoType1Generator*)psFontGen)->Init(font);
698 +    if (NS_FAILED(rv)) {
699 +      delete psFontGen;
700 +      return;
701 +    }
702 +    psFGList->Put(data->key, (void *) psFontGen);
703 +  }
704 +  nscoord font_size = NSToCoordRound (ps_renderer->zoom * data->font_size / PANGO_SCALE);
705 +
706 +  g_return_if_fail (aContext);
707 +  g_return_if_fail (psObj);
708 +
709 +  nscoord aX = NSToCoordRound(ps_renderer->zoom * x / PANGO_SCALE);
710 +  nscoord aY = NSToCoordRound(ps_renderer->zoom * y / PANGO_SCALE);
711 +  psObj->moveto(aX, aY);
712 +
713 +  PRInt32 currSubFont, prevSubFont = -1;
714 +  PRUint32 i;
715 +  PangoGlyphString gl;
716 +
717 +  gl.glyphs = glyphs->glyphs;
718 +  gl.num_glyphs = 0;
719 +  currSubFont = prevSubFont;
720 +  for (i = 0; i < glyphs->num_glyphs; ++i) {
721 +    PangoGlyph glyph = glyphs->glyphs[i].glyph;
722 +
723 +    if (glyph != PANGO_GLYPH_EMPTY)
724 +      currSubFont = psFontGen->AddToGlyphSubset(glyph > 0x0fffffff ? 0 : glyph);
725 +
726 +    if (prevSubFont != currSubFont) {
727 +      if (prevSubFont != -1)
728 +        psObj->show(&gl, ps_renderer->zoom,  psFontGen, prevSubFont);
729 +
730 +      psObj->setfont(*data->FontNameBase, (PRUint32) font_size, currSubFont);
731 +      prevSubFont = currSubFont;
732 +      gl.glyphs = glyphs->glyphs + i;
733 +      gl.num_glyphs = 0;
734 +    }
735  
736 -    return rv;
737 +    gl.num_glyphs++;
738 +  }
739 +
740 +  if (prevSubFont != -1)
741 +    psObj->show(&gl, ps_renderer->zoom, psFontGen, prevSubFont);
742  }
743 +#endif
744 +
745 +static void
746 +draw_layout_line (int x, int y,
747 +                  PangoLayoutLine *line,
748 +                  nsFontMetricsPango *fm
749 +                  CONTEXT_AND_SURFACE_ARG_DEF)
750 +{
751 +#ifdef PSPANGO
752 +  PangoRenderer *renderer = get_renderer ();
753 +  nsPSPangoRenderer *ps_renderer = (nsPSPangoRenderer *)renderer;
754 +  ps_renderer->psContext = aContext;
755 +  ps_renderer->psPangoFontMetrics = fm;
756 +  nsDeviceContextPS* dc = NS_REINTERPRET_CAST (nsDeviceContextPS*, fm->GetDeviceContext());
757 +  ps_renderer->zoom = dc->DevUnitsToAppUnits();
758 +
759 +  pango_renderer_draw_layout_line (renderer, line,
760 +                                   NSToCoordRound (x * PANGO_SCALE / ps_renderer->zoom),
761 +                                   NSToCoordRound (y * PANGO_SCALE / ps_renderer->zoom));
762 +#else
763 +    aContext->UpdateGC();
764 +    GdkGC *gc = aContext->GetGC();
765 +    gdk_draw_layout_line(aSurface->GetDrawable(), gc, x, y, line);
766 +    g_object_unref(gc);
767 +#endif
768 +}
769 +
770  
771 -#ifdef MOZ_MATHML
772  nsresult
773 -nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
774 -                                       nsBoundingMetrics &aBoundingMetrics,
775 -                                       nsRenderingContextGTK *aContext)
776 +nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength,
777 +                               nscoord aX, nscoord aY,
778 +                               const nscoord* aSpacing
779 +                               CONTEXT_AND_SURFACE_ARG_DEF)
780  {
781 -    printf("GetBoundingMetrics (char *)\n");
782 -    return NS_ERROR_FAILURE;
783 +    int x = aX;
784 +    int y = aY;
785 +
786 +    aContext->GetTranMatrix()->TransformCoord(&x, &y);
787 +
788 +    PangoLayout *layout = GetLayout(aString, aLength);
789 +    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
790 +
791 +    ApplySpacing(aString, aLength, line, aSpacing);
792 +    draw_layout_line(x, y, line, this CONTEXT_AND_SURFACE_ARG_PASS);
793 +
794 +    g_object_unref(layout);
795 +
796 +    return NS_OK;
797  }
798  
799  nsresult
800 -nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString,
801 -                                       PRUint32 aLength,
802 -                                       nsBoundingMetrics &aBoundingMetrics,
803 -                                       PRInt32 *aFontID,
804 -                                       nsRenderingContextGTK *aContext)
805 +nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
806 +                               nscoord aX, nscoord aY,
807 +                               PRInt32 aFontID,
808 +                               const nscoord* aSpacing
809 +                               CONTEXT_AND_SURFACE_ARG_DEF)
810  {
811 -    nsresult rv = NS_OK;
812 -    PangoLayout *layout = pango_layout_new(mPangoContext);
813 +    int x = aX;
814 +    int y = aY;
815  
816 -    gchar *text = g_utf16_to_utf8(aString, aLength,
817 -                                  NULL, NULL, NULL);
818 +    aContext->GetTranMatrix()->TransformCoord(&x, &y);
819  
820 -    if (!text) {
821 -#ifdef DEBUG
822 -        NS_WARNING("nsFontMetricsPango::GetBoundingMetrics invalid unicode to follow");
823 -        DUMP_PRUNICHAR(aString, aLength)
824 -#endif
825 -        aBoundingMetrics.Clear();
826 +    PangoLayout *layout = GetLayout(aString, aLength);
827 +    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
828  
829 -        rv = NS_ERROR_FAILURE;
830 -        goto loser;
831 -    }
832 +    ApplySpacing(aString, aLength, line, aSpacing);
833 +    draw_layout_line(x, y, line, this CONTEXT_AND_SURFACE_ARG_PASS);
834  
835 -    pango_layout_set_text(layout, text, -1);
836 -    FixupSpaceWidths(layout, text);
837 +    g_object_unref(layout);
838 +
839 +    return NS_OK;
840 +}
841  
842 -    PangoLayoutLine *line;
843 -    if (pango_layout_get_line_count(layout) != 1) {
844 -        printf("Warning: more than one line!\n");
845 -    }
846 -    line = pango_layout_get_line(layout, 0);
847 +
848 +#ifdef MOZ_MATHML
849 +void
850 +nsFontMetricsPango::GetBoundingMetricsInternal(PangoLayout *aLayout,
851 +                                               nsBoundingMetrics &aBoundingMetrics
852 +                                               CONTEXT_ARG_DEF)
853 +{
854 +    PangoLayoutLine *line = pango_layout_get_line(aLayout, 0);
855  
856      // Get the ink and logical extents
857      PangoRectangle ink, logical;
858      pango_layout_line_get_extents(line, &ink, &logical);
859  
860 -    float P2T;
861 -    P2T = mDeviceContext->DevUnitsToAppUnits();
862 +    float P2T = mDeviceContext->DevUnitsToAppUnits();
863  
864      aBoundingMetrics.leftBearing  = NSToCoordRound(PANGO_LBEARING(ink) * P2T / PANGO_SCALE);
865      aBoundingMetrics.rightBearing = NSToCoordRound(PANGO_RBEARING(ink) * P2T / PANGO_SCALE);
866      aBoundingMetrics.ascent       = NSToCoordRound(PANGO_ASCENT(ink)   * P2T / PANGO_SCALE);
867      aBoundingMetrics.descent      = NSToCoordRound(PANGO_DESCENT(ink)  * P2T / PANGO_SCALE);
868      aBoundingMetrics.width        = NSToCoordRound(logical.width       * P2T / PANGO_SCALE);
869 +}
870  
871 - loser:
872 -    g_free(text);
873 +nsresult
874 +nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
875 +                                       nsBoundingMetrics &aBoundingMetrics
876 +                                       CONTEXT_ARG_DEF)
877 +{
878 +    PangoLayout *layout = GetLayout(aString, aLength);
879 +    GetBoundingMetricsInternal (layout, aBoundingMetrics CONTEXT_ARG_PASS);
880      g_object_unref(layout);
881  
882 -    return rv;
883 +   return NS_OK;
884 +}
885 +
886 +nsresult
887 +nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString,
888 +                                       PRUint32 aLength,
889 +                                       nsBoundingMetrics &aBoundingMetrics,
890 +                                       PRInt32 *aFontID
891 +                                       CONTEXT_ARG_DEF)
892 +{
893 +    PangoLayout *layout = GetLayout(aString, aLength);
894 +    GetBoundingMetricsInternal (layout, aBoundingMetrics CONTEXT_ARG_PASS);
895 +    g_object_unref(layout);
896 +
897 +    return NS_OK;
898  }
899  
900  #endif /* MOZ_MATHML */
901  
902 +#ifndef PSPANGO
903  GdkFont*
904  nsFontMetricsPango::GetCurrentGDKFont(void)
905  {
906      return nsnull;
907  }
908 +#endif
909  
910  nsresult
911  nsFontMetricsPango::SetRightToLeftText(PRBool aIsRTL)
912  {
913      if (aIsRTL) {
914          if (!mRTLPangoContext) {
915 -            mRTLPangoContext = gdk_pango_context_get();
916 +            mRTLPangoContext = get_context();
917              pango_context_set_base_dir(mRTLPangoContext, PANGO_DIRECTION_RTL);
918 -
919 -            gdk_pango_context_set_colormap(mRTLPangoContext, gdk_rgb_get_cmap());
920              pango_context_set_language(mRTLPangoContext, GetPangoLanguage(mLangGroup));
921              pango_context_set_font_description(mRTLPangoContext, mPangoFontDesc);
922          }
923 @@ -899,34 +1087,18 @@ nsFontMetricsPango::GetClusterInfo(const
924                                     PRUint32 aLength,
925                                     PRUint8 *aClusterStarts)
926  {
927 -    nsresult rv = NS_OK;
928      PangoLogAttr *attrs = NULL;
929      gint n_attrs = 0;
930 -    PangoLayout *layout = pango_layout_new(mPangoContext);
931 -    
932 -    // Convert the incoming UTF-16 to UTF-8
933 -    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
934  
935 -    if (!text) {
936 -#ifdef DEBUG
937 -        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
938 -        DUMP_PRUNICHAR(aText, aLength)
939 -#endif
940 -        rv = NS_ERROR_FAILURE;
941 -        goto loser;
942 -    }
943 -
944 -    // Set up the pango layout
945 -    pango_layout_set_text(layout, text, strlen(text));
946 -    FixupSpaceWidths(layout, text);
947 +    PangoLayout *layout = GetLayout(aText, aLength);
948 +    pango_layout_get_log_attrs(layout, &attrs, &n_attrs);
949 +    g_object_unref(layout);
950  
951      // Convert back to UTF-16 while filling in the cluster info
952      // structure.
953 -    pango_layout_get_log_attrs(layout, &attrs, &n_attrs);
954 -
955      for (PRUint32 pos = 0; pos < aLength; pos++) {
956          if (IS_HIGH_SURROGATE(aText[pos])) {
957 -            aClusterStarts[pos] = 1;
958 +            aClusterStarts[pos] = 1;//FIXME: shouldn't this be zero?! --be
959              pos++;
960          }
961          else {
962 @@ -934,56 +1106,34 @@ nsFontMetricsPango::GetClusterInfo(const
963          }
964      }
965  
966 - loser:
967 -    if (attrs)
968 -        g_free(attrs);
969 -    if (text)
970 -        g_free(text);
971 -    if (layout)
972 -        g_object_unref(layout);
973 +    g_free(attrs);
974  
975 -    return rv;
976 +    return NS_OK;
977  }
978  
979  PRInt32
980 -nsFontMetricsPango::GetPosition(const PRUnichar *aText, PRUint32 aLength,
981 -                                nsPoint aPt)
982 +nsFontMetricsPango::GetPosition(const PRUnichar *aText, PRUint32 aLength, nsPoint aPt)
983  {
984      int trailing = 0;
985      int inx = 0;
986 -    const gchar *curChar;
987      PRInt32 retval = 0;
988  
989      float f = mDeviceContext->AppUnitsToDevUnits();
990      
991 -    PangoLayout *layout = pango_layout_new(mPangoContext);
992      PRUint32 localX = (PRUint32)(aPt.x * PANGO_SCALE * f);
993      PRUint32 localY = (PRUint32)(aPt.y * PANGO_SCALE * f);
994  
995 -    // Convert the incoming UTF-16 to UTF-8
996 -    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
997 -
998 -    if (!text) {
999 -#ifdef DEBUG
1000 -        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
1001 -        DUMP_PRUNICHAR(aText, aLength)
1002 -#endif
1003 -        retval = -1;
1004 -        goto loser;
1005 -    }
1006 -
1007 -    // Set up the pango layout
1008 -    pango_layout_set_text(layout, text, strlen(text));
1009 -    FixupSpaceWidths(layout, text);
1010 +    PangoLayout *layout = GetLayout(aText, aLength);
1011      
1012      pango_layout_xy_to_index(layout, localX, localY,
1013                               &inx, &trailing);
1014  
1015      // Convert the index back to the utf-16 index
1016 -    curChar = text;
1017 +    const gchar *text = pango_layout_get_text (layout);
1018 +    const gchar *curChar = text;
1019  
1020      for (PRUint32 curOffset=0; curOffset < aLength;
1021 -         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
1022 +         curOffset++, curChar = g_utf8_next_char(curChar)) {
1023  
1024          // Check for a match before checking for a surrogate pair
1025          if (curChar - text == inx) {
1026 @@ -1006,13 +1156,9 @@ nsFontMetricsPango::GetPosition(const PR
1027          trailing--;
1028      }
1029  
1030 - loser:
1031 -    if (text)
1032 -        g_free(text);
1033 -    if (layout)
1034 -        g_object_unref(layout);
1035 +    g_object_unref(layout);
1036  
1037 -    return retval;
1038 +    return retval; 
1039  }
1040  
1041  nsresult
1042 @@ -1022,28 +1168,21 @@ nsFontMetricsPango::GetRangeWidth(const 
1043                                    PRUint32 aEnd,
1044                                    PRUint32 &aWidth)
1045  {
1046 -    nsresult rv = NS_OK;
1047      PRUint32 utf8Start = 0;
1048      PRUint32 utf8End = 0;
1049  
1050      aWidth = 0;
1051  
1052      // Convert the incoming UTF-16 to UTF-8
1053 -    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
1054 -    gchar *curChar = text;
1055  
1056 -    if (!text) {
1057 -#ifdef DEBUG
1058 -        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
1059 -        DUMP_PRUNICHAR(aText, aLength)
1060 -#endif
1061 -        rv = NS_ERROR_FAILURE;
1062 -        goto loser;
1063 -    }
1064 +    gchar* text;
1065 +    gint text_len;
1066 +    utf16_to_utf8 (aText, aLength, text, text_len);
1067 +    gchar *curChar = text;
1068  
1069      // Convert the utf16 offsets into utf8 offsets
1070      for (PRUint32 curOffset = 0; curOffset < aLength;
1071 -         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
1072 +         curOffset++, curChar = g_utf8_next_char(curChar)) {
1073  
1074          if (curOffset == aStart)
1075              utf8Start = curChar - text;
1076 @@ -1057,15 +1196,13 @@ nsFontMetricsPango::GetRangeWidth(const 
1077  
1078      // Special case where the end index is the same as the length
1079      if (aLength == aEnd)
1080 -        utf8End = strlen(text);
1081 +        utf8End = text_len;
1082  
1083 -    rv = GetRangeWidth(text, strlen(text), utf8Start, utf8End, aWidth);
1084 +    GetRangeWidth(text, text_len, utf8Start, utf8End, aWidth);
1085  
1086 - loser:
1087 -    if (text)
1088 -        g_free(text);
1089 +    g_free(text);
1090  
1091 -    return rv;
1092 +    return NS_OK;
1093  }
1094  
1095  nsresult
1096 @@ -1075,43 +1212,26 @@ nsFontMetricsPango::GetRangeWidth(const 
1097                                    PRUint32 aEnd,
1098                                    PRUint32 &aWidth)
1099  {
1100 -    nsresult rv = NS_OK;
1101      int *ranges = NULL;
1102      int n_ranges = 0;
1103      float f;
1104  
1105      aWidth = 0;
1106  
1107 -    PangoLayout *layout = pango_layout_new(mPangoContext);
1108 -
1109 -    if (!aText) {
1110 -        rv = NS_ERROR_FAILURE;
1111 -        goto loser;
1112 -    }
1113 -
1114 -    pango_layout_set_text(layout, aText, aLength);
1115 -    FixupSpaceWidths(layout, aText);
1116 -
1117 -    PangoLayoutLine *line;
1118 -    if (pango_layout_get_line_count(layout) != 1) {
1119 -        printf("Warning: more than one line!\n");
1120 -    }
1121 -    line = pango_layout_get_line(layout, 0);
1122 +    PangoLayout *layout = GetLayout(aText, aLength);
1123 +    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
1124  
1125      pango_layout_line_get_x_ranges(line, aStart, aEnd, &ranges, &n_ranges);
1126  
1127      aWidth = (ranges[((n_ranges - 1) * 2) + 1] - ranges[0]);
1128  
1129      f = mDeviceContext-> DevUnitsToAppUnits();
1130 -    aWidth = nscoord(aWidth * f / PANGO_SCALE);
1131 +    aWidth = NSToCoordRound(aWidth * f / PANGO_SCALE);
1132  
1133 - loser:
1134 -    if (ranges)
1135 -        g_free(ranges);
1136 -    if (layout)
1137 -        g_object_unref(layout);
1138 +    g_free(ranges);
1139 +    g_object_unref(layout);
1140  
1141 -    return rv;
1142 +    return NS_OK;
1143  }
1144  
1145  /* static */
1146 @@ -1134,7 +1254,7 @@ nsFontMetricsPango::FamilyExists(nsIDevi
1147      NS_ConvertUTF16toUTF8 name(aName);
1148  
1149      nsresult rv = NS_ERROR_FAILURE;
1150 -    PangoContext *context = gdk_pango_context_get();
1151 +    PangoContext *context = get_context();
1152      PangoFontFamily **familyList;
1153      int n;
1154  
1155 @@ -1233,16 +1353,13 @@ nsFontMetricsPango::RealizeFont(void)
1156  
1157      // Now that we have the font description set up, create the
1158      // context.
1159 -    mLTRPangoContext = gdk_pango_context_get();
1160 +    mLTRPangoContext = get_context();
1161      mPangoContext = mLTRPangoContext;
1162  
1163      // Make sure to set the base direction to LTR - if layout needs to
1164      // render RTL text it will use ::SetRightToLeftText()
1165      pango_context_set_base_dir(mPangoContext, PANGO_DIRECTION_LTR);
1166  
1167 -    // Set the color map so we can draw later.
1168 -    gdk_pango_context_set_colormap(mPangoContext, gdk_rgb_get_cmap());
1169 -
1170      // Set the pango language now that we have a context
1171      pango_context_set_language(mPangoContext, GetPangoLanguage(mLangGroup));
1172  
1173 @@ -1280,79 +1397,268 @@ nsFontMetricsPango::EnumFontCallback(con
1174   * This is only used when there's per-character spacing happening.
1175   * Well, really it can be either line or character spacing but it's
1176   * just turtles all the way down!
1177 + *
1178 + * To do it correctly (ligatures, etc) we need machinery that is private
1179 + * in Pango.  IMPORT IT:
1180 + */
1181 +
1182 +#define _PangoGlyphItemIter _nsFontMetricsPangoGlyphItemIter
1183 +#define PangoGlyphItemIter nsFontMetricsPangoGlyphItemIter
1184 +
1185 +#define LTR(glyph_item) (((glyph_item)->item->analysis.level % 2) == 0)
1186 +
1187 +/* Structure holding state when we're iterating over a GlyphItem.
1188 + * start_index/cluster_end (and range_start/range_end in
1189 + * apply_attrs()) are offsets into the text, so note the difference
1190 + * of glyph_item->item->offset between them and clusters in the
1191 + * log_clusters[] array.
1192   */
1193 +typedef struct _PangoGlyphItemIter PangoGlyphItemIter;
1194 +
1195 +struct _PangoGlyphItemIter
1196 +{
1197 +  PangoGlyphItem *glyph_item;
1198 +  const gchar *text;
1199 +  
1200 +  int start_glyph;
1201 +  int start_index;
1202 +  int start_char;
1203 +
1204 +  int end_glyph;
1205 +  int end_index;
1206 +  int end_char;
1207 +};
1208 +
1209 +/**
1210 + * _pango_glyph_item_iter_next_cluster:
1211 + * @iter: a #PangoGlyphItemIter
1212 + * 
1213 + * Advances the iterator to the next cluster in the glyph item.
1214 + * 
1215 + * Return value: %TRUE if the iterator was advanced, %FALSE if we were already on the
1216 + *  last cluster.
1217 + **/
1218 +static gboolean
1219 +_pango_glyph_item_iter_next_cluster (PangoGlyphItemIter *iter)
1220 +{
1221 +  int glyph_index = iter->end_glyph;
1222 +  PangoGlyphString *glyphs = iter->glyph_item->glyphs;
1223 +  PangoItem *item = iter->glyph_item->item;
1224 +
1225 +  if (LTR (iter->glyph_item))
1226 +    {
1227 +      if (glyph_index == glyphs->num_glyphs)
1228 +       return FALSE;
1229 +    }
1230 +  else
1231 +    {
1232 +      if (glyph_index < 0)
1233 +       return FALSE;
1234 +    }
1235 +      
1236 +  iter->start_glyph = iter->end_glyph;
1237 +  iter->start_index = iter->end_index;
1238 +  iter->start_char = iter->end_char;
1239 +  
1240 +  if (LTR (iter->glyph_item))
1241 +    {
1242 +      while (TRUE)
1243 +       {
1244 +         glyph_index++;
1245 +         
1246 +         if (glyph_index == glyphs->num_glyphs)
1247 +           {
1248 +             iter->end_index = item->offset + item->length;
1249 +             iter->end_char = item->num_chars;
1250 +             break;
1251 +           }
1252 +         
1253 +         if (item->offset + glyphs->log_clusters[glyph_index] != iter->start_index)
1254 +           {
1255 +             iter->end_index = item->offset + glyphs->log_clusters[glyph_index];
1256 +             iter->end_char += g_utf8_strlen (iter->text + iter->start_index,
1257 +                                              iter->end_index - iter->start_index);
1258 +             break; 
1259 +           }
1260 +       }
1261 +    }
1262 +  else                 /* RTL */
1263 +    {
1264 +      while (TRUE)
1265 +       {
1266 +         glyph_index--;
1267 +         
1268 +         if (glyph_index < 0)
1269 +           {
1270 +             iter->end_index = item->offset + item->length;
1271 +             iter->end_char = item->num_chars;
1272 +             break;
1273 +           }
1274 +         
1275 +         if (item->offset + glyphs->log_clusters[glyph_index] != iter->start_index)
1276 +           {
1277 +             iter->end_index = item->offset + glyphs->log_clusters[glyph_index];
1278 +             iter->end_char += g_utf8_strlen (iter->text + iter->start_index,
1279 +                                              iter->end_index - iter->start_index);
1280 +             break; 
1281 +           }
1282 +       }
1283 +    }
1284 +
1285 +  iter->end_glyph = glyph_index;
1286 +  return TRUE;
1287 +}
1288 +
1289 +/**
1290 + * _pango_glyph_item_iter_init_start:
1291 + * @iter: pointer to a #PangoGlyphItemIter structure
1292 + * @glyph_item: the glyph item that the iter points into
1293 + * @text: text corresponding to the glyph item
1294 + * 
1295 + * Initializes a #PangoGlyphItemIter structure to point to the
1296 + * first cluster in a glyph item.
1297 + * 
1298 + * Return value: %FALSE if there are no clusters in the glyph item;
1299 + *  in this case, the state of the iter is undefined.
1300 + **/
1301 +static gboolean
1302 +_pango_glyph_item_iter_init_start (PangoGlyphItemIter  *iter,
1303 +                                  PangoGlyphItem      *glyph_item,
1304 +                                  const char          *text)
1305 +{
1306 +  iter->glyph_item = glyph_item;
1307 +  iter->text = text;
1308 +  
1309 +  if (LTR (glyph_item))
1310 +    iter->end_glyph = 0;
1311 +  else
1312 +    iter->end_glyph = glyph_item->glyphs->num_glyphs - 1;
1313 +
1314 +  iter->end_index = glyph_item->item->offset;
1315 +  iter->end_char = 0;
1316 +
1317 +  /* Advance onto the first cluster of the glyph item */
1318 +  return _pango_glyph_item_iter_next_cluster (iter);
1319 +}
1320 +
1321  
1322  void
1323 -nsFontMetricsPango::DrawStringSlowly(const gchar *aText,
1324 -                                     const PRUnichar *aOrigString,
1325 -                                     PRUint32 aLength,
1326 -                                     GdkDrawable *aDrawable,
1327 -                                     GdkGC *aGC, gint aX, gint aY,
1328 -                                     PangoLayoutLine *aLine,
1329 -                                     const nscoord *aSpacing)
1330 -{
1331 -    float app2dev;
1332 -    app2dev = mDeviceContext->AppUnitsToDevUnits();
1333 -    gint offset = 0;
1334 +nsFontMetricsPango::ApplySpacing(const gchar *aText,
1335 +                                 PRUint32 aLength,
1336 +                                 PangoLayoutLine *aLine,
1337 +                                 const nscoord *aSpacing)
1338 +{
1339 +    if (!(aSpacing && *aSpacing))
1340 +      return;
1341 +
1342 +    float app2dev = mDeviceContext->AppUnitsToDevUnits();
1343  
1344      /*
1345       * We walk the list of glyphs returned in each layout run,
1346       * matching up the glyphs with the characters in the source text.
1347       * We use the aSpacing argument to figure out where to place those
1348 -     * glyphs.  It's important to note that since the string we're
1349 -     * working with is in UTF-8 while the spacing argument assumes
1350 -     * that offset will be part of the UTF-16 string.  Logical
1351 -     * attributes in pango are in byte offsets in the UTF-8 string, so
1352 -     * we need to store the offsets based on the UTF-8 string.
1353 +     * glyphs.
1354       */
1355 -    nscoord *utf8spacing = new nscoord[strlen(aText)];
1356 +    for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
1357 +         tmpList = tmpList->next) {
1358 +        PangoGlyphItem *glyph_item = (PangoGlyphItem *)tmpList->data;
1359 +        PangoGlyphItemIter iter;
1360 +        gboolean have_cluster;
1361 +        PangoGlyphInfo *glyphs = glyph_item->glyphs->glyphs;
1362 +        int residualWidth = 0;
1363 +
1364 +        for (have_cluster = _pango_glyph_item_iter_init_start (&iter, glyph_item, aText);
1365 +             have_cluster;
1366 +             have_cluster = _pango_glyph_item_iter_next_cluster (&iter))
1367 +        {
1368 +          int clusterOldWidth = 0;
1369 +          int clusterNewWidth = 0;
1370 +          int dir = iter.start_glyph < iter.end_glyph ? +1 : -1;
1371 +          gboolean has_zero_width = FALSE;
1372 +
1373 +          for (const char *p = iter.text + iter.start_index;
1374 +               p < iter.text + iter.end_index;
1375 +               p = g_utf8_next_char (p))
1376 +            clusterNewWidth += aSpacing[p - iter.text];
1377 +
1378 +          clusterNewWidth = (gint)(clusterNewWidth * app2dev * PANGO_SCALE);
1379 +
1380 +          for (gint i = iter.start_glyph; i != iter.end_glyph; i += dir) {
1381 +            if (!glyphs[i].geometry.width)
1382 +              has_zero_width = TRUE;
1383 +            clusterOldWidth += glyphs[i].geometry.width;
1384 +          }
1385 +            
1386 +          /* if a zero-width glyph exists, don't touch the glyph widths.
1387 +           * required for combining marks.  ff thinks they have a width.
1388 +           * instead, we charge the difference to the next space glyph. */
1389 +          if (has_zero_width) {
1390 +            residualWidth += clusterNewWidth - clusterOldWidth;
1391 +            continue;
1392 +          }
1393  
1394 -    if (aOrigString) {
1395 -        const gchar *curChar = aText;
1396 -        bzero(utf8spacing, sizeof(nscoord) * strlen(aText));
1397 -
1398 -        // Covert the utf16 spacing offsets to utf8 spacing offsets
1399 -        for (PRUint32 curOffset=0; curOffset < aLength;
1400 -             curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
1401 -            utf8spacing[curChar - aText] = aSpacing[curOffset];
1402 +          /* If a space glyph is found, charge it whatever residual we
1403 +           * have accumulated so far. */
1404 +          if (iter.end_index - iter.start_index == 1 &&
1405 +              *(iter.text + iter.start_index) == ' ') {
1406 +            clusterNewWidth += residualWidth;
1407 +            residualWidth = 0;
1408 +          }
1409 +          
1410 +#ifndef PSPANGO
1411 +          /* do some hinting for display */
1412 +
1413 +          if (clusterOldWidth % PANGO_SCALE == 0 && clusterNewWidth % PANGO_SCALE != 0) {
1414 +            int tmp = clusterNewWidth;
1415 +            clusterNewWidth = PANGO_PIXELS (clusterNewWidth) * PANGO_SCALE;
1416 +            residualWidth += tmp - clusterNewWidth;
1417 +          }
1418 +#endif
1419  
1420 -            if (IS_HIGH_SURROGATE(aOrigString[curOffset]))
1421 -                curOffset++;
1422 +          /* find the first non-zero-width glyph and adjust its width */
1423 +          for (gint i = iter.start_glyph; i != iter.end_glyph; i += dir)
1424 +            if (glyphs[i].geometry.width) {
1425 +              glyphs[i].geometry.width += clusterNewWidth - clusterOldWidth;
1426 +              break;
1427 +            }
1428          }
1429      }
1430 -    else {
1431 -        memcpy(utf8spacing, aSpacing, (sizeof(nscoord *) * aLength));
1432 -    }
1433 +}
1434  
1435 -    gint curRun = 0;
1436 +void
1437 +nsFontMetricsPango::ApplySpacing(const PRUnichar *aText,
1438 +                                 PRUint32 aLength,
1439 +                                 PangoLayoutLine *aLine,
1440 +                                 const nscoord *aSpacing)
1441 +{
1442 +    if (!(aSpacing && *aSpacing))
1443 +      return;
1444  
1445 -    for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
1446 -         tmpList = tmpList->next, curRun++) {
1447 -        PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data;
1448 -        gint tmpOffset = 0;
1449 +    const char *utf8Text = pango_layout_get_text (aLine->layout);
1450 +    int utf8Text_len = aLine->start_index + aLine->length;
1451  
1452 -        /*        printf("    Rendering run %d: \"%s\"\n", curRun,
1453 -                  &aText[layoutRun->item->offset]); */
1454 +    /* Since the string we're
1455 +     * working with is in UTF-8 while the spacing argument assumes
1456 +     * that offset will be part of the UTF-16 string.  Logical
1457 +     * attributes in pango are in byte offsets in the UTF-8 string, so
1458 +     * we need to store the offsets based on the UTF-8 string.
1459 +     */
1460 +    nscoord *utf8spacing = g_new0 (nscoord, utf8Text_len);
1461  
1462 -        for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) {
1463 -            /* printf("glyph %d offset %d orig width %d new width %d\n", i,
1464 -             *        layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset,
1465 -             *        layoutRun->glyphs->glyphs[i].geometry.width,
1466 -             *       (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset] * app2dev * PANGO_SCALE));
1467 -             */
1468 -            gint thisOffset = (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset]
1469 -                                     * app2dev * PANGO_SCALE);
1470 -            layoutRun->glyphs->glyphs[i].geometry.width = thisOffset;
1471 -            tmpOffset += thisOffset;
1472 -        }
1473 +    const gchar *curChar = utf8Text + aLine->start_index;
1474  
1475 -        /*        printf("    rendering at X coord %d\n", aX + offset); */
1476 -        offset += tmpOffset;
1477 +    // Covert the utf16 spacing offsets to utf8 spacing offsets
1478 +    for (PRUint32 curOffset=0; curOffset < aLength;
1479 +         curOffset++, curChar = g_utf8_next_char(curChar)) {
1480 +        utf8spacing[curChar - utf8Text] = aSpacing[curOffset];
1481 +
1482 +        if (IS_HIGH_SURROGATE(aText[curOffset]))
1483 +            curOffset++;
1484      }
1485  
1486 -    gdk_draw_layout_line(aDrawable, aGC, aX, aY, aLine);
1487 +    ApplySpacing (utf8Text, utf8Text_len, aLine, utf8spacing);
1488  
1489 -    delete[] utf8spacing;
1490 +    g_free (utf8spacing);
1491  }
1492  
1493  nsresult
1494 @@ -1363,8 +1669,8 @@ nsFontMetricsPango::GetTextDimensionsInt
1495                                                PRInt32             aNumBreaks,
1496                                                nsTextDimensions&   aDimensions,
1497                                                PRInt32&            aNumCharsFit,
1498 -                                              nsTextDimensions&   aLastWordDimensions,
1499 -                                              nsRenderingContextGTK *aContext)
1500 +                                              nsTextDimensions&   aLastWordDimensions
1501 +                                              CONTEXT_ARG_DEF)
1502  {
1503      NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");
1504  
1505 @@ -1410,7 +1716,7 @@ nsFontMetricsPango::GetTextDimensionsInt
1506              // All the characters should fit
1507              numChars = aLength - start;
1508              breakIndex = aNumBreaks - 1;
1509 -        } 
1510 +        }
1511          else {
1512              breakIndex = prevBreakState_BreakIndex;
1513              while (((breakIndex + 1) < aNumBreaks) &&
1514 @@ -1431,7 +1737,7 @@ nsFontMetricsPango::GetTextDimensionsInt
1515          if ((1 == numChars) && (aString[start] == ' '))
1516              GetSpaceWidth(twWidth);
1517          else if (numChars > 0)
1518 -            GetWidth(&aString[start], numChars, twWidth, aContext);
1519 +            GetWidth(&aString[start], numChars, twWidth CONTEXT_ARG_PASS);
1520  
1521          // See if the text fits
1522          PRBool  textFits = (twWidth + width) <= aAvailWidth;
1523 @@ -1481,8 +1787,7 @@ nsFontMetricsPango::GetTextDimensionsInt
1524                  if ((1 == numChars) && (aString[start] == ' '))
1525                      GetSpaceWidth(twWidth);
1526                  else if (numChars > 0)
1527 -                    GetWidth(&aString[start], numChars, twWidth,
1528 -                             aContext);
1529 +                    GetWidth(&aString[start], numChars, twWidth CONTEXT_ARG_PASS);
1530                  width -= twWidth;
1531                  aNumCharsFit = start;
1532                  breakIndex--;
1533 @@ -1504,9 +1809,16 @@ nsFontMetricsPango::GetTextDimensionsInt
1534  }
1535  
1536  void
1537 -nsFontMetricsPango::FixupSpaceWidths (PangoLayout *aLayout,
1538 -                                      const char *aString)
1539 +nsFontMetricsPango::FixupSpaceWidths (PangoLayout *aLayout)
1540  {
1541 +    if (!mPangoSpaceWidth)
1542 +      return;
1543 +
1544 +    const char *aString = pango_layout_get_text (aLayout);
1545 +
1546 +    if (pango_layout_get_line_count(aLayout) != 1) {
1547 +        printf("Warning: more than one line!\n");
1548 +    }
1549      PangoLayoutLine *line = pango_layout_get_line(aLayout, 0);
1550  
1551      gint curRun = 0;
1552 @@ -1523,6 +1835,107 @@ nsFontMetricsPango::FixupSpaceWidths (Pa
1553      }
1554  }
1555  
1556 +PangoLayout*
1557 +nsFontMetricsPango::GetLayout (const PRUnichar* aText,
1558 +                               PRUint32         aLength)
1559 +{
1560 +  gchar* text;
1561 +  gint length;
1562 +  utf16_to_utf8 (aText, aLength, text, length);
1563 +
1564 +  PangoLayout *layout = pango_layout_new(mPangoContext);
1565 +  pango_layout_set_text (layout, text, length);
1566 +  FixupSpaceWidths (layout);
1567 +
1568 +  g_free ((gpointer) text);
1569 +
1570 +  return layout;
1571 +}
1572 +
1573 +PangoLayout*
1574 +nsFontMetricsPango::GetLayout (const gchar*     aText,
1575 +                               PRInt32          aLength)
1576 +{
1577 +  gboolean has_nul = FALSE;
1578 +  int i;
1579 +
1580 +  for (i = 0; i < aLength; i++)
1581 +    if (!aText[i]) {
1582 +      has_nul = TRUE;
1583 +      break;
1584 +    }
1585 +
1586 +  if (has_nul) {
1587 +    /* Pango doesn't correctly handle nuls.  We convert them to 0xff. */
1588 +
1589 +    char *p = (char *) g_memdup (aText, aLength);
1590 +
1591 +    /* don't need to reset i */
1592 +    for (; i < aLength; i++)
1593 +      if (!p[i])
1594 +        p[i] = (char) 0xff;
1595 +
1596 +    aText = p;
1597 +  }
1598 +
1599 +  PangoLayout *layout = pango_layout_new(mPangoContext);
1600 +  pango_layout_set_text (layout, aText, aLength);
1601 +  FixupSpaceWidths (layout);
1602 +
1603 +  if (has_nul)
1604 +    g_free ((gpointer) aText);
1605 +
1606 +  return layout;
1607 +}
1608 +
1609 +static void
1610 +utf16_to_utf8 (const PRUnichar* aText, PRUint32 aLength, char *&text, gint &length)
1611 +{
1612 +  gboolean need_copy = FALSE;
1613 +  int i;
1614 +
1615 +  for (i = 0; i < aLength; i++) {
1616 +    if (!aText[i] || IS_LOW_SURROGATE (aText[i]))
1617 +      need_copy = TRUE;
1618 +    else if (IS_HIGH_SURROGATE (aText[i])) {
1619 +      if (i < aLength - 1 && IS_LOW_SURROGATE (aText[i+1]))
1620 +        i++;
1621 +      else
1622 +        need_copy = TRUE;
1623 +    }
1624 +  }
1625 +
1626 +  if (need_copy) {
1627 +
1628 +    /* Pango doesn't correctly handle nuls.  We convert them to 0xff. */
1629 +    /* Also "validate" UTF-16 text to make sure conversion doesn't fail. */
1630 +
1631 +    PRUnichar *p = (PRUnichar *) g_memdup (aText, aLength * sizeof (aText[0]));
1632 +
1633 +    /* don't need to reset i */
1634 +    for (i = 0; i < aLength; i++) {
1635 +      if (!p[i] || IS_LOW_SURROGATE (p[i]))
1636 +        p[i] = 0xFFFD;
1637 +      else if (IS_HIGH_SURROGATE (p[i])) {
1638 +        if (i < aLength - 1 && IS_LOW_SURROGATE (aText[i+1]))
1639 +          i++;
1640 +        else
1641 +          p[i] = 0xFFFD;
1642 +      }
1643 +    }
1644 +
1645 +    aText = p;
1646 +  }
1647 +
1648 +  glong items_written;
1649 +  text = g_utf16_to_utf8 (aText, aLength, NULL, &items_written, NULL);
1650 +  length = items_written;
1651 +
1652 +  if (need_copy)
1653 +    g_free ((gpointer) aText);
1654 +
1655 +}
1656 +
1657  /* static */
1658  PangoLanguage *
1659  GetPangoLanguage(nsIAtom *aLangGroup)
1660 --- mozilla.back/gfx/src/gtk/nsFontMetricsPango.h.orig  2006-06-30 01:18:34.000000000 +0200
1661 +++ mozilla.back/gfx/src/gtk/nsFontMetricsPango.h       2007-06-28 15:16:39.000000000 +0200
1662 @@ -37,17 +37,53 @@
1663   *
1664   * ***** END LICENSE BLOCK ***** */
1665  
1666 +
1667  #include "nsIFontMetrics.h"
1668  #include "nsIFontEnumerator.h"
1669  #include "nsCRT.h"
1670  #include "nsIAtom.h"
1671  #include "nsString.h"
1672  #include "nsVoidArray.h"
1673 +
1674 +#ifdef PSPANGO
1675 +#include "nsFontMetricsPS.h"
1676 +#else
1677  #include "nsIFontMetricsGTK.h"
1678 +#endif
1679  
1680  #include <pango/pango.h>
1681  
1682 -class nsFontMetricsPango : public nsIFontMetricsGTK
1683 +#ifdef PSPANGO
1684 +
1685 +#define CONTEXT_ARG_DEF
1686 +#define CONTEXT_ARG_PASS
1687 +#define CONTEXT_ARG_NULL
1688 +#define CONTEXT_AND_SURFACE_ARG_DEF  , nsRenderingContextPS *aContext
1689 +#define CONTEXT_AND_SURFACE_ARG_PASS , aContext
1690 +
1691 +#else
1692 +
1693 +#define CONTEXT_ARG_DEF              , nsRenderingContextGTK *aContext
1694 +#define CONTEXT_ARG_PASS             , aContext
1695 +#define CONTEXT_ARG_NULL             , NULL
1696 +#define CONTEXT_AND_SURFACE_ARG_DEF  , nsRenderingContextGTK *aContext, nsDrawingSurfaceGTK *aSurface
1697 +#define CONTEXT_AND_SURFACE_ARG_PASS , aContext, aSurface
1698 +
1699 +#endif
1700 +
1701 +
1702 +#ifdef PSPANGO
1703 +
1704 +#define nsFontMetricsPango   nsFontMetricsPSPango
1705 +#define PSPANGO_PARENT_CLASS nsFontMetricsPS
1706 +
1707 +#else
1708 +
1709 +#define PSPANGO_PARENT_CLASS nsIFontMetricsGTK
1710 +
1711 +#endif
1712 +
1713 +class nsFontMetricsPango : public PSPANGO_PARENT_CLASS
1714  {
1715  public:
1716      nsFontMetricsPango();
1717 @@ -136,20 +172,30 @@ public:
1718  
1719      PRInt32 GetMaxStringLength() { return mMaxStringLength; }
1720  
1721 -    // nsIFontMetricsGTK (calls from the font rendering layer)
1722 -    virtual nsresult GetWidth(const char* aString, PRUint32 aLength,
1723 -                              nscoord& aWidth,
1724 -                              nsRenderingContextGTK *aContext);
1725 -    virtual nsresult GetWidth(const PRUnichar* aString, PRUint32 aLength,
1726 -                              nscoord& aWidth, PRInt32 *aFontID,
1727 -                              nsRenderingContextGTK *aContext);
1728 +    // nsIFontMetrics (calls from the font rendering layer)
1729  
1730 -    virtual nsresult GetTextDimensions(const PRUnichar* aString,
1731 +#ifdef PSPANGO
1732 +    NS_IMETHOD  GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength);
1733 +    NS_IMETHOD  GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength);
1734 +#endif
1735 +
1736 +    NS_METHOD        GetWidth(const char* aString, PRUint32 aLength,
1737 +                              nscoord& aWidth
1738 +                              CONTEXT_ARG_DEF);
1739 +    NS_METHOD        GetWidth(const PRUnichar* aString, PRUint32 aLength,
1740 +                              nscoord& aWidth, PRInt32 *aFontID
1741 +                              CONTEXT_ARG_DEF);
1742 +
1743 +    NS_METHOD        GetTextDimensions(const char* aString,
1744 +                                       PRUint32 aLength,
1745 +                                       nsTextDimensions& aDimensions
1746 +                                       CONTEXT_ARG_DEF);
1747 +    NS_METHOD        GetTextDimensions(const PRUnichar* aString,
1748                                         PRUint32 aLength,
1749                                         nsTextDimensions& aDimensions, 
1750 -                                       PRInt32* aFontID,
1751 -                                       nsRenderingContextGTK *aContext);
1752 -    virtual nsresult GetTextDimensions(const char*         aString,
1753 +                                       PRInt32* aFontID
1754 +                                       CONTEXT_ARG_DEF);
1755 +    NS_METHOD        GetTextDimensions(const char*         aString,
1756                                         PRInt32             aLength,
1757                                         PRInt32             aAvailWidth,
1758                                         PRInt32*            aBreaks,
1759 @@ -157,9 +203,9 @@ public:
1760                                         nsTextDimensions&   aDimensions,
1761                                         PRInt32&            aNumCharsFit,
1762                                         nsTextDimensions&   aLastWordDimensions,
1763 -                                       PRInt32*            aFontID,
1764 -                                       nsRenderingContextGTK *aContext);
1765 -    virtual nsresult GetTextDimensions(const PRUnichar*    aString,
1766 +                                       PRInt32*            aFontID
1767 +                                       CONTEXT_ARG_DEF);
1768 +    NS_METHOD        GetTextDimensions(const PRUnichar*    aString,
1769                                         PRInt32             aLength,
1770                                         PRInt32             aAvailWidth,
1771                                         PRInt32*            aBreaks,
1772 @@ -167,38 +213,37 @@ public:
1773                                         nsTextDimensions&   aDimensions,
1774                                         PRInt32&            aNumCharsFit,
1775                                         nsTextDimensions&   aLastWordDimensions,
1776 -                                       PRInt32*            aFontID,
1777 -                                       nsRenderingContextGTK *aContext);
1778 +                                       PRInt32*            aFontID
1779 +                                       CONTEXT_ARG_DEF);
1780  
1781 -    virtual nsresult DrawString(const char *aString, PRUint32 aLength,
1782 +    NS_METHOD        DrawString(const char *aString, PRUint32 aLength,
1783                                  nscoord aX, nscoord aY,
1784 -                                const nscoord* aSpacing,
1785 -                                nsRenderingContextGTK *aContext,
1786 -                                nsDrawingSurfaceGTK *aSurface);
1787 -    virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength,
1788 +                                const nscoord* aSpacing  
1789 +                                CONTEXT_AND_SURFACE_ARG_DEF);
1790 +
1791 +    NS_METHOD        DrawString(const PRUnichar* aString, PRUint32 aLength,
1792                                  nscoord aX, nscoord aY,
1793                                  PRInt32 aFontID,
1794 -                                const nscoord* aSpacing,
1795 -                                nsRenderingContextGTK *aContext,
1796 -                                nsDrawingSurfaceGTK *aSurface);
1797 +                                const nscoord* aSpacing  
1798 +                                CONTEXT_AND_SURFACE_ARG_DEF);
1799  
1800  #ifdef MOZ_MATHML
1801 -    virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength,
1802 -                                        nsBoundingMetrics &aBoundingMetrics,
1803 -                                        nsRenderingContextGTK *aContext);
1804 -    virtual nsresult GetBoundingMetrics(const PRUnichar *aString,
1805 +    NS_METHOD        GetBoundingMetrics(const char *aString, PRUint32 aLength,
1806 +                                        nsBoundingMetrics &aBoundingMetrics
1807 +                                        CONTEXT_ARG_DEF);
1808 +    NS_METHOD        GetBoundingMetrics(const PRUnichar *aString,
1809                                          PRUint32 aLength,
1810                                          nsBoundingMetrics &aBoundingMetrics,
1811 -                                        PRInt32 *aFontID,
1812 -                                        nsRenderingContextGTK *aContext);
1813 +                                        PRInt32 *aFontID
1814 +                                        CONTEXT_ARG_DEF);
1815  #endif /* MOZ_MATHML */
1816 -
1817 +#ifndef PSPANGO
1818      virtual GdkFont* GetCurrentGDKFont(void);
1819 -
1820 -    virtual nsresult SetRightToLeftText(PRBool aIsRTL);
1821 +#endif
1822      virtual PRBool GetRightToLeftText();
1823 -
1824 -    virtual nsresult GetClusterInfo(const PRUnichar *aText,
1825 +    NS_METHOD        SetRightToLeftText(PRBool aIsRTL);
1826 +    
1827 +    NS_METHOD        GetClusterInfo(const PRUnichar *aText,
1828                                      PRUint32 aLength,
1829                                      PRUint8 *aClusterStarts);
1830  
1831 @@ -206,32 +251,35 @@ public:
1832                                  PRUint32 aLength,
1833                                  nsPoint aPt);
1834  
1835 -    virtual nsresult GetRangeWidth(const PRUnichar *aText,
1836 +    NS_METHOD        GetRangeWidth(const PRUnichar *aText,
1837                                     PRUint32 aLength,
1838                                     PRUint32 aStart,
1839                                     PRUint32 aEnd,
1840                                     PRUint32 &aWidth);
1841  
1842 -    virtual nsresult GetRangeWidth(const char *aText,
1843 +    NS_METHOD        GetRangeWidth(const char *aText,
1844                                     PRUint32 aLength,
1845                                     PRUint32 aStart,
1846                                     PRUint32 aEnd,
1847                                     PRUint32 &aWidth);
1848  
1849      // get hints for the font
1850 -    static PRUint32    GetHints     (void);
1851 +#ifndef PSPANGO
1852 +    static
1853 +#endif
1854 +    PRUint32    GetHints     (void);
1855  
1856      // drawing surface methods
1857      static nsresult FamilyExists    (nsIDeviceContext *aDevice,
1858                                       const nsString &aName);
1859  
1860 +
1861  private:
1862  
1863      // generic font metrics class bits
1864      nsCStringArray       mFontList;
1865      nsAutoVoidArray      mFontIsGeneric;
1866  
1867 -    nsIDeviceContext    *mDeviceContext;
1868      nsCOMPtr<nsIAtom>    mLangGroup;
1869      nsCString           *mGenericFont;
1870      float                mPointSize;
1871 @@ -246,6 +294,9 @@ private:
1872      PangoAttrList        *mPangoAttrList;
1873      PRBool                mIsRTL;
1874  
1875 +#ifndef PSPANGO
1876 +    nsIDeviceContext    *mDeviceContext; 
1877 +
1878      // Cached font metrics
1879      nscoord                  mXHeight;
1880      nscoord                  mSuperscriptOffset;
1881 @@ -263,6 +314,7 @@ private:
1882      nscoord                  mMaxDescent;
1883      nscoord                  mMaxAdvance;
1884      nscoord                  mSpaceWidth;
1885 +#endif
1886      nscoord                  mPangoSpaceWidth;
1887      nscoord                  mAveCharWidth;
1888      PRInt32                  mMaxStringLength;
1889 @@ -274,13 +326,14 @@ private:
1890      static PRBool EnumFontCallback(const nsString &aFamily,
1891                                     PRBool aIsGeneric, void *aData);
1892  
1893 -    void     DrawStringSlowly(const gchar *aText,
1894 -                              const PRUnichar *aOrigString,
1895 -                              PRUint32 aLength,
1896 -                              GdkDrawable *aDrawable,
1897 -                              GdkGC *aGC, gint aX, gint aY,
1898 -                              PangoLayoutLine *aLine,
1899 -                              const nscoord *aSpacing);
1900 +    void ApplySpacing(const gchar *aText,
1901 +                      PRUint32 aLength,
1902 +                      PangoLayoutLine *aLine,
1903 +                      const nscoord *aSpacing);
1904 +    void ApplySpacing(const PRUnichar *aText,
1905 +                      PRUint32 aLength,
1906 +                      PangoLayoutLine *aLine,
1907 +                      const nscoord *aSpacing);
1908  
1909      nsresult GetTextDimensionsInternal(const gchar*        aString,
1910                                         PRInt32             aLength,
1911 @@ -289,10 +342,20 @@ private:
1912                                         PRInt32             aNumBreaks,
1913                                         nsTextDimensions&   aDimensions,
1914                                         PRInt32&            aNumCharsFit,
1915 -                                       nsTextDimensions&   aLastWordDimensions,
1916 -                                       nsRenderingContextGTK *aContext);
1917 +                                       nsTextDimensions&   aLastWordDimensions
1918 +                                       CONTEXT_ARG_DEF);
1919 +#ifdef MOZ_MATHML
1920 +    void GetBoundingMetricsInternal(PangoLayout *aLayout,
1921 +                                    nsBoundingMetrics &aBoundingMetrics
1922 +                                    CONTEXT_ARG_DEF);
1923 +#endif /* MOZ_MATHML */
1924 +
1925 +    void FixupSpaceWidths (PangoLayout *aLayout);
1926  
1927 -    void FixupSpaceWidths (PangoLayout *aLayout, const char *aString);
1928 +    PangoLayout* GetLayout (const PRUnichar* aText,
1929 +                            PRUint32         aLength);
1930 +    PangoLayout* GetLayout (const gchar*     aText,
1931 +                            PRInt32          aLength);
1932  };
1933  
1934  class nsFontEnumeratorPango : public nsIFontEnumerator
This page took 0.455851 seconds and 3 git commands to generate.