Changeset 24977 in webkit


Ignore:
Timestamp:
Aug 10, 2007 12:50:06 AM (17 years ago)
Author:
bdash
Message:

2007-08-10 Mitz Pettel <mitz@webkit.org>

Reviewed by Dave Hyatt.

Test: fast/text/international/bidi-neutral-run.html

Fixed several bugs in resolving the embedding level of runs of neutral
characters. Changed the logic to rely on the eor direction only for
the number types, and otherwise consider the last strong type.

  • platform/BidiContext.h: (WebCore::BidiContext::BidiContext): Added an ASSERT.
  • platform/BidiResolver.h: (WebCore::::embed): (WebCore::::createBidiRunsForLine):
  • platform/graphics/GraphicsContext.cpp: (WebCore::TextRunIterator::atEnd): Changed to return true instead of crashing when called on the empty iterator.

2007-08-10 Mitz Pettel <mitz@webkit.org>

Reviewed by Dave Hyatt.

  • fast/text/international/bidi-neutral-run-expected.checksum: Added.
  • fast/text/international/bidi-neutral-run-expected.png: Added.
  • fast/text/international/bidi-neutral-run-expected.txt: Added.
  • fast/text/international/bidi-neutral-run.html: Added.
Location:
trunk
Files:
4 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r24975 r24977  
     12007-08-10  Mitz Pettel  <mitz@webkit.org>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        - test for http://bugs.webkit.org/show_bug.cgi?id=14798
     6          Incorrect bidi reordering of neutrals and digits after RTL embed
     7          and other bugs in the bidi algorithm.
     8
     9        * fast/text/international/bidi-neutral-run-expected.checksum: Added.
     10        * fast/text/international/bidi-neutral-run-expected.png: Added.
     11        * fast/text/international/bidi-neutral-run-expected.txt: Added.
     12        * fast/text/international/bidi-neutral-run.html: Added.
     13
    1142007-08-09  Sam Weinig  <sam@webkit.org>
    215
  • trunk/WebCore/ChangeLog

    r24976 r24977  
     12007-08-10  Mitz Pettel  <mitz@webkit.org>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        - fix http://bugs.webkit.org/show_bug.cgi?id=14798
     6          Incorrect bidi reordering of neutrals and digits after RTL embed
     7          and other bugs in the bidi algorithm.
     8
     9        Test: fast/text/international/bidi-neutral-run.html
     10
     11        Fixed several bugs in resolving the embedding level of runs of neutral
     12        characters. Changed the logic to rely on the eor direction only for
     13        the number types, and otherwise consider the last strong type.
     14
     15        * platform/BidiContext.h:
     16        (WebCore::BidiContext::BidiContext): Added an ASSERT.
     17        * platform/BidiResolver.h:
     18        (WebCore::::embed):
     19        (WebCore::::createBidiRunsForLine):
     20        * platform/graphics/GraphicsContext.cpp:
     21        (WebCore::TextRunIterator::atEnd): Changed to return true instead of
     22        crashing when called on the empty iterator.
     23
    1242007-08-09  Mark Rowe  <mrowe@apple.com>
    225
  • trunk/WebCore/platform/BidiContext.h

    r24485 r24977  
    2323#define BidiContext_h
    2424
     25#include <wtf/Assertions.h>
    2526#include <wtf/RefPtr.h>
    2627#include <wtf/unicode/Unicode.h>
     
    3839        , m_refCount(0)
    3940    {
     41        ASSERT(direction == WTF::Unicode::LeftToRight || direction == WTF::Unicode::RightToLeft);
    4042    }
    4143
  • trunk/WebCore/platform/BidiResolver.h

    r24621 r24977  
    2424
    2525#include "BidiContext.h"
    26 #include <wtf/Assertions.h>
    2726#include <wtf/PassRefPtr.h>
    2827
     
    193192        if (c) {
    194193            if (!emptyRun && eor != last) {
    195                 ASSERT(m_status.eor != OtherNeutral);
     194                ASSERT(m_status.eor != OtherNeutral || eor.atEnd());
    196195                // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last
    197196                ASSERT(m_status.last == EuropeanNumberSeparator
     
    204203                    || m_status.last == OtherNeutral);
    205204                if (m_direction == OtherNeutral)
    206                     m_direction = context()->dir();
     205                    m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightToLeft;
    207206                if (context()->dir() == LeftToRight) {
    208207                    // bidi.sor ... bidi.eor ... bidi.last L
     
    215214                        m_direction = ArabicNumber;
    216215                        appendRun();
    217                     } else if (m_status.eor != LeftToRight)
    218                         appendRun();
    219                 } else if (m_status.eor != RightToLeft && m_status.eor != RightToLeftArabic)
     216                    } else if (m_status.lastStrong != LeftToRight) {
     217                        if (context()->dir() == RightToLeft)
     218                            m_direction = RightToLeft;
     219                        else {
     220                            appendRun();
     221                            m_direction = LeftToRight;
     222                        }
     223                    }
     224                } else if (m_status.eor == EuropeanNumber || m_status.eor == ArabicNumber || m_status.lastStrong == LeftToRight) {
    220225                    appendRun();
     226                    m_direction = RightToLeft;
     227                }
    221228                eor = last;
    222229            }
     
    227234            setLastStrongDir(context()->dir());
    228235            setContext(c);
    229             setEorDir(context()->dir());
    230236            eor = Iterator();
    231237        }
     
    253259        if (level < 61) {
    254260            if (!emptyRun && eor != last) {
    255                 ASSERT(m_status.eor != OtherNeutral);
     261                ASSERT(m_status.eor != OtherNeutral || eor.atEnd());
    256262                // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last
    257263                ASSERT(m_status.last == EuropeanNumberSeparator
     
    264270                    || m_status.last == OtherNeutral);
    265271                if (m_direction == OtherNeutral)
    266                     m_direction = runDir;
     272                    m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightToLeft;
    267273                if (runDir == LeftToRight) {
    268274                    // bidi.sor ... bidi.eor ... bidi.last L
     
    271277                            m_direction = EuropeanNumber;
    272278                            appendRun();
    273                             if (context()->dir() != LeftToRight)
    274                                 m_direction = RightToLeft;
    275279                        }
    276280                    } else if (m_status.eor == ArabicNumber) {
    277281                        m_direction = ArabicNumber;
    278282                        appendRun();
    279                         if (context()->dir() != LeftToRight) {
    280                             eor = last;
    281                             m_direction = RightToLeft;
    282                             appendRun();
    283                         }
    284                     } else if (m_status.eor != LeftToRight) {
    285                         if (context()->dir() == LeftToRight || m_status.lastStrong == LeftToRight)
    286                             appendRun();
    287                         else
    288                             m_direction = RightToLeft;
     283                    } else if (m_status.lastStrong != LeftToRight && context()->dir() == LeftToRight) {
     284                        appendRun();
     285                        m_direction = LeftToRight;
    289286                    }
    290                 } else if (m_status.eor != RightToLeft && m_status.eor != RightToLeftArabic) {
    291                     // bidi.sor ... bidi.eor ... bidi.last R; bidi.eor=L/EN/AN; EN,AN behave like R (rule N1)
    292                     if (context()->dir() == RightToLeft || m_status.lastStrong == RightToLeft || m_status.lastStrong == RightToLeftArabic)
    293                         appendRun();
    294                     else
    295                         m_direction = LeftToRight;
     287                } else if (m_status.eor == ArabicNumber
     288                    || m_status.eor == EuropeanNumber && (m_status.lastStrong != LeftToRight || context()->dir() == RightToLeft)
     289                    || m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && context()->dir() == RightToLeft) {
     290                    appendRun();
     291                    m_direction = RightToLeft;
    296292                }
    297293                eor = last;
     
    302298            setLastDir(runDir);
    303299            setLastStrongDir(runDir);
    304             setEorDir(runDir);
    305300            eor = Iterator();
    306301        }
     
    422417        }
    423418
    424         ASSERT(m_status.eor != OtherNeutral);
     419        ASSERT(m_status.eor != OtherNeutral || eor.atEnd());
    425420        switch (dirCurrent) {
    426421
     
    476471                            appendRun();
    477472                        }
    478                     } else if (m_status.eor != LeftToRight) {
     473                    } else if (m_status.lastStrong != LeftToRight) {
    479474                        //last stuff takes embedding dir
    480                         if (context()->dir() != LeftToRight && m_status.lastStrong != LeftToRight) {
     475                        if (context()->dir() == RightToLeft) {
    481476                            eor = last;
    482477                            m_direction = RightToLeft;
    483478                        }
    484                         appendRun(); 
     479                        appendRun();
    485480                    }
    486481                default:
     
    510505                case WhiteSpaceNeutral:
    511506                case OtherNeutral:
    512                     if (m_status.eor != RightToLeft && m_status.eor != RightToLeftArabic) {
    513                         //last stuff takes embedding dir
    514                         if (context()->dir() != RightToLeft && m_status.lastStrong != RightToLeft
    515                             && m_status.lastStrong != RightToLeftArabic) {
     507                    if (m_status.eor == EuropeanNumber) {
     508                        if (m_status.lastStrong == LeftToRight && context()->dir() == LeftToRight)
    516509                            eor = last;
    517                             m_direction = LeftToRight;
    518                         }
     510                        appendRun();
     511                    } else if (m_status.eor == ArabicNumber)
     512                        appendRun();
     513                    else if (m_status.lastStrong == LeftToRight) {
     514                        if (context()->dir() == LeftToRight)
     515                            eor = last;
    519516                        appendRun();
    520517                    }
     
    554551                    case WhiteSpaceNeutral:
    555552                    case OtherNeutral:
    556                         if (m_status.eor == RightToLeft) {
    557                             // neutrals go to R
    558                             eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : last;
     553                        if (m_status.eor == EuropeanNumber) {
     554                            if (m_status.lastStrong == RightToLeft) {
     555                                // ENs on both sides behave like Rs, so the neutrals should be R.
     556                                // Terminate the EN run.
     557                                appendRun();
     558                                // Make an R run.
     559                                eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : last;
     560                                m_direction = RightToLeft;
     561                                appendRun();
     562                                // Begin a new EN run.
     563                                m_direction = EuropeanNumber;
     564                            }
     565                        } else if (m_status.eor == ArabicNumber) {
     566                            // Terminate the AN run.
    559567                            appendRun();
    560                             m_direction = EuropeanNumber;
    561                         } else if (m_status.eor != LeftToRight &&
    562                                  (m_status.eor != EuropeanNumber || m_status.lastStrong != LeftToRight) &&
    563                                  m_direction != LeftToRight) {
    564                             // numbers on both sides, neutrals get right to left direction
    565                             appendRun();
     568                            if (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft) {
     569                                // Make an R run.
     570                                eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : last;
     571                                m_direction = RightToLeft;
     572                                appendRun();
     573                                // Begin a new EN run.
     574                                m_direction = EuropeanNumber;
     575                            }
     576                        } else if (m_status.lastStrong == RightToLeft) {
     577                            // Extend the R run to include the neutrals.
    566578                            eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : last;
    567579                            m_direction = RightToLeft;
    568580                            appendRun();
     581                            // Begin a new EN run.
    569582                            m_direction = EuropeanNumber;
    570583                        }
     
    603616                case WhiteSpaceNeutral:
    604617                case OtherNeutral:
    605                     if (m_status.eor != RightToLeft && m_status.eor != RightToLeftArabic) {
    606                         // run of L before neutrals, neutrals take embedding dir (N2)
    607                         if (context()->dir() == RightToLeft || m_status.lastStrong == RightToLeft
    608                             || m_status.lastStrong == RightToLeftArabic) {
    609                             // the embedding direction is R
    610                             // close the L run
    611                             appendRun();
    612                             // neutrals become an R run
    613                             m_direction = RightToLeft;
    614                         } else {
    615                             // the embedding direction is L
    616                             // append neutrals to the L run and close it
    617                             m_direction = LeftToRight;
    618                         }
    619                     }
     618                    if (m_status.eor == ArabicNumber
     619                        || m_status.eor == EuropeanNumber && (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft)
     620                        || m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && context()->dir() == RightToLeft) {
     621                        // Terminate the run before the neutrals.
     622                        appendRun();
     623                        // Begin an R run for the neutrals.
     624                        m_direction = RightToLeft;
     625                    } else if (m_direction == OtherNeutral)
     626                        m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightToLeft;
    620627                    eor = last;
    621628                    appendRun();
  • trunk/WebCore/platform/graphics/GraphicsContext.cpp

    r24582 r24977  
    5757    unsigned offset() const { return m_offset; }
    5858    void increment(BidiResolver<TextRunIterator, BidiCharacterRun>&) { m_offset++; }
    59     bool atEnd() const { return m_offset >= m_textRun->length(); }
     59    bool atEnd() const { return !m_textRun || m_offset >= m_textRun->length(); }
    6060    UChar current() const { return (*m_textRun)[m_offset]; }
    6161    WTF::Unicode::Direction direction() const { return atEnd() ? WTF::Unicode::OtherNeutral : WTF::Unicode::direction(current()); }
Note: See TracChangeset for help on using the changeset viewer.