]> git.pld-linux.org Git - packages/firefox.git/blame - 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
CommitLineData
fa18ca2f
AM
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 {
d24b66a1 121@@ -169,15 +228,21 @@
fa18ca2f
AM
122 mLangGroup = aLangGroup;
123
124 // Hang on to the device context
125+#ifdef PSPANGO
126+ mDeviceContext = (nsDeviceContextPS *)aContext;
127+#else
128 mDeviceContext = aContext;
d24b66a1 129-
fa18ca2f 130+#endif
d24b66a1 131+
fa18ca2f
AM
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);
d24b66a1 139 mPointSize = PR_MIN(2000, mPointSize);
fa18ca2f
AM
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.364329 seconds and 4 git commands to generate.