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

David harrison at opensource.apple.com
Wed Jun 29 18:28:36 PDT 2005


harrison    05/06/29 18:28:36

  Modified:    .        ChangeLog
               WebCoreSupport.subproj WebTextRenderer.m
  Log:
          Reviewed by Dave Hyatt (rendering) and Maciej (editing).
  
          Test cases added:  Coming soon.  Will include with next round of changes for this bug.
  
          This is the first checkin for...
  
          <rdar://problem/3792529> REGRESSION (Mail): Tabs do not work the way they did in Panther (especially useful in plain text mail)
  
          Basic strategy is to put tabs into spans with white-space:pre style, and
          render them with tabs stops every 8th space, where the space width and
          the left margin are those of the enclosing block.
  
          What's left is to switch to implement white-space:pre-wrap so
          that we can coalesce consecutive tabs while maintaining proper
          line breaking.  That will keep the markup smaller.
  
          * WebCoreSupport.subproj/WebTextRenderer.m:
          (isSpace):
          (-[WebTextRenderer _CG_drawHighlightForRun:style:geometry:]):
          (-[WebTextRenderer _CG_floatWidthForRun:style:widths:fonts:glyphs:startPosition:numGlyphs:]):
          (-[WebTextRenderer _extendCharacterToGlyphMapToInclude:]):
          (-[WebTextRenderer _CG_pointToOffset:style:position:reversed:includePartialGlyphs:]):
          (initializeCharacterWidthIterator):
          (widthForNextCharacter):
  
  Revision  Changes    Path
  1.3208    +27 -0     WebKit/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebKit/ChangeLog,v
  retrieving revision 1.3207
  retrieving revision 1.3208
  diff -u -r1.3207 -r1.3208
  --- ChangeLog	29 Jun 2005 22:53:44 -0000	1.3207
  +++ ChangeLog	30 Jun 2005 01:28:32 -0000	1.3208
  @@ -1,3 +1,30 @@
  +2005-06-29  David Harrison  <harrison at apple.com>
  +
  +        Reviewed by Dave Hyatt (rendering) and Maciej (editing).
  +
  +        Test cases added:  Coming soon.  Will include with next round of changes for this bug.
  +
  +        This is the first checkin for...
  +        
  +        <rdar://problem/3792529> REGRESSION (Mail): Tabs do not work the way they did in Panther (especially useful in plain text mail)
  +        
  +        Basic strategy is to put tabs into spans with white-space:pre style, and
  +        render them with tabs stops every 8th space, where the space width and
  +        the left margin are those of the enclosing block.
  +        
  +        What's left is to switch to implement white-space:pre-wrap so
  +        that we can coalesce consecutive tabs while maintaining proper
  +        line breaking.  That will keep the markup smaller.
  +
  +        * WebCoreSupport.subproj/WebTextRenderer.m:
  +        (isSpace):
  +        (-[WebTextRenderer _CG_drawHighlightForRun:style:geometry:]):
  +        (-[WebTextRenderer _CG_floatWidthForRun:style:widths:fonts:glyphs:startPosition:numGlyphs:]):
  +        (-[WebTextRenderer _extendCharacterToGlyphMapToInclude:]):
  +        (-[WebTextRenderer _CG_pointToOffset:style:position:reversed:includePartialGlyphs:]):
  +        (initializeCharacterWidthIterator):
  +        (widthForNextCharacter):
  +
   2005-06-29  John Sullivan  <sullivan at apple.com>
   
           Reviewed by Kevin.
  
  
  
  1.176     +29 -21    WebKit/WebCoreSupport.subproj/WebTextRenderer.m
  
  Index: WebTextRenderer.m
  ===================================================================
  RCS file: /cvs/root/WebKit/WebCoreSupport.subproj/WebTextRenderer.m,v
  retrieving revision 1.175
  retrieving revision 1.176
  diff -u -r1.175 -r1.176
  --- WebTextRenderer.m	22 Jun 2005 16:44:08 -0000	1.175
  +++ WebTextRenderer.m	30 Jun 2005 01:28:36 -0000	1.176
  @@ -179,11 +179,11 @@
   
   static inline BOOL isSpace(UniChar c)
   {
  -    return c == SPACE || c == '\n' || c == NO_BREAK_SPACE;
  +    return c == SPACE || c == '\t' || c == '\n' || c == NO_BREAK_SPACE;
   }
   
   static const uint8_t isRoundingHackCharacterTable[0x100] = {
  -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*\n*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  +    0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*\t*/, 1 /*\n*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       1 /*space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*-*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*?*/,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  @@ -287,7 +287,7 @@
   
   // Iterator functions
   static void initializeCharacterWidthIterator (CharacterWidthIterator *iterator, WebTextRenderer *renderer, const WebCoreTextRun *run , const WebCoreTextStyle *style);
  -static float widthForNextCharacter (CharacterWidthIterator *iterator, ATSGlyphRef *glyphUsed, NSFont **fontUsed);
  +static float widthForNextCharacter (CharacterWidthIterator *iterator, float leadWidth, ATSGlyphRef *glyphUsed, NSFont **fontUsed);
   
   
   // Misc.
  @@ -1008,13 +1008,13 @@
       // The starting point needs to be adjusted to account for the width of
       // the glyphs at the start of the run.
       while (widthIterator.currentCharacter < (unsigned)run->from) {
  -        startPosition += widthForNextCharacter(&widthIterator, 0, 0);
  +        startPosition += widthForNextCharacter(&widthIterator, style->xpos + startPosition, 0, 0);
       }
       float startX = startPosition + geometry->point.x;
       
       float backgroundWidth = 0.0;
       while (widthIterator.currentCharacter < (unsigned)run->to) {
  -        backgroundWidth += widthForNextCharacter(&widthIterator, 0, 0);
  +        backgroundWidth += widthForNextCharacter(&widthIterator, style->xpos + startPosition + backgroundWidth, 0, 0);
       }
   
       if (style->backgroundColor != nil){
  @@ -1028,7 +1028,7 @@
           if (style->rtl){
               float completeRunWidth = startPosition + backgroundWidth;
               while (widthIterator.currentCharacter < run->length) {
  -                completeRunWidth += widthForNextCharacter(&widthIterator, 0, 0);
  +                completeRunWidth += widthForNextCharacter(&widthIterator, completeRunWidth, 0, 0);
               }
   
               [NSBezierPath fillRect:NSMakeRect(geometry->point.x + completeRunWidth - startPosition - backgroundWidth, yPos, backgroundWidth, height)];
  @@ -1203,7 +1203,7 @@
       initializeCharacterWidthIterator(&widthIterator, self, run, style);
       if (startPosition)
           *startPosition = widthIterator.widthToStart;
  -    while ((_nextWidth = widthForNextCharacter(&widthIterator, &glyphUsed, &fontUsed)) != INVALID_WIDTH){
  +    while ((_nextWidth = widthForNextCharacter(&widthIterator, _totalWidth+style->xpos, &glyphUsed, &fontUsed)) != INVALID_WIDTH){
           if (fontBuffer)
               fontBuffer[numGlyphs] = fontUsed;
           if (glyphBuffer)
  @@ -1339,8 +1339,9 @@
               buffer[i] = ZERO_WIDTH_SPACE;
           buffer[0x7F] = ZERO_WIDTH_SPACE;
   
  -        // But both \n and nonbreaking space must render as a space.
  +        // But \n, \t, and nonbreaking space must render as a space.
           buffer['\n'] = ' ';
  +        buffer['\t'] = ' ';
           buffer[NO_BREAK_SPACE] = ' ';
       }
   
  @@ -1756,7 +1757,8 @@
   - (int)_CG_pointToOffset:(const WebCoreTextRun *)run style:(const WebCoreTextStyle *)style position:(int)x reversed:(BOOL)reversed includePartialGlyphs:(BOOL)includePartialGlyphs
   {
       float delta = (float)x;
  -    float width;
  +    float width;   ///  FIX: CHECK THIS
  +    float leadWidth = style->xpos;
       unsigned offset = run->from;
       CharacterWidthIterator widthIterator;
       
  @@ -1766,7 +1768,8 @@
           width = [self floatWidthForRun:run style:style widths:nil];
           delta -= width;
           while (offset < run->length) {
  -            float w = widthForNextCharacter(&widthIterator, 0, 0);
  +            float w = widthForNextCharacter(&widthIterator, leadWidth, 0, 0);
  +            leadWidth += w;
               if (w == INVALID_WIDTH) {
                   // Something very bad happened, like we only have half of a surrogate pair.
                   break;
  @@ -1786,7 +1789,8 @@
           }
       } else {
           while (offset < run->length) {
  -            float w = widthForNextCharacter(&widthIterator, 0, 0);
  +            float w = widthForNextCharacter(&widthIterator, leadWidth, 0, 0);
  +            leadWidth += w;
               if (w == INVALID_WIDTH) {
                   // Something very bad happened, like we only have half of a surrogate pair.
                   break;
  @@ -1942,7 +1946,7 @@
           initializeCharacterWidthIterator (&startPositionIterator, renderer, &startPositionRun, style);
           
           while (startPositionIterator.currentCharacter < (unsigned)startPositionRun.to){
  -            widthForNextCharacter(&startPositionIterator, 0, 0);
  +            widthForNextCharacter(&startPositionIterator, startPositionIterator.runWidthSoFar+style->xpos, 0, 0);
           }
           iterator->widthToStart = startPositionIterator.runWidthSoFar;
       }
  @@ -1961,7 +1965,7 @@
   #define HIRAGANA_KATAKANA_VOICING_MARKS 8
   
   // Return INVALID_WIDTH if an error is encountered or we're at the end of the range in the run.
  -static float widthForNextCharacter(CharacterWidthIterator *iterator, ATSGlyphRef *glyphUsed, NSFont **fontUsed)
  +static float widthForNextCharacter(CharacterWidthIterator *iterator, float leadWidth, ATSGlyphRef *glyphUsed, NSFont **fontUsed)
   {
       WebTextRenderer *renderer = iterator->renderer;
       const WebCoreTextRun *run = iterator->run;
  @@ -2069,15 +2073,19 @@
       }
   
       // Now that we have glyph and font, get its width.
  -    WebGlyphWidth width = widthForGlyph(renderer, *glyphUsed, *fontUsed);
  +    WebGlyphWidth width;
  +    if (c == '\t' && style->tabWidth != 0) {
  +        width = style->tabWidth - (CEIL_TO_INT(leadWidth) % style->tabWidth);
  +    } else {
  +        width = widthForGlyph(renderer, *glyphUsed, *fontUsed);
  +        // We special case spaces in two ways when applying word rounding.
  +        // First, we round spaces to an adjusted width in all fonts.
  +        // Second, in fixed-pitch fonts we ensure that all characters that
  +        // match the width of the space character have the same width as the space character.
  +        if ((renderer->treatAsFixedPitch ? width == renderer->spaceWidth : *glyphUsed == renderer->spaceGlyph) && iterator->style->applyWordRounding)
  +            width = renderer->adjustedSpaceWidth;
  +    }
       
  -    // We special case spaces in two ways when applying word rounding.
  -    // First, we round spaces to an adjusted width in all fonts.
  -    // Second, in fixed-pitch fonts we ensure that all characters that
  -    // match the width of the space character have the same width as the space character.
  -    if ((renderer->treatAsFixedPitch ? width == renderer->spaceWidth : *glyphUsed == renderer->spaceGlyph) && iterator->style->applyWordRounding)
  -        width = renderer->adjustedSpaceWidth;
  -
       // Try to find a substitute font if this font didn't have a glyph for a character in the
       // string.  If one isn't found we end up drawing and measuring the 0 glyph, usually a box.
       if (*glyphUsed == 0 && iterator->style->attemptFontSubstitution) {
  
  
  



More information about the webkit-changes mailing list