[webkit-changes] cvs commit: WebKit/WebCoreSupport.subproj WebTextRenderer.m

Alexey ap at opensource.apple.com
Fri Dec 30 14:17:09 PST 2005


ap          05/12/30 14:17:09

  Modified:    .        ChangeLog
               .        ChangeLog
               khtml/rendering font.cpp font.h render_text.cpp
               kwq      KWQFontMetrics.h KWQFontMetrics.mm
                        WebCoreTextRenderer.h
               .        ChangeLog
               WebCoreSupport.subproj WebTextRenderer.m
  Added:       fast/text justified-text-rect-expected.checksum
                        justified-text-rect-expected.png
                        justified-text-rect-expected.txt
                        justified-text-rect.html
  Log:
          Reviewed by Darin, landed by ap.
  
          - fix for http://bugzilla.opendarwin.org/show_bug.cgi?id=5461
            Text width measured incorrectly when text-align: justify
  
  WebCore:
          * khtml/rendering/font.h:
          * khtml/rendering/font.cpp:
          (khtml::Font::selectionRectForText): Added.
          * khtml/rendering/render_text.cpp:
          (kthml::InlineTextBox::selectionRect): Use selectionRectForText. This
          works for justified text as well, and avoids intermediate rounding which
          resulted in selection rects narrower than AppKit's.
          (khtml::InlineTextBox::positionForOffset): Use selectionRectForText,
          which works for justified text as well.
          * kwq/KWQFontMetrics.h:
          * kwq/KWQFontMetrics.mm:
          (QFontMetrics::selectionRectForText): Added.
          * kwq/WebCoreTextRenderer.h:
  
  WebKit:
          * WebCoreSupport.subproj/WebTextRenderer.m:
          (-[WebTextRenderer selectionRectForRun:style:geometry:]): Added.
          (CG_drawHighlight): Use new function CG_selectionRect.
          (CG_selectionRect): New function to compute the selection rect.
          Eliminated rounding hackery that was required for keeping the highlight
          rect within the selection rect computed by
          InlineTextBox::selectionRect, since the latter uses this function now.
          The new selection rect is wider and matches AppKit more closely,
          although the right hand side is roundf()ed instead of cielf()ed for
          optimal caret positioning.
          (ATSU_drawHighlight): Use new function ATSU_selectionRect.
          (ATSU_selectionRect): New function to compute the selection rect.
          Much like CG_selectionRect.
  LayoutTests:
          * fast/text/justified-text-rect-expected.checksum: Added.
          * fast/text/justified-text-rect-expected.png: Added.
          * fast/text/justified-text-rect-expected.txt: Added.
          * fast/text/justified-text-rect.html: Added.
  
  Revision  Changes    Path
  1.210     +12 -0     LayoutTests/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/LayoutTests/ChangeLog,v
  retrieving revision 1.209
  retrieving revision 1.210
  diff -u -r1.209 -r1.210
  --- ChangeLog	30 Dec 2005 21:16:18 -0000	1.209
  +++ ChangeLog	30 Dec 2005 22:17:03 -0000	1.210
  @@ -1,3 +1,15 @@
  +2005-12-30  Alexey Proskuryakov  <ap at nypop.com>
  +
  +        Reviewed by Darin.
  +        
  +        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=5461
  +          Text width measured incorrectly when text-align: justify
  +        
  +        * fast/text/justified-text-rect-expected.checksum: Added.
  +        * fast/text/justified-text-rect-expected.png: Added.
  +        * fast/text/justified-text-rect-expected.txt: Added.
  +        * fast/text/justified-text-rect.html: Added.
  +
   2005-12-30  Eric Seidel  <eseidel at apple.com>
   
           Reviewed by ggaren.
  
  
  
  1.1                  LayoutTests/fast/text/justified-text-rect-expected.checksum
  
  Index: justified-text-rect-expected.checksum
  ===================================================================
  f711e51f2e376d82b547ae37e94e263b
  \ No newline at end of file
  
  
  
  1.1                  LayoutTests/fast/text/justified-text-rect-expected.png
  
  	<<Binary file>>
  
  
  1.1                  LayoutTests/fast/text/justified-text-rect-expected.txt
  
  Index: justified-text-rect-expected.txt
  ===================================================================
  EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
  layer at (0,0) size 800x600
    RenderCanvas at (0,0) size 800x600
  layer at (0,0) size 800x600
    RenderBlock {HTML} at (0,0) size 800x600
      RenderBody {BODY} at (0,0) size 800x584
        RenderBlock {P} at (0,0) size 70x50 [bgcolor=#008000]
          RenderText {TEXT} at (0,0) size 70x36
            text run at (0,0) width 70: "a         a"
            text run at (0,18) width 39: "        a"
        RenderBlock (anonymous) at (0,66) size 800x18
          RenderText {TEXT} at (0,0) size 76x18
            text run at (0,0) width 76: "63,582,6,18"
        RenderBlock {P} at (0,100) size 800x18
          RenderText {TEXT} at (0,0) size 54x18
            text run at (0,0) width 54: "Success."
  caret: position 0 of child 0 {TEXT} of child 1 {P} of child 1 {BODY} of child 0 {HTML} of document
  
  
  
  1.1                  LayoutTests/fast/text/justified-text-rect.html
  
  Index: justified-text-rect.html
  ===================================================================
  <html>
  <head>
  <style>
  body { margin: 0; padding: 0 }
  </style>
  </head>
  <body>
  <p contenteditable id='test' STYLE="width: 70px; height: 50px; background-color: green; text-align: justify;">a         a         a</p>
  <script type="text/javascript">
  
      if (window.layoutTestController) {
          
          try {
          
              window.getSelection().setPosition(document.getElementById("test"), 0);
  			
  			rect = textInputController.firstRectForCharacterRange(10, 1);
              document.write(rect);
          
              // the second character 'a' should be at the right border of the box
              if (rect[0] > 60)
              	document.write("<p>Success.</p>");
              else
              	document.write("<p>Failure (rect: " + rect + ")</p>");
  
  		} catch (ex) {
  			document.write("Exception: " + ex.description);
  		}
  	} else {
  		document.write("(cannot run interactively)");
  	}
  </script>
  </body>
  </html>
  
  
  
  1.70      +24 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -r1.69 -r1.70
  --- ChangeLog	30 Dec 2005 21:23:32 -0000	1.69
  +++ ChangeLog	30 Dec 2005 22:17:04 -0000	1.70
  @@ -1,3 +1,27 @@
  +2005-12-30  Mitz Pettel  <opendarwin.org at mitzpettel.com>
  +
  +        Reviewed by Darin, landed by ap.
  +        
  +        Test: fast/text/justified-text-rect.html
  +        
  +        - WebCore part of fix for
  +          http://bugzilla.opendarwin.org/show_bug.cgi?id=5461
  +          Text width measured incorrectly when text-align: justify
  +
  +        * khtml/rendering/font.h:
  +        * khtml/rendering/font.cpp:
  +        (khtml::Font::selectionRectForText): Added.
  +        * khtml/rendering/render_text.cpp:
  +        (kthml::InlineTextBox::selectionRect): Use selectionRectForText. This
  +        works for justified text as well, and avoids intermediate rounding which
  +        resulted in selection rects narrower than AppKit's.
  +        (khtml::InlineTextBox::positionForOffset): Use selectionRectForText,
  +        which works for justified text as well.
  +        * kwq/KWQFontMetrics.h:
  +        * kwq/KWQFontMetrics.mm:
  +        (QFontMetrics::selectionRectForText): Added.
  +        * kwq/WebCoreTextRenderer.h:
  +
   2005-12-30  Alexey Proskuryakov  <ap at nypop.com>
   
           - Fix http://bugzilla.opendarwin.org/show_bug.cgi?id=6289
  
  
  
  1.47      +8 -0      WebCore/khtml/rendering/font.cpp
  
  Index: font.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/font.cpp,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- font.cpp	20 Oct 2005 06:02:24 -0000	1.46
  +++ font.cpp	30 Dec 2005 22:17:05 -0000	1.47
  @@ -33,6 +33,14 @@
   
   namespace khtml {
   
  +QRect Font::selectionRectForText(int x, int y, int h, int tabWidth, int xpos, 
  +                      QChar *str, int slen, int pos, int len, int toAdd,
  +                      bool rtl, bool visuallyOrdered, int from, int to) const
  +{
  +    return fm.selectionRectForText(x, y, h, tabWidth, xpos, str + pos, std::min(slen - pos, len), from, to, toAdd, rtl, visuallyOrdered, letterSpacing, wordSpacing, fontDef.smallCaps);
  +
  +}
  +
   void Font::drawHighlightForText( QPainter *p, int x, int y, int h, int tabWidth, int xpos, 
                        QChar *str, int slen, int pos, int len,
                        int toAdd, QPainter::TextDirection d, bool visuallyOrdered, int from, int to, QColor bg) const
  
  
  
  1.38      +5 -1      WebCore/khtml/rendering/font.h
  
  Index: font.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/font.h,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- font.h	29 Dec 2005 11:27:07 -0000	1.37
  +++ font.h	30 Dec 2005 22:17:05 -0000	1.38
  @@ -103,7 +103,11 @@
                     QPainter::TextDirection d, bool visuallyOrdered = false, int from = -1, int to = -1, QColor bg = QColor()) const;
       float floatWidth(QChar *str, int slen, int pos, int len, int tabWidth, int xpos) const;
       bool isFixedPitch() const;
  -    int checkSelectionPoint(QChar *s, int slen, int pos, int len, int toAdd, int tabWidth, int xpos, int x, QPainter::TextDirection d, bool visuallyOrdered, bool includePartialGlyphs) const;
  +    int checkSelectionPoint(QChar *s, int slen, int pos, int len, int toAdd, int tabWidth, int xpos,
  +        int x, QPainter::TextDirection d, bool visuallyOrdered, bool includePartialGlyphs) const;
  +    QRect selectionRectForText(int x, int y, int h, int tabWidth, int xpos, 
  +        QChar *str, int slen, int pos, int len, int width,
  +        bool rtl, bool visuallyOrdered = false, int from = -1, int to = -1) const;
       void drawHighlightForText(QPainter *p, int x, int y, int h, int tabWidth, int xpos, 
           QChar *str, int slen, int pos, int len, int width,
           QPainter::TextDirection d, bool visuallyOrdered = false, int from = -1, int to = -1, QColor bg = QColor()) const;
  
  
  
  1.217     +6 -48     WebCore/khtml/rendering/render_text.cpp
  
  Index: render_text.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_text.cpp,v
  retrieving revision 1.216
  retrieving revision 1.217
  diff -u -r1.216 -r1.217
  --- render_text.cpp	28 Dec 2005 18:18:34 -0000	1.216
  +++ render_text.cpp	30 Dec 2005 22:17:05 -0000	1.217
  @@ -123,44 +123,11 @@
   
       RootInlineBox* rootBox = root();
       RenderText* textObj = textObject();
  -    int selStart = m_reversed ? m_x + m_width : m_x;
  -    int selEnd = selStart;
       int selTop = rootBox->selectionTop();
       int selHeight = rootBox->selectionHeight();
  -    int leadWidth = 0;
  +    const Font *f = textObj->htmlFont(m_firstLine);
   
  -    // FIXME: For justified text, just return the entire text box's rect.  At the moment there's still no easy
  -    // way to get the width of a run including the justification padding.
  -    if (sPos > 0 && !m_toAdd) {
  -        // The selection begins in the middle of our run.
  -        leadWidth = textObj->width(m_start, sPos, textPos(), m_firstLine);
  -        if (m_reversed)
  -            selStart -= leadWidth;
  -        else
  -            selStart += leadWidth;
  -    }
  -
  -    if (m_toAdd || (sPos == 0 && ePos == m_len)) {
  -        if (m_reversed)
  -            selEnd = m_x;
  -        else
  -            selEnd = m_x + m_width;
  -    }
  -    else {
  -        // Our run is partially selected, and so we need to measure.
  -        int w = textObj->width(sPos + m_start, ePos - sPos, textPos() + leadWidth, m_firstLine);
  -        if (sPos + m_start > 0 && textObj->str->s[sPos + m_start].isSpace() && !textObj->str->s[sPos + m_start - 1].isSpace())
  -            w += textObj->style(m_firstLine)->wordSpacing();
  -        if (m_reversed)
  -            selEnd = selStart - w;
  -        else
  -            selEnd = selStart + w;
  -    }
  -    
  -    int selLeft = m_reversed ? selEnd : selStart;
  -    int selRight = m_reversed ? selStart : selEnd;
  -
  -    return QRect(selLeft + tx, selTop + ty, selRight - selLeft, selHeight);
  +    return f->selectionRectForText(tx + m_x, ty + selTop, selHeight, textObj->tabWidth(), textPos(), textObj->str->s, textObj->str->l, m_start, m_len, m_toAdd, m_reversed, m_dirOverride, sPos, ePos);
   }
   
   void InlineTextBox::deleteLine(RenderArena* arena)
  @@ -741,20 +708,11 @@
   int InlineTextBox::positionForOffset(int offset) const
   {
       RenderText *text = static_cast<RenderText *>(m_object);
  -    const QFontMetrics &fm = text->metrics(m_firstLine);
  -
  -    int left;
  -    if (m_reversed) {
  -	int len = m_start + m_len - offset;
  -	QString string(text->str->s + offset, len);
  -	left = m_x + fm.boundingRect(string, text->tabWidth(), textPos(), len).right();
  -    } else {
  -	int len = offset - m_start;
  -	QString string(text->str->s + m_start, len);
  -	left = m_x + fm.boundingRect(string, text->tabWidth(), textPos(), len).right();
  -    }
  +    const Font *f = text->htmlFont(m_firstLine);
  +    int from = m_reversed ? offset - m_start : 0;
  +    int to = m_reversed ? m_len : offset - m_start;
       // FIXME: Do we need to add rightBearing here?
  -    return left;
  +    return f->selectionRectForText(m_x, 0, 0, text->tabWidth(), textPos(), text->str->s, text->str->l, m_start, m_len, m_toAdd, m_reversed, m_dirOverride, from, to).right();
   }
   
   // -------------------------------------------------------------------------------------
  
  
  
  1.45      +4 -0      WebCore/kwq/KWQFontMetrics.h
  
  Index: KWQFontMetrics.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQFontMetrics.h,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -r1.44 -r1.45
  --- KWQFontMetrics.h	17 Dec 2005 18:10:25 -0000	1.44
  +++ KWQFontMetrics.h	30 Dec 2005 22:17:05 -0000	1.45
  @@ -54,6 +54,10 @@
       int width(const QString &, int tabWidth, int xpos, int len=-1) const;
       int width(const QChar *, int len, int tabWidth, int xpos) const;
       float floatWidth(const QChar *, int slen, int pos, int len, int tabWidth, int xpos, int letterSpacing, int wordSpacing, bool smallCaps) const;
  +    QRect selectionRectForText(int x, int y, int h, int tabWidth, int xpos,
  +                            const QChar *str, int len, int from, int to, int toAdd,
  +                            bool rtl, bool visuallyOrdered, int letterSpacing,
  +                            int wordSpacing, bool smallCaps) const;
       int checkSelectionPoint(QChar *s, int slen, int pos, int len, int toAdd, int tabWidth, int xpos, int letterSpacing, int wordSpacing, bool smallCaps, int x, bool reversed, bool dirOverride, bool includePartialGlyphs) const;
   
       QRect boundingRect(QChar) const;
  
  
  
  1.95      +33 -0     WebCore/kwq/KWQFontMetrics.mm
  
  Index: KWQFontMetrics.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQFontMetrics.mm,v
  retrieving revision 1.94
  retrieving revision 1.95
  diff -u -r1.94 -r1.95
  --- KWQFontMetrics.mm	17 Dec 2005 18:10:25 -0000	1.94
  +++ KWQFontMetrics.mm	30 Dec 2005 22:17:05 -0000	1.95
  @@ -224,6 +224,39 @@
       return [data->getRenderer() floatWidthForRun:&run style:&style];
   }
   
  +QRect QFontMetrics::selectionRectForText(int x, int y, int h, int tabWidth, int xpos,
  +    const QChar *str, int len, int from, int to, int toAdd,
  +    bool rtl, bool visuallyOrdered, int letterSpacing, int wordSpacing, bool smallCaps) const
  +{
  +    CREATE_FAMILY_ARRAY(data->font(), families);
  +
  +    if (from < 0)
  +        from = 0;
  +    if (to < 0)
  +        to = len;
  +        
  +    WebCoreTextRun run;
  +    WebCoreInitializeTextRun(&run, (const UniChar *)str, len, from, to);    
  +    WebCoreTextStyle style;
  +    WebCoreInitializeEmptyTextStyle(&style);
  +    style.rtl = rtl;
  +    style.directionalOverride = visuallyOrdered;
  +    style.letterSpacing = letterSpacing;
  +    style.wordSpacing = wordSpacing;
  +    style.smallCaps = smallCaps;
  +    style.families = families;    
  +    style.padding = toAdd;
  +    style.tabWidth = tabWidth;
  +    style.xpos = xpos;
  +    WebCoreTextGeometry geometry;
  +    WebCoreInitializeEmptyTextGeometry(&geometry);
  +    geometry.point = NSMakePoint(x, y);
  +    geometry.selectionY = y;
  +    geometry.selectionHeight = h;
  +    geometry.useFontMetricsForSelectionYAndHeight = false;
  +    return QRect([data->getRenderer() selectionRectForRun:&run style:&style geometry:&geometry]);
  +}
  +
   int QFontMetrics::checkSelectionPoint(QChar *s, int slen, int pos, int len, int toAdd, int tabWidth, int xpos, int letterSpacing, int wordSpacing, bool smallCaps, int x, bool reversed, bool dirOverride, bool includePartialGlyphs) const
   {
       if (!data) {
  
  
  
  1.39      +1 -0      WebCore/kwq/WebCoreTextRenderer.h
  
  Index: WebCoreTextRenderer.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/WebCoreTextRenderer.h,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- WebCoreTextRenderer.h	17 Dec 2005 18:10:25 -0000	1.38
  +++ WebCoreTextRenderer.h	30 Dec 2005 22:17:05 -0000	1.39
  @@ -94,6 +94,7 @@
   
   // drawing
   - (void)drawRun:(const WebCoreTextRun *)run style:(const WebCoreTextStyle *)style geometry:(const WebCoreTextGeometry *)geometry;
  +- (NSRect)selectionRectForRun:(const WebCoreTextRun *)run style:(const WebCoreTextStyle *)style geometry:(const WebCoreTextGeometry *)geometry;
   - (void)drawHighlightForRun:(const WebCoreTextRun *)run style:(const WebCoreTextStyle *)style geometry:(const WebCoreTextGeometry *)geometry;
   - (void)drawLineForCharacters:(NSPoint)point yOffset:(float)yOffset width: (int)width color:(NSColor *)color thickness:(float)thickness;
   - (void)drawLineForMisspelling:(NSPoint)point withWidth:(int)width;
  
  
  
  1.3437    +24 -0     WebKit/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebKit/ChangeLog,v
  retrieving revision 1.3436
  retrieving revision 1.3437
  diff -u -r1.3436 -r1.3437
  --- ChangeLog	30 Dec 2005 20:42:12 -0000	1.3436
  +++ ChangeLog	30 Dec 2005 22:17:06 -0000	1.3437
  @@ -1,3 +1,27 @@
  +2005-12-30  Mitz Pettel  <opendarwin.org at mitzpettel.com>
  +
  +        Reviewed by Darin, landed by ap.
  +        
  +        Test: fast/text/justified-text-rect.html
  +        
  +        - WebKit part of fix for
  +          http://bugzilla.opendarwin.org/show_bug.cgi?id=5461
  +          Text width measured incorrectly when text-align: justify
  +
  +        * WebCoreSupport.subproj/WebTextRenderer.m:
  +        (-[WebTextRenderer selectionRectForRun:style:geometry:]): Added.
  +        (CG_drawHighlight): Use new function CG_selectionRect.
  +        (CG_selectionRect): New function to compute the selection rect.
  +        Eliminated rounding hackery that was required for keeping the highlight
  +        rect within the selection rect computed by
  +        InlineTextBox::selectionRect, since the latter uses this function now.
  +        The new selection rect is wider and matches AppKit more closely,
  +        although the right hand side is roundf()ed instead of cielf()ed for
  +        optimal caret positioning.
  +        (ATSU_drawHighlight): Use new function ATSU_selectionRect.
  +        (ATSU_selectionRect): New function to compute the selection rect.
  +        Much like CG_selectionRect.
  +
   2005-12-29  Geoffrey Garen  <ggaren at apple.com>
   
           Reviewed by Eric.
  
  
  
  1.213     +52 -32    WebKit/WebCoreSupport.subproj/WebTextRenderer.m
  
  Index: WebTextRenderer.m
  ===================================================================
  RCS file: /cvs/root/WebKit/WebCoreSupport.subproj/WebTextRenderer.m,v
  retrieving revision 1.212
  retrieving revision 1.213
  diff -u -r1.212 -r1.213
  --- WebTextRenderer.m	30 Dec 2005 07:05:54 -0000	1.212
  +++ WebTextRenderer.m	30 Dec 2005 22:17:09 -0000	1.213
  @@ -144,6 +144,10 @@
   static int ATSU_pointToOffset(WebTextRenderer *, const WebCoreTextRun *, const WebCoreTextStyle *,
       int x, bool includePartialGlyphs);
   
  +// Selection rect.
  +static NSRect CG_selectionRect(WebTextRenderer *, const WebCoreTextRun *, const WebCoreTextStyle *, const WebCoreTextGeometry *);
  +static NSRect ATSU_selectionRect(WebTextRenderer *, const WebCoreTextRun *, const WebCoreTextStyle *, const WebCoreTextGeometry *);
  +
   // Drawing highlight.
   static void CG_drawHighlight(WebTextRenderer *, const WebCoreTextRun *, const WebCoreTextStyle *, const WebCoreTextGeometry *);
   static void ATSU_drawHighlight(WebTextRenderer *, const WebCoreTextRun *, const WebCoreTextStyle *, const WebCoreTextGeometry *);
  @@ -556,6 +560,14 @@
       [graphicsContext setShouldAntialias: flag];
   }
   
  +- (NSRect)selectionRectForRun:(const WebCoreTextRun *)run style:(const WebCoreTextStyle *)style geometry:(const WebCoreTextGeometry *)geometry
  +{
  +    if (shouldUseATSU(run))
  +        return ATSU_selectionRect(self, run, style, geometry);
  +    else
  +        return CG_selectionRect(self, run, style, geometry);
  +}
  +
   - (void)drawHighlightForRun:(const WebCoreTextRun *)run style:(const WebCoreTextStyle *)style geometry:(const WebCoreTextGeometry *)geometry
   {
       if (shouldUseATSU(run))
  @@ -871,7 +883,11 @@
           return;
   
       [style->backgroundColor set];
  +    [NSBezierPath fillRect:CG_selectionRect(renderer, run, style, geometry)];
  +}
   
  +static NSRect CG_selectionRect(WebTextRenderer *renderer, const WebCoreTextRun * run, const WebCoreTextStyle *style, const WebCoreTextGeometry *geometry)
  +{
       float yPos = geometry->useFontMetricsForSelectionYAndHeight
           ? geometry->point.y - renderer->ascent - (renderer->lineGap / 2) : geometry->selectionY;
       float height = geometry->useFontMetricsForSelectionYAndHeight
  @@ -886,20 +902,15 @@
       
       advanceWidthIterator(&it, run->from, 0, 0, 0);
       float beforeWidth = it.runWidthSoFar;
  -    // apply rounding as if this is the end of the run, since that's how RenderText::selectionRect() works
  -    if ((style->applyWordRounding && isRoundingHackCharacter(run->characters[run->from]))
  -            || style->applyRunRounding)
  -        beforeWidth = ceilf(beforeWidth);
       advanceWidthIterator(&it, run->to, 0, 0, 0);
  -    float backgroundWidth = it.runWidthSoFar - beforeWidth;
  +    float afterWidth = it.runWidthSoFar;
  +    // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning
       if (style->rtl) {
           advanceWidthIterator(&it, run->length, 0, 0, 0);
           float totalWidth = it.runWidthSoFar;
  -        if (style->applyRunRounding)
  -            totalWidth = ceilf(totalWidth);
  -        [NSBezierPath fillRect:NSMakeRect(geometry->point.x + roundf(totalWidth - backgroundWidth - beforeWidth), yPos, roundf(backgroundWidth), height)];
  +        return NSMakeRect(geometry->point.x + floorf(totalWidth - afterWidth), yPos, roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), height);
       } else {
  -        [NSBezierPath fillRect:NSMakeRect(geometry->point.x + roundf(beforeWidth), yPos, roundf(backgroundWidth), height)];
  +        return NSMakeRect(geometry->point.x + floorf(beforeWidth), yPos, roundf(afterWidth) - floorf(beforeWidth), height);
       }
   }
   
  @@ -1457,53 +1468,62 @@
   
       if (style->backgroundColor == nil)
           return;
  +    if (run->to <= run->from)
  +        return;
       
  +    [style->backgroundColor set];
  +    [NSBezierPath fillRect:ATSU_selectionRect(renderer, run, style, geometry)];
  +}
  +
  +static NSRect ATSU_selectionRect(WebTextRenderer *renderer, const WebCoreTextRun *run, const WebCoreTextStyle *style, const WebCoreTextGeometry *geometry)
  +{
       int from = run->from;
       int to = run->to;
       if (from == -1)
           from = 0;
       if (to == -1)
           to = run->length;
  -    int runLength = to - from;
  -    if (runLength <= 0)
  -        return;
  -
  -    WebCoreTextRun runWithLead = *run;
  -    runWithLead.from = 0;
  -    WebCoreTextRun *aRun = &runWithLead;
  +        
  +    WebCoreTextRun completeRun = *run;
  +    completeRun.from = 0;
  +    completeRun.to = run->length;
  +    
  +    WebCoreTextRun *aRun = &completeRun;
       WebCoreTextRun swappedRun;
  -
  +    
       if (style->directionalOverride) {
           swappedRun = addDirectionalOverride(aRun, style->rtl);
           aRun = &swappedRun;
  +        from++;
  +        to++;
       }
      
  -    float selectedLeftX;
  -    float widthWithLead = ATSU_floatWidthForRun(renderer, aRun, style);
  +    ATSULayoutParameters params;
  +    createATSULayoutParameters(&params, renderer, aRun, style);
       
  -    aRun->to -= runLength;
  -    float leadWidth = ATSU_floatWidthForRun(renderer, aRun, style);
  +    ATSTrapezoid firstGlyphBounds;
  +    ItemCount actualNumBounds;
       
  -    float backgroundWidth = roundf(widthWithLead - leadWidth);
  -
  -    if (!style->rtl)
  -        selectedLeftX = roundf(geometry->point.x + leadWidth);
  -    else {
  -        aRun->to += run->length - run->from;
  -        float totalWidth = ATSU_floatWidthForRun(renderer, aRun, style);
  -        selectedLeftX = roundf(geometry->point.x + totalWidth - widthWithLead);
  +    OSStatus status = ATSUGetGlyphBounds(params.layout, 0, 0, from, to - from, kATSUseFractionalOrigins, 1, &firstGlyphBounds, &actualNumBounds);
  +    if (status != noErr || actualNumBounds != 1) {
  +        static ATSTrapezoid zeroTrapezoid = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
  +        firstGlyphBounds = zeroTrapezoid;
       }
  +    disposeATSULayoutParameters(&params);    
       
  -    [style->backgroundColor set];
  -
  +    float beforeWidth = MIN(FixedToFloat(firstGlyphBounds.lowerLeft.x), FixedToFloat(firstGlyphBounds.upperLeft.x));
  +    float afterWidth = MAX(FixedToFloat(firstGlyphBounds.lowerRight.x), FixedToFloat(firstGlyphBounds.upperRight.x));
       float yPos = geometry->useFontMetricsForSelectionYAndHeight
           ? geometry->point.y - renderer->ascent : geometry->selectionY;
       float height = geometry->useFontMetricsForSelectionYAndHeight
           ? renderer->lineSpacing : geometry->selectionHeight;
  -    [NSBezierPath fillRect:NSMakeRect(selectedLeftX, yPos, backgroundWidth, height)];
  +
  +    NSRect rect = NSMakeRect(geometry->point.x + floorf(beforeWidth), yPos, roundf(afterWidth) - floorf(beforeWidth), height);
   
       if (style->directionalOverride)
           free((void *)swappedRun.characters);
  +
  +    return rect;
   }
   
   
  
  
  



More information about the webkit-changes mailing list