Magellan Linux

Annotation of /trunk/mozilla-firefox/patches/mozilla-firefox-1.0.7-pango-selection.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 153 - (hide annotations) (download)
Tue May 8 20:52:56 2007 UTC (17 years, 1 month ago) by niro
File size: 28829 byte(s)
-import

1 niro 153 --- mozilla/gfx/src/gtk/nsFontMetricsXft.cpp.foo 2004-12-16 13:12:54.000000000 -0500
2     +++ mozilla/gfx/src/gtk/nsFontMetricsXft.cpp 2004-12-16 13:13:31.000000000 -0500
3     @@ -831,6 +831,33 @@
4     return NS_OK;
5     }
6    
7     +nsresult
8     +nsFontMetricsXft::GetClusterInfo(const PRUnichar *aText,
9     + PRUint32 aLength,
10     + PRUint32 *aClusterStarts)
11     +{
12     + return NS_ERROR_NOT_IMPLEMENTED;
13     +}
14     +
15     +nsresult
16     +nsFontMetricsXft::GetPosition(const PRUnichar *aText,
17     + PRUint32 aLength,
18     + nscoord aCoord,
19     + PRUint32 &aInx)
20     +{
21     + return NS_ERROR_NOT_IMPLEMENTED;
22     +}
23     +
24     +nsresult
25     +nsFontMetricsXft::GetRangeWidth(const PRUnichar *aText,
26     + PRUint32 aLength,
27     + PRUint32 aStart,
28     + PRUint32 aEnd,
29     + PRUint32 &aWidth)
30     +{
31     + return NS_ERROR_NOT_IMPLEMENTED;
32     +}
33     +
34     PRUint32
35     nsFontMetricsXft::GetHints(void)
36     {
37     --- mozilla/gfx/src/gtk/nsFontMetricsPango.cpp.foo 2004-12-16 13:12:54.000000000 -0500
38     +++ mozilla/gfx/src/gtk/nsFontMetricsPango.cpp 2004-12-16 13:13:31.000000000 -0500
39     @@ -907,13 +907,222 @@
40     return NS_OK;
41     }
42    
43     +nsresult
44     +nsFontMetricsPango::GetClusterInfo(const PRUnichar *aText,
45     + PRUint32 aLength,
46     + PRUint32 *aClusterStarts)
47     +{
48     + nsresult rv = NS_OK;
49     + PangoLogAttr *attrs = NULL;
50     + gint n_attrs = 0;
51     + PangoLayout *layout = pango_layout_new(mPangoContext);
52     +
53     + // Convert the incoming UTF-16 to UTF-8
54     + gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
55     +
56     + if (!text) {
57     +#ifdef DEBUG
58     + NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
59     + DUMP_PRUNICHAR(aText, aLength)
60     +#endif
61     + rv = NS_ERROR_FAILURE;
62     + goto loser;
63     + }
64     +
65     + // Set up the pango layout
66     + pango_layout_set_text(layout, text, strlen(text));
67     +
68     + // Convert back to UTF-16 while filling in the cluster info
69     + // structure.
70     + pango_layout_get_log_attrs(layout, &attrs, &n_attrs);
71     +
72     + for (PRUint32 pos = 0; pos < aLength; pos++) {
73     + if (IS_HIGH_SURROGATE(aText[pos])) {
74     + aClusterStarts[pos] = 1;
75     + pos++;
76     + }
77     + else {
78     + aClusterStarts[pos] = attrs[pos].is_cursor_position;
79     + }
80     + }
81     +
82     + loser:
83     + if (attrs)
84     + g_free(attrs);
85     + if (text)
86     + g_free(text);
87     + if (layout)
88     + g_object_unref(layout);
89     +
90     + return rv;
91     +}
92     +
93     +nsresult
94     +nsFontMetricsPango::GetPosition(const PRUnichar *aText, PRUint32 aLength,
95     + nscoord aCoord, PRUint32 &aInx)
96     +{
97     + nsresult rv = NS_OK;
98     + int trailing = 0;
99     + int inx = 0;
100     + gboolean found = FALSE;
101     + const gchar *curChar;
102     +
103     + float f = mDeviceContext->AppUnitsToDevUnits();
104     +
105     + PangoLayout *layout = pango_layout_new(mPangoContext);
106     + PRUint32 localCoord = (PRUint32)(aCoord * PANGO_SCALE * f);
107     +
108     + // Convert the incoming UTF-16 to UTF-8
109     + gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
110     +
111     + if (!text) {
112     +#ifdef DEBUG
113     + NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
114     + DUMP_PRUNICHAR(aText, aLength)
115     +#endif
116     + rv = NS_ERROR_FAILURE;
117     + goto loser;
118     + }
119     +
120     + // Set up the pango layout
121     + pango_layout_set_text(layout, text, strlen(text));
122     +
123     + found = pango_layout_xy_to_index(layout, localCoord, 0,
124     + &inx, &trailing);
125     +
126     + // Convert the index back to the utf-16 index
127     + curChar = text;
128     + aInx = 0;
129     +
130     + // Jump to the end if it's not found.
131     + if (!found) {
132     + if (inx = 0)
133     + aInx = 0;
134     + else if (trailing)
135     + aInx = aLength;
136     +
137     + goto loser;
138     + }
139     +
140     + for (PRUint32 curOffset=0; curOffset < aLength;
141     + curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
142     +
143     + // Check for a match before checking for a surrogate pair
144     + if (curChar - text == inx) {
145     + aInx = curOffset;
146     + break;
147     + }
148     +
149     + if (IS_HIGH_SURROGATE(aText[curOffset]))
150     + curOffset++;
151     + }
152     +
153     + // If there was a trailing result, advance the index pointer the
154     + // number of characters equal to the trailing result.
155     + while (trailing) {
156     + aInx++;
157     + // Yes, this can make aInx > length to indicate the end of the
158     + // string.
159     + if (aInx < aLength && IS_HIGH_SURROGATE(aText[aInx]))
160     + aInx++;
161     + trailing--;
162     + }
163     +
164     + loser:
165     + if (text)
166     + g_free(text);
167     + if (layout)
168     + g_object_unref(layout);
169     +
170     + return rv;
171     +}
172     +
173     +nsresult
174     +nsFontMetricsPango::GetRangeWidth(const PRUnichar *aText,
175     + PRUint32 aLength,
176     + PRUint32 aStart,
177     + PRUint32 aEnd,
178     + PRUint32 &aWidth)
179     +{
180     + nsresult rv = NS_OK;
181     + int *ranges = NULL;
182     + int n_ranges = 0;
183     + PRUint32 utf8Start = 0;
184     + PRUint32 utf8End = 0;
185     + float f;
186     +
187     + aWidth = 0;
188     +
189     + // Convert the incoming UTF-16 to UTF-8
190     + gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
191     + gchar *curChar = text;
192     +
193     + PangoLayout *layout = pango_layout_new(mPangoContext);
194     +
195     + if (!text) {
196     +#ifdef DEBUG
197     + NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
198     + DUMP_PRUNICHAR(aText, aLength)
199     +#endif
200     + rv = NS_ERROR_FAILURE;
201     + goto loser;
202     + }
203     +
204     + // Convert the utf16 offsets into utf8 offsets
205     + for (PRUint32 curOffset = 0; curOffset < aLength;
206     + curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
207     +
208     + if (curOffset == aStart)
209     + utf8Start = curChar - text;
210     +
211     + if (curOffset == aEnd)
212     + utf8End = curChar - text;
213     +
214     + if (IS_HIGH_SURROGATE(aText[curOffset]))
215     + curOffset++;
216     + }
217     +
218     + // Special case where the end index is the same as the length
219     + if (aLength == aEnd)
220     + utf8End = strlen(text);
221     +
222     + pango_layout_set_text(layout, text, strlen(text));
223     +
224     + PangoLayoutLine *line;
225     + if (pango_layout_get_line_count(layout) != 1) {
226     + printf("Warning: more than one line!\n");
227     + }
228     + line = pango_layout_get_line(layout, 0);
229     +
230     + pango_layout_line_get_x_ranges(line, utf8Start, utf8End, &ranges, &n_ranges);
231     +
232     + // Convert the width into app units
233     + for (int i = 0; i < n_ranges; i++) {
234     + aWidth += (ranges[(i * 2) + 1] - ranges[(i * 2)]) / PANGO_SCALE;
235     + }
236     +
237     + f = mDeviceContext-> DevUnitsToAppUnits();
238     + aWidth = nscoord(aWidth * f);
239     +
240     + loser:
241     + if (ranges)
242     + g_free(ranges);
243     + if (text)
244     + g_free(text);
245     + if (layout)
246     + g_object_unref(layout);
247     +
248     + return rv;
249     +}
250     +
251     /* static */
252     PRUint32
253     nsFontMetricsPango::GetHints(void)
254     {
255     return (NS_RENDERING_HINT_BIDI_REORDERING |
256     NS_RENDERING_HINT_ARABIC_SHAPING |
257     - NS_RENDERING_HINT_FAST_MEASURE);
258     + NS_RENDERING_HINT_FAST_MEASURE |
259     + NS_RENDERING_HINT_TEXT_CLUSTERS);
260     }
261    
262     /* static */
263     @@ -1137,13 +1346,11 @@
264     }
265    
266     /* printf(" rendering at X coord %d\n", aX + offset); */
267     -
268     - gdk_draw_glyphs(aDrawable, aGC, layoutRun->item->analysis.font,
269     - aX + (gint)(offset / PANGO_SCALE), aY, layoutRun->glyphs);
270     -
271     offset += tmpOffset;
272     }
273    
274     + gdk_draw_layout_line(aDrawable, aGC, aX, aY, aLine);
275     +
276     delete[] utf8spacing;
277     }
278    
279     --- mozilla/gfx/src/gtk/nsRenderingContextGTK.h.foo 2004-12-16 13:12:54.000000000 -0500
280     +++ mozilla/gfx/src/gtk/nsRenderingContextGTK.h 2004-12-16 13:13:31.000000000 -0500
281     @@ -195,6 +195,15 @@
282     NS_IMETHOD RetrieveCurrentNativeGraphicData(PRUint32 * ngd);
283    
284     NS_IMETHOD SetRightToLeftText(PRBool aIsRTL);
285     + NS_IMETHOD GetClusterInfo(const PRUnichar *aText, PRUint32 aLength,
286     + PRUint32 *aClusterStarts);
287     + NS_IMETHOD GetPosition(const PRUnichar *aText, PRUint32 aLength,
288     + nscoord aCoord, PRUint32 &aInx);
289     + NS_IMETHOD GetRangeWidth(const PRUnichar *aText,
290     + PRUint32 aLength,
291     + PRUint32 aStart,
292     + PRUint32 aEnd,
293     + PRUint32 &aWidth);
294    
295     NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint);
296     NS_IMETHOD DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect);
297     --- mozilla/gfx/src/gtk/nsFontMetricsPango.h.foo 2004-12-16 13:12:54.000000000 -0500
298     +++ mozilla/gfx/src/gtk/nsFontMetricsPango.h 2004-12-16 13:13:31.000000000 -0500
299     @@ -195,6 +195,21 @@
300    
301     virtual nsresult SetRightToLeftText(PRBool aIsRTL);
302    
303     + virtual nsresult GetClusterInfo(const PRUnichar *aText,
304     + PRUint32 aLength,
305     + PRUint32 *aClusterStarts);
306     +
307     + virtual nsresult GetPosition(const PRUnichar *aText,
308     + PRUint32 aLength,
309     + nscoord aCoord,
310     + PRUint32 &aInx);
311     +
312     + virtual nsresult GetRangeWidth(const PRUnichar *aText,
313     + PRUint32 aLength,
314     + PRUint32 aStart,
315     + PRUint32 aEnd,
316     + PRUint32 &aWidth);
317     +
318     // get hints for the font
319     static PRUint32 GetHints (void);
320    
321     --- mozilla/gfx/src/gtk/nsIFontMetricsGTK.h.foo 2004-12-16 13:12:54.000000000 -0500
322     +++ mozilla/gfx/src/gtk/nsIFontMetricsGTK.h 2004-12-16 13:13:31.000000000 -0500
323     @@ -124,6 +124,21 @@
324     // Set the direction of the text rendering
325     virtual nsresult SetRightToLeftText(PRBool aIsRTL) = 0;
326    
327     + virtual nsresult GetClusterInfo(const PRUnichar *aText,
328     + PRUint32 aLength,
329     + PRUint32 *aClusterStarts) = 0;
330     +
331     + virtual nsresult GetPosition(const PRUnichar *aText,
332     + PRUint32 aLength,
333     + nscoord aCoord,
334     + PRUint32 &aInx) = 0;
335     +
336     + virtual nsresult GetRangeWidth(const PRUnichar *aText,
337     + PRUint32 aLength,
338     + PRUint32 aStart,
339     + PRUint32 aEnd,
340     + PRUint32 &aWidth) = 0;
341     +
342     };
343    
344     #endif /* __nsIFontMetricsGTK_h */
345     --- mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp.foo 2004-12-16 13:12:54.000000000 -0500
346     +++ mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp 2004-12-16 13:13:31.000000000 -0500
347     @@ -1446,6 +1446,26 @@
348     return mFontMetrics->SetRightToLeftText(aIsRTL);
349     }
350    
351     +NS_IMETHODIMP nsRenderingContextGTK::GetClusterInfo(const PRUnichar *aText,
352     + PRUint32 aLength,
353     + PRUint32 *aClusterStarts)
354     +{
355     + return mFontMetrics->GetClusterInfo(aText, aLength, aClusterStarts);
356     +}
357     +
358     +NS_IMETHODIMP nsRenderingContextGTK::GetPosition(const PRUnichar *aText, PRUint32 aLength,
359     + nscoord aCoord, PRUint32 &aInx)
360     +{
361     + return mFontMetrics->GetPosition(aText, aLength, aCoord, aInx);
362     +}
363     +
364     +NS_IMETHODIMP nsRenderingContextGTK::GetRangeWidth(const PRUnichar *aText, PRUint32 aLength,
365     + PRUint32 aStart, PRUint32 aEnd,
366     + PRUint32 &aWidth)
367     +{
368     + return mFontMetrics->GetRangeWidth(aText, aLength, aStart, aEnd, aWidth);
369     +}
370     +
371     NS_IMETHODIMP nsRenderingContextGTK::DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint)
372     {
373     UpdateGC();
374     --- mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp.foo 2004-12-16 13:12:54.000000000 -0500
375     +++ mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp 2004-12-16 13:13:31.000000000 -0500
376     @@ -4606,6 +4606,34 @@
377     return NS_OK;
378     }
379    
380     +nsresult
381     +nsFontMetricsGTK::GetClusterInfo(const PRUnichar *aText,
382     + PRUint32 aLength,
383     + PRUint32 *aClusterStarts)
384     +{
385     + return NS_ERROR_NOT_IMPLEMENTED;
386     +}
387     +
388     +nsresult
389     +nsFontMetricsGTK::GetPosition(const PRUnichar *aText,
390     + PRUint32 aLength,
391     + nscoord aCoord,
392     + PRUint32 &aInx)
393     +{
394     + return NS_ERROR_NOT_IMPLEMENTED;
395     +}
396     +
397     +
398     +nsresult
399     +nsFontMetricsGTK::GetRangeWidth(const PRUnichar *aText,
400     + PRUint32 aLength,
401     + PRUint32 aStart,
402     + PRUint32 aEnd,
403     + PRUint32 &aWidth)
404     +{
405     + return NS_ERROR_NOT_IMPLEMENTED;
406     +}
407     +
408     PR_BEGIN_EXTERN_C
409     static int
410     CompareSizes(const void* aArg1, const void* aArg2, void *data)
411     --- mozilla/gfx/src/gtk/nsFontMetricsXft.h.foo 2004-12-16 13:12:54.000000000 -0500
412     +++ mozilla/gfx/src/gtk/nsFontMetricsXft.h 2004-12-16 13:13:31.000000000 -0500
413     @@ -204,6 +204,21 @@
414    
415     virtual nsresult SetRightToLeftText(PRBool aIsRTL);
416    
417     + virtual nsresult GetClusterInfo(const PRUnichar *aText,
418     + PRUint32 aLength,
419     + PRUint32 *aClusterStarts);
420     +
421     + virtual nsresult GetPosition(const PRUnichar *aText,
422     + PRUint32 aLength,
423     + nscoord aCoord,
424     + PRUint32 &aInx);
425     +
426     + virtual nsresult GetRangeWidth(const PRUnichar *aText,
427     + PRUint32 aLength,
428     + PRUint32 aStart,
429     + PRUint32 aEnd,
430     + PRUint32 &aWidth);
431     +
432     // get hints for the font
433     static PRUint32 GetHints (void);
434    
435     --- mozilla/gfx/src/gtk/nsFontMetricsGTK.h.foo 2004-12-16 13:12:54.000000000 -0500
436     +++ mozilla/gfx/src/gtk/nsFontMetricsGTK.h 2004-12-16 13:13:31.000000000 -0500
437     @@ -346,6 +346,21 @@
438    
439     virtual nsresult SetRightToLeftText(PRBool aIsRTL);
440    
441     + virtual nsresult GetClusterInfo(const PRUnichar *aText,
442     + PRUint32 aLength,
443     + PRUint32 *aClusterStarts);
444     +
445     + virtual nsresult GetPosition(const PRUnichar *aText,
446     + PRUint32 aLength,
447     + nscoord aCoord,
448     + PRUint32 &aInx);
449     +
450     + virtual nsresult GetRangeWidth(const PRUnichar *aText,
451     + PRUint32 aLength,
452     + PRUint32 aStart,
453     + PRUint32 aEnd,
454     + PRUint32 &aWidth);
455     +
456     static nsresult FamilyExists(nsIDeviceContext *aDevice, const nsString& aName);
457     static PRUint32 GetHints(void);
458    
459     --- mozilla/gfx/src/shared/nsRenderingContextImpl.cpp.foo 2004-10-08 12:57:19.000000000 -0400
460     +++ mozilla/gfx/src/shared/nsRenderingContextImpl.cpp 2004-12-16 13:13:31.000000000 -0500
461     @@ -938,3 +938,32 @@
462     {
463     return NS_OK;
464     }
465     +
466     +NS_IMETHODIMP
467     +nsRenderingContextImpl::GetClusterInfo(const PRUnichar *aText,
468     + PRUint32 aLength,
469     + PRUint32 *aClusterStarts)
470     +{
471     + return NS_ERROR_NOT_IMPLEMENTED;
472     +}
473     +
474     +NS_IMETHODIMP
475     +nsRenderingContextImpl::GetPosition(const PRUnichar *aText,
476     + PRUint32 aLength,
477     + nscoord aCoord,
478     + PRUint32 &aInx)
479     +{
480     + return NS_ERROR_NOT_IMPLEMENTED;
481     +}
482     +
483     +NS_IMETHODIMP
484     +nsRenderingContextImpl::GetRangeWidth(const PRUnichar *aText,
485     + PRUint32 aLength,
486     + PRUint32 aStart,
487     + PRUint32 aEnd,
488     + PRUint32 &aWidth)
489     +{
490     + return NS_ERROR_NOT_IMPLEMENTED;
491     +}
492     +
493     +
494     --- mozilla/gfx/src/nsRenderingContextImpl.h.foo 2004-10-08 12:57:18.000000000 -0400
495     +++ mozilla/gfx/src/nsRenderingContextImpl.h 2004-12-16 13:13:31.000000000 -0500
496     @@ -138,6 +138,19 @@
497     NS_IMETHOD DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect);
498     NS_IMETHOD DrawTile(imgIContainer *aImage, nscoord aXOffset, nscoord aYOffset, const nsRect * aTargetRect);
499    
500     + NS_IMETHOD GetClusterInfo(const PRUnichar *aText,
501     + PRUint32 aLength,
502     + PRUint32 *aClusterStarts);
503     + NS_IMETHOD GetPosition(const PRUnichar *aText,
504     + PRUint32 aLength,
505     + nscoord aCoord,
506     + PRUint32 &aInx);
507     + NS_IMETHOD GetRangeWidth(const PRUnichar *aText,
508     + PRUint32 aLength,
509     + PRUint32 aStart,
510     + PRUint32 aEnd,
511     + PRUint32 &aWidth);
512     +
513     protected:
514     virtual ~nsRenderingContextImpl();
515    
516     --- mozilla/gfx/public/nsIRenderingContext.h.foo 2004-10-08 12:57:18.000000000 -0400
517     +++ mozilla/gfx/public/nsIRenderingContext.h 2004-12-16 13:13:31.000000000 -0500
518     @@ -824,6 +824,66 @@
519     NS_IMETHOD DrawTile(imgIContainer *aImage,
520     nscoord aXImageStart, nscoord aYImageStart,
521     const nsRect * aTargetRect) = 0;
522     +
523     + /**
524     + * Get cluster details for a chunk of text.
525     + *
526     + * This will fill in the aClusterStarts array with information about
527     + * what characters are the start of clusters for display.
528     + *
529     + * @param aText Text on which to get details.
530     + * @param aLength Length of the text.
531     + * @param aClusterStarts Array of ints that will be populated
532     + * with information about which characters are the starts
533     + * of clusters.
534     + *
535     + */
536     + NS_IMETHOD GetClusterInfo(const PRUnichar *aText,
537     + PRUint32 aLength,
538     + PRUint32 *aClusterStarts) = 0;
539     +
540     + /**
541     + * Find the closest cursor position for a given x coordinate.
542     + *
543     + * This will find the closest byte index for a given x coordinate.
544     + * This takes into account grapheme clusters and bidi text.
545     + *
546     + * @param aText Text on which to operate.
547     + * @param aLength Length of the text.
548     + * @param aCoord The distance into the string to check.
549     + * @param aInx Index of character where the cursor falls - note that
550     + * this can be after the last character if the cursor happens to
551     + * the right of the last character in the text!
552     + *
553     + */
554     + NS_IMETHOD GetPosition(const PRUnichar *aText,
555     + PRUint32 aLength,
556     + nscoord aCoord,
557     + PRUint32 &aInx) = 0;
558     +
559     + /**
560     + * Get the width for the specific range of a given string.
561     + *
562     + * This function is similar to other GetWidth functions, except that
563     + * it gets the width for a part of the string instead of the entire
564     + * string. This is useful when you're interested in finding out the
565     + * length of a chunk in the middle of the string. Lots of languages
566     + * require you to include surrounding information to accurately
567     + * determine the length of a substring.
568     + *
569     + * @param aText Text on which to operate
570     + * @param aLength Length of the text
571     + * @param aStart Start index into the string
572     + * @param aEnd End index into the string (inclusive)
573     + * @param aWidth Returned with in app coordinates
574     + *
575     + */
576     + NS_IMETHOD GetRangeWidth(const PRUnichar *aText,
577     + PRUint32 aLength,
578     + PRUint32 aStart,
579     + PRUint32 aEnd,
580     + PRUint32 &aWidth) = 0;
581     +
582     };
583    
584     //modifiers for text rendering
585     @@ -866,6 +926,12 @@
586     */
587     #define NS_RENDERING_HINT_FAST_MEASURE 0x10
588    
589     +/**
590     + * This bit, when set, indicates that the gfx supports describing
591     + * cluster information in a string
592     + */
593     +#define NS_RENDERING_HINT_TEXT_CLUSTERS 0x20
594     +
595     //flags for copy CopyOffScreenBits
596    
597     //when performing the blit, use the region, if any,
598     --- mozilla/layout/html/base/src/nsTextFrame.cpp.foo 2004-10-08 09:39:27.000000000 -0400
599     +++ mozilla/layout/html/base/src/nsTextFrame.cpp 2004-12-16 13:14:23.000000000 -0500
600     @@ -2339,6 +2339,24 @@
601     #endif
602     sdptr = sdptr->mNext;
603     }
604     +
605     + /*
606     + * Text is drawn by drawing the entire string every time, but
607     + * using clip regions to control which part of the text is shown
608     + * (selected or unselected.) We do this because you can't
609     + * assume that the layout of a part of text will be the same
610     + * when it's drawn apart from the entire string. This is true
611     + * in languages like arabic, where shaping affects entire words.
612     + * Simply put: length("abcd") != length("ab") + length("cd") in
613     + * some languages.
614     + */
615     +
616     + // See if this rendering backend supports getting cluster
617     + // information.
618     + PRUint32 clusterHint = 0;
619     + aRenderingContext.GetHints(clusterHint);
620     + clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS;
621     +
622     //while we have substrings...
623     //PRBool drawn = PR_FALSE;
624     DrawSelectionIterator iter(content, details,text,(PRUint32)textLength,aTextStyle, selectionValue, aPresContext, mStyleContext);
625     @@ -2361,37 +2379,55 @@
626     nscolor currentBKColor;
627     PRBool isCurrentBKColorTransparent;
628    
629     -#ifdef IBMBIDI
630     - if (currentlength > 0
631     - && NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
632     + if (currentlength > 0)
633     {
634     -
635     - if (isRightToLeftOnBidiPlatform)
636     - currentX -= newWidth;
637     -#else // not IBMBIDI
638     - if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
639     - {
640     -#endif
641     - if (iter.CurrentBackGroundColor(currentBKColor, &isCurrentBKColorTransparent) && !isPaginated)
642     - {//DRAW RECT HERE!!!
643     - if (!isCurrentBKColorTransparent) {
644     - aRenderingContext.SetColor(currentBKColor);
645     - aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);
646     + if (clusterHint) {
647     + PRUint32 tmpWidth;
648     + rv = aRenderingContext.GetRangeWidth(text, textLength, currenttext - text,
649     + (currenttext - text) + currentlength,
650     + tmpWidth);
651     + newWidth = nscoord(tmpWidth);
652     + }
653     + else {
654     + rv = aRenderingContext.GetWidth(currenttext, currentlength,newWidth); //ADJUST FOR CHAR SPACING
655     + }
656     + if (NS_SUCCEEDED(rv)) {
657     + if (isRightToLeftOnBidiPlatform)
658     + currentX -= newWidth;
659     + if (iter.CurrentBackGroundColor(currentBKColor, &isCurrentBKColorTransparent) && !isPaginated)
660     + {//DRAW RECT HERE!!!
661     + if (!isCurrentBKColorTransparent) {
662     + aRenderingContext.SetColor(currentBKColor);
663     + aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);
664     + }
665     + currentFGColor = EnsureDifferentColors(currentFGColor, currentBKColor);
666     }
667     - currentFGColor = EnsureDifferentColors(currentFGColor, currentBKColor);
668     + }
669     + else {
670     + newWidth = 0;
671     }
672     }
673     - else
674     - newWidth =0;
675     -
676     + else {
677     + newWidth = 0;
678     + }
679     +
680     + aRenderingContext.PushState();
681     +
682     + nsRect rect(currentX, dy, newWidth, mRect.height);
683     + PRBool ignore;
684     + aRenderingContext.SetClipRect(rect, nsClipCombine_kIntersect,
685     + ignore);
686     +
687     if (isPaginated && !iter.IsBeforeOrAfter()) {
688     aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor));
689     - aRenderingContext.DrawString(currenttext, currentlength, currentX, dy + mAscent);
690     + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);
691     } else if (!isPaginated) {
692     aRenderingContext.SetColor(nsCSSRendering::TransformColor(currentFGColor,canDarkenColor));
693     - aRenderingContext.DrawString(currenttext, currentlength, currentX, dy + mAscent);
694     + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);
695     }
696    
697     + aRenderingContext.PopState(ignore);
698     +
699     #ifdef IBMBIDI
700     if (!isRightToLeftOnBidiPlatform)
701     #endif
702     @@ -3429,6 +3465,16 @@
703     PRInt32 textWidth = 0;
704     PRUnichar* text = paintBuffer.mBuffer;
705    
706     + // See if the font backend will do all the hard work for us.
707     + PRUint32 clusterHint = 0;
708     + acx->GetHints(clusterHint);
709     + clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS;
710     + if (clusterHint) {
711     + PRUint32 tmpIndx = indx;
712     + acx->GetPosition(text, textLength, aPoint.x - origin.x, tmpIndx);
713     + indx = tmpIndx;
714     + }
715     + else {
716     #ifdef IBMBIDI
717     PRBool getReversedPos = PR_FALSE;
718     PRUint8 level = 0;
719     @@ -3465,6 +3511,7 @@
720     indx++;
721     }
722     }
723     + }
724    
725     aContentOffset = indx + mContentOffset;
726     //reusing wordBufMem
727     @@ -3916,6 +3963,12 @@
728     }
729     PRInt32* ip = indexBuffer.mBuffer;
730    
731     + nsAutoIndexBuffer clusterBuffer;
732     + rv = clusterBuffer.GrowTo(mContentLength + 1);
733     + if (NS_FAILED(rv)) {
734     + return rv;
735     + }
736     +
737     PRInt32 textLength;
738     nsresult result(NS_ERROR_FAILURE);
739     aPos->mResultContent = mContent;//do this right off
740     @@ -3981,8 +4034,32 @@
741     aPos->mContentOffset = 0;
742     PRInt32 i;
743    
744     + // Fill in the cluster hint information, if it's available.
745     + nsCOMPtr<nsIRenderingContext> acx;
746     + PRUint32 clusterHint = 0;
747     +
748     + nsIPresShell *shell = aPresContext->GetPresShell();
749     + if (shell) {
750     + shell->CreateRenderingContext(this, getter_AddRefs(acx));
751     +
752     + // Find the font metrics for this text
753     + SetFontFromStyle(acx, mStyleContext);
754     +
755     + if (acx)
756     + acx->GetHints(clusterHint);
757     + clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS;
758     + }
759     +
760     + if (clusterHint) {
761     + acx->GetClusterInfo(paintBuffer.mBuffer, (PRUint32)textLength, (PRUint32 *)clusterBuffer.mBuffer);
762     + }
763     + else {
764     + memset(clusterBuffer.mBuffer, 1, sizeof(PRInt32) * textLength);
765     + }
766     +
767     for (i = aPos->mStartOffset -1 - mContentOffset; i >=0; i--){
768     if ((ip[i] < ip[aPos->mStartOffset - mContentOffset]) &&
769     + (clusterBuffer.mBuffer[ip[i] - mContentOffset]) &&
770     (! IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i]-mContentOffset])))
771     {
772     aPos->mContentOffset = i + mContentOffset;
773     @@ -4033,14 +4110,39 @@
774     PRInt32 i;
775     aPos->mContentOffset = mContentLength;
776    
777     - for (i = aPos->mStartOffset +1 - mContentOffset; i <= mContentLength; i++){
778     + // Fill in the cluster hint information, if it's available.
779     + nsCOMPtr<nsIRenderingContext> acx;
780     + PRUint32 clusterHint = 0;
781     +
782     + nsIPresShell *shell = aPresContext->GetPresShell();
783     + if (shell) {
784     + shell->CreateRenderingContext(this, getter_AddRefs(acx));
785     +
786     + // Find the font metrics for this text
787     + SetFontFromStyle(acx, mStyleContext);
788     +
789     + if (acx)
790     + acx->GetHints(clusterHint);
791     + clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS;
792     + }
793     +
794     + if (clusterHint) {
795     + acx->GetClusterInfo(paintBuffer.mBuffer, (PRUint32)textLength, (PRUint32 *)clusterBuffer.mBuffer);
796     + }
797     + else {
798     + memset(clusterBuffer.mBuffer, 1, sizeof(PRInt32) * textLength);
799     + }
800     +
801     + for (i = aPos->mStartOffset - mContentOffset; i <= mContentLength; i++) {
802     if ((ip[i] > ip[aPos->mStartOffset - mContentOffset]) &&
803     - (! IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i]-mContentOffset])))
804     - {
805     + ((i == mContentLength) ||
806     + (!IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i] - mContentOffset])) &&
807     + (clusterBuffer.mBuffer[ip[i] - mContentOffset]))) {
808     aPos->mContentOffset = i + mContentOffset;
809     break;
810     }
811     }
812     +
813     #ifdef SUNCTL
814     static NS_DEFINE_CID(kLECID, NS_ULE_CID);
815