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