Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 --- 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