Changeset 182:721afe91f448

Show
Ignore:
Timestamp:
03/02/08 12:39:35 (7 months ago)
Author:
Frank Benoit <benoit@tionex.de>
branch:
default
Message:

Fix: several utf8 awareness problems

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • dwt/custom/CTabFolder.d

    r150 r182  
    13051305        while (index < length_ && string[index] !is '&') index++; 
    13061306        if (++index >= length_) return '\0'; 
    1307         if (string[index] !is '&') return CharacterToLower(getFirstCodepoint( string[index..$])); 
     1307        if (string[index] !is '&') return CharacterFirstToLower(string[index..$]); 
    13081308        index++; 
    13091309    } while (index < length_); 
  • dwt/custom/DefaultContent.d

    r108 r182  
    1 /******************************************************************************* 
     1/******************************************************************************* 
    22 * Copyright (c) 2000, 2007 IBM Corporation and others. 
    33 * All rights reserved. This program and the accompanying materials 
     
    890890    gapLine = getLineAtPhysicalOffset(gapStart); 
    891891} 
    892 
     892 
     893/++ 
     894 + DWT extension 
     895 +/ 
     896int utf8AdjustOffset( int offset ){ 
     897    if (textStore is null) 
     898        return offset; 
     899    if (offset is 0) 
     900        return offset; 
     901    if( offset >= textStore.length ){ 
     902        return offset; 
     903    } 
     904    if (!gapExists() || (offset < gapStart)){ 
     905        while( textStore[offset] & 0xC0 is 0x80 ){ 
     906            offset--; 
     907        } 
     908        return offset; 
     909    } 
     910    int gapLength= gapEnd - gapStart; 
     911    if( offset+gapLength >= textStore.length ){ 
     912        return offset; 
     913    } 
     914    while( textStore[offset+gapLength] & 0xC0 is 0x80 ){ 
     915        offset--; 
     916    } 
     917    return offset; 
     918
     919 
     920 
     921
  • dwt/custom/ExtendedModifyEvent.d

    r108 r182  
    1 /******************************************************************************* 
     1/******************************************************************************* 
    22 * Copyright (c) 2000, 2004 IBM Corporation and others. 
    33 * All rights reserved. This program and the accompanying materials 
  • dwt/custom/StyledText.d

    r170 r182  
    9191alias tango.text.Text.Text!(char) StringBuffer; 
    9292private alias char[] String; 
    93  
    9493 
    9594/** 
     
    841840     */ 
    842841    void write(String string, int start, int end) { 
    843         wchar[] wstring = tango.text.convert.Utf.toString16( string[ start .. end ] ); 
    844842        start = 0; 
    845         end = wstring.length; 
    846         for (int index = start; index < end; index++) { 
    847             wchar ch = wstring[index]; 
     843        end = string.length; 
     844        int incr = 1; 
     845        for (int index = start; index < end; index+=incr) { 
     846            dchar ch = firstCodePoint( string[index .. $], incr ); 
    848847            if (ch > 0xFF && WriteUnicode) { 
    849848                // write the sub string from the last escaped character 
    850849                // to the current one. Fixes bug 21698. 
    851850                if (index > start) { 
    852                     write(tango.text.convert.Utf.toString(wstring[start .. index ])); 
     851                    write( string[start .. index ] ); 
    853852                } 
    854853                write("\\u"); 
    855854                write( to!(char[])( cast(short)ch )); 
    856855                write(' ');                     // control word delimiter 
    857                 start = index + 1
     856                start = index + incr
    858857            } else if (ch is '}' || ch is '{' || ch is '\\') { 
    859858                // write the sub string from the last escaped character 
    860859                // to the current one. Fixes bug 21698. 
    861860                if (index > start) { 
    862                     write(tango.text.convert.Utf.toString(wstring[start .. index])); 
     861                    write(string[start .. index]); 
    863862                } 
    864863                write('\\'); 
     
    870869        // Fixes bug 21698. 
    871870        if (start < end) { 
    872             write(tango.text.convert.Utf.toString(wstring[ start .. end])); 
     871            write(string[ start .. end]); 
    873872        } 
    874873    } 
     
    22342233 * @param key the character typed by the user 
    22352234 */ 
    2236 void doContent(char key) { 
     2235void doContent(dchar key) { 
    22372236    if (textLimit > 0 && 
    22382237        content.getCharCount() - (selection.y - selection.x) >= textLimit) { 
     
    22582257        // end of the line 
    22592258        if (event.end < lineOffset + line.length) { 
    2260             event.end++
    2261         } 
    2262         event.text = [key]
     2259            event.end+=dcharToString( key ).length
     2260        } 
     2261        event.text = dcharToString( key )
    22632262    } else { 
    2264         event.text = [key]
     2263        event.text = dcharToString( key )
    22652264    } 
    22662265    if (event.text !is null) { 
     
    29762975    int offsetInLine = caretOffset - lineOffset; 
    29772976    caretAlignment = OFFSET_LEADING; 
     2977 
    29782978    if (offsetInLine > 0) { 
    29792979        caretOffset = getClusterPrevious(caretOffset, caretLine); 
     
    56245624        while (index < length_ && string[index] !is '&') index++; 
    56255625        if (++index >= length_) return '\0'; 
    5626         if (string[index] !is '&') return CharacterToLower(getFirstCodepoint( string[index .. $ ] )); 
     5626        if (string[index] !is '&') return CharacterFirstToLower(string[index .. $ ] ); 
    56275627        index++; 
    56285628    } while (index < length_); 
     
    76867686void setSelection(int start, int length, bool sendEvent) { 
    76877687    int end = start + length; 
     7688    start = content.utf8AdjustOffset(start); 
     7689    end = content.utf8AdjustOffset(end); 
    76887690    if (start > end) { 
    76897691        int temp = end; 
  • dwt/custom/StyledTextContent.d

    r108 r182  
    1 /******************************************************************************* 
     1/******************************************************************************* 
    22 * Copyright (c) 2000, 2006 IBM Corporation and others. 
    33 * All rights reserved. This program and the accompanying materials 
     
    206206 */ 
    207207public void setText(char[] text); 
     208 
     209/++ 
     210 + DWT Extension 
     211 +/ 
     212int utf8AdjustOffset( int offset ); 
     213 
    208214} 
  • dwt/custom/TextChangingEvent.d

    r108 r182  
    1 /******************************************************************************* 
     1/******************************************************************************* 
    22 * Copyright (c) 2000, 2004 IBM Corporation and others. 
    33 * All rights reserved. This program and the accompanying materials 
  • dwt/graphics/TextLayout.d

    r170 r182  
    7272    PangoAttrList* attrList; 
    7373    int[] invalidOffsets; 
    74     static const wchar LTR_MARK = '\u200E', RTL_MARK = '\u200F', ZWS = '\u200B', ZWNBS = '\uFEFF'; 
     74    // LTR_MARK LEFT-TO-RIGHT MARK 
     75    // RTL_MARK RIGHT-TO-LEFT MARK 
     76    // ZWS      ZERO WIDTH SPACE 
     77    // ZWNBS    ZERO WIDTH NO-BREAK SPACE 
     78    static const dchar LTR_MARK = '\u200E', RTL_MARK = '\u200F', ZWS = '\u200B', ZWNBS = '\uFEFF'; 
     79    static const char[] STR_LTR_MARK = "\u200E", STR_RTL_MARK = "\u200F", STR_ZWS = "\u200B", STR_ZWNBS = "\uFEFF"; 
    7580 
    7681/** 
     
    124129    attrList = OS.pango_attr_list_new(); 
    125130    //PangoAttribute* attribute = new PangoAttribute(); 
    126     wchar[] charsW = null; 
    127     wchar[] segmentsTextW = toString16( segmentsText ); 
    128     int segementsWLength = segmentsTextW.length; 
    129     if ((ascent !is -1  || descent !is -1) && segementsWLength > 0) { 
     131    char[] chars = null; 
     132    int segementsLength = segmentsText.length; 
     133    if ((ascent !is -1  || descent !is -1) && segementsLength > 0) { 
    130134        auto iter = OS.pango_layout_get_iter(layout); 
    131135        if (iter is null) DWT.error(DWT.ERROR_NO_HANDLES); 
     
    134138        rect.height = (Math.max(0, ascent) + Math.max(0, descent)) * OS.PANGO_SCALE; 
    135139        int lineCount = OS.pango_layout_get_line_count(layout); 
    136         charsW = new wchar[segementsWLength + lineCount * 2]; 
     140        chars = new char[segementsLength + lineCount * 6/*2*/]; 
    137141        int oldPos = 0, count = 0; 
    138142        do { 
     
    148152            attr.end_index = bytePos + offset + 6; 
    149153            OS.pango_attr_list_insert(attrList, attr); 
    150             int pos = OS.g_utf8_pointer_to_offset(ptr, ptr + bytePos); 
    151             charsW[pos + count * 2] = ZWS; 
    152             charsW[pos + count * 2 + 1] = ZWNBS; 
    153             charsW[ oldPos + count*2 .. oldPos + count*2 + pos - oldPos ] = 
    154                 segmentsTextW[ oldPos .. pos ]; 
    155             //segmentsTextW.getChars(oldPos, pos, chars,  oldPos + count * 2); 
     154            int pos = bytePos;//OS.g_utf8_pointer_to_offset(ptr, ptr + bytePos); 
     155            chars[pos + count * 6 +0 .. pos + count * 6 + 3] = STR_ZWS; 
     156            chars[pos + count * 6 +3 .. pos + count * 6 + 6] = STR_ZWNBS; 
     157            chars[ oldPos + count*6 .. oldPos + count*6 + pos - oldPos ] = 
     158                segmentsText[ oldPos .. pos ]; 
    156159            oldPos = pos; 
    157160            count++; 
    158161        } while (OS.pango_layout_iter_next_line(iter)); 
    159162        OS.pango_layout_iter_free (iter); 
    160         charsW[ oldPos + count*2 .. oldPos + count*2 + segementsWLength - oldPos ] = 
    161             segmentsTextW[ oldPos .. segementsWLength ]; 
    162         //segmentsTextW.getChars(oldPos, segementsWLength, chars,  oldPos + count * 2); 
    163         char[] buffer = .toString( charsW );// Converter.wcsToMbcs(null, chars, false); 
     163        chars[ oldPos + count*6 .. oldPos + count*6 + segementsLength - oldPos ] = 
     164            segmentsText[ oldPos .. segementsLength ]; 
     165        char[] buffer = chars;// Converter.wcsToMbcs(null, chars, false); 
     166 
    164167        OS.pango_layout_set_text (layout, buffer.ptr, buffer.length); 
    165168        ptr = OS.pango_layout_get_text(layout); 
    166169    } else { 
    167         charsW = segmentsTextW.dup; 
     170        chars = segmentsText.dup; 
    168171    } 
    169172    int offsetCount = 0; 
    170     for (int i = 0; i < charsW.length; i++) { 
    171         wchar c = charsW[i]; 
    172         if (c is LTR_MARK || c is RTL_MARK || c is ZWNBS || c is ZWS) { 
    173             offsetCount++; 
     173    { 
     174        int i = 0; 
     175        while( i < chars.length ){ 
     176            int incr; 
     177            dchar c = firstCodePoint( chars[ i .. $ ], incr ); 
     178            if (c is LTR_MARK || c is RTL_MARK || c is ZWNBS || c is ZWS) { 
     179                offsetCount+=3; 
     180            } 
     181            i += incr; 
    174182        } 
    175183    } 
    176184    invalidOffsets = new int[offsetCount]; 
    177185    offsetCount = 0; 
    178     for (int i = 0; i < charsW.length; i++) { 
    179         wchar c = charsW[i]; 
    180         if (c is LTR_MARK || c is RTL_MARK || c is ZWNBS || c is ZWS) { 
    181             invalidOffsets[offsetCount++] = i; 
     186    { 
     187        int i = 0; 
     188        while( i < chars.length ){ 
     189            int incr; 
     190            dchar c = firstCodePoint( chars[ i .. $ ], incr ); 
     191            if (c is LTR_MARK || c is RTL_MARK || c is ZWNBS || c is ZWS) { 
     192                invalidOffsets[offsetCount++] = i; 
     193                invalidOffsets[offsetCount++] = i+1; 
     194                invalidOffsets[offsetCount++] = i+2; 
     195            } 
     196            i += incr; 
    182197        } 
    183198    } 
     
    189204        int start = translateOffset(styleItem.start); 
    190205        int end = translateOffset(styles[i+1].start - 1); 
    191         int byteStart = (OS.g_utf8_offset_to_pointer(ptr, start) - ptr); 
    192         int byteEnd = (OS.g_utf8_offset_to_pointer(ptr, end + 1) - ptr); 
     206        int byteStart = start;//(OS.g_utf8_offset_to_pointer(ptr, start) - ptr); 
     207        int byteEnd = end+1;//(OS.g_utf8_offset_to_pointer(ptr, end + 1) - ptr); 
    193208        byteStart = Math.min(byteStart, slen); 
    194209        byteEnd = Math.min(byteEnd, slen); 
     
    371386            if (OS.pango_layout_iter_next_line(iter)) { 
    372387                int bytePos = OS.pango_layout_iter_get_index(iter); 
    373                 lineEnd = OS.g_utf8_pointer_to_offset(ptr, ptr + bytePos); 
     388                lineEnd = bytePos;//OS.g_utf8_pointer_to_offset(ptr, ptr + bytePos); 
    374389            } else { 
    375390                lineEnd = OS.g_utf8_strlen(ptr, -1); 
     
    440455        } else { 
    441456            auto ptr = OS.pango_layout_get_text(layout); 
    442             int byteSelStart = (OS.g_utf8_offset_to_pointer(ptr, selectionStart) - ptr); 
    443             int byteSelEnd = (OS.g_utf8_offset_to_pointer(ptr, selectionEnd + 1) - ptr); 
     457            int byteSelStart = selectionStart;//(OS.g_utf8_offset_to_pointer(ptr, selectionStart) - ptr); 
     458            int byteSelEnd = selectionEnd + 1;//(OS.g_utf8_offset_to_pointer(ptr, selectionEnd + 1) - ptr); 
    444459            int slen = strlen(ptr); 
    445460            byteSelStart = Math.min(byteSelStart, slen); 
     
    583598    end = translateOffset(end); 
    584599    auto ptr = OS.pango_layout_get_text(layout); 
    585     int byteStart = (OS.g_utf8_offset_to_pointer (ptr, start) - ptr); 
    586     int byteEnd = (OS.g_utf8_offset_to_pointer (ptr, end + 1) - ptr); 
     600    auto cont = fromStringz(ptr); 
     601    start = cont.utf8AdjustOffset( start ); 
     602    end = cont.utf8AdjustOffset( end ); 
     603    int incr = 1; 
     604    if( end < cont.length ){ 
     605        incr = cont.getRelativeCodePointOffset( end, 1 ); 
     606    } 
     607    int byteStart = start;//(OS.g_utf8_offset_to_pointer (ptr, start) - ptr); 
     608    int byteEnd = end + incr;//(OS.g_utf8_offset_to_pointer (ptr, end + 1) - ptr); 
    587609    int slen = strlen(ptr); 
    588610    byteStart = Math.min(byteStart, slen); 
     
    719741    PangoLayoutRun* run = new PangoLayoutRun(); 
    720742    auto ptr = OS.pango_layout_get_text(layout); 
    721     auto byteOffset = OS.g_utf8_offset_to_pointer(ptr, offset) - ptr; 
     743    auto byteOffset = offset;//OS.g_utf8_offset_to_pointer(ptr, offset) - ptr; 
    722744    int slen = strlen(ptr); 
    723745    byteOffset = Math.min(byteOffset, slen); 
     
    809831    int line = 0; 
    810832    auto ptr = OS.pango_layout_get_text(layout); 
    811     auto byteOffset = OS.g_utf8_offset_to_pointer(ptr,offset) - ptr; 
     833    auto byteOffset = offset;//OS.g_utf8_offset_to_pointer(ptr,offset) - ptr; 
    812834    int slen = strlen(ptr); 
    813835    byteOffset = Math.min(byteOffset, slen); 
     
    883905    do { 
    884906        int bytePos = OS.pango_layout_iter_get_index(iter); 
    885         int pos = OS.g_utf8_pointer_to_offset(ptr, ptr + bytePos); 
     907        int pos = bytePos;//OS.g_utf8_pointer_to_offset(ptr, ptr + bytePos); 
    886908        offsets[i++] = untranslateOffset(pos); 
    887909    } while (OS.pango_layout_iter_next_line(iter)); 
     
    914936    offset = translateOffset(offset); 
    915937    auto ptr = OS.pango_layout_get_text(layout); 
    916     int byteOffset = (OS.g_utf8_offset_to_pointer(ptr, offset) - ptr); 
    917     int slen = strlen(ptr); 
     938    auto cont = fromStringz(ptr); 
     939    offset = cont.utf8AdjustOffset(offset); 
     940    // leading ZWS+ZWNBS are 2 codepoints in 6 bytes, so we miss 4 bytes here 
     941    int byteOffset = offset;//(OS.g_utf8_offset_to_pointer(ptr, offset) - ptr); 
     942    int slen = cont.length; 
    918943    byteOffset = Math.min(byteOffset, slen); 
    919944    PangoRectangle* pos = new PangoRectangle(); 
     
    957982        if (offset is 0) return 0; 
    958983    } 
     984    auto cont = OS.pango_layout_get_text(layout); 
     985    assert( cont ); 
     986    auto dcont = fromStringz(cont); 
    959987    int step = forward ? 1 : -1; 
    960     if ((movement & DWT.MOVEMENT_CHAR) !is 0) return offset + step; 
     988    if ((movement & DWT.MOVEMENT_CHAR) !is 0){ 
     989        //PORTING take care of utf8 
     990        int toffset = translateOffset(offset); 
     991        toffset = dcont.utf8AdjustOffset( toffset ); 
     992        int incr = dcont.getRelativeCodePointOffset( toffset, step ); 
     993        return offset + incr; 
     994    } 
    961995    PangoLogAttr* attrs; 
    962996    int nAttrs; 
    963997    OS.pango_layout_get_log_attrs(layout, &attrs, &nAttrs); 
    964998    if (attrs is null) return offset + step; 
    965     length = OS.g_utf8_strlen(OS.pango_layout_get_text(layout), -1); 
     999    length = OS.g_utf8_strlen(cont, -1); 
    9661000    offset = translateOffset(offset); 
     1001    offset = dcont.utf8AdjustOffset( offset ); 
    9671002    PangoLogAttr* logAttr = new PangoLogAttr(); 
    968     offset = validateOffset(offset, step); 
     1003    offset = validateOffset( dcont, offset, step); 
    9691004    while (0 < offset && offset < length) { 
    9701005        *logAttr = attrs[ offset ]; 
     
    9831018            if (logAttr.bitfield0 & (1<<6/*is_word_end*/)) break; 
    9841019        } 
    985         offset = validateOffset(offset, step); 
     1020        offset = validateOffset( dcont, offset, step); 
    9861021    } 
    9871022    OS.g_free(attrs); 
     
    10741109    OS.pango_layout_xy_to_index(layout, x * OS.PANGO_SCALE, y * OS.PANGO_SCALE, &index, &piTrailing); 
    10751110    auto ptr = OS.pango_layout_get_text(layout); 
    1076     int offset = OS.g_utf8_pointer_to_offset(ptr, ptr + index); 
     1111    int offset = index;//OS.g_utf8_pointer_to_offset(ptr, ptr + index); 
    10771112    if (trailing !is null) trailing[0] = piTrailing; 
    10781113    return untranslateOffset(offset); 
     
    11731208    } 
    11741209    char[] oldChars = text[0..len].dup; 
    1175     char[] newChars = new char[len + nSegments]; 
     1210    char[] newChars = new char[len + nSegments*3]; 
    11761211    int charCount = 0, segmentCount = 0; 
    1177     wchar separator = getOrientation() is DWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK; 
     1212    char[] separator = getOrientation() is DWT.RIGHT_TO_LEFT ? STR_RTL_MARK : STR_LTR_MARK; 
    11781213    while (charCount < len) { 
    11791214        if (segmentCount < nSegments && charCount is segments[segmentCount]) { 
    1180             newChars[charCount + segmentCount++] = separator; 
     1215            newChars[charCount + segmentCount .. charCount + segmentCount + separator.length ] = separator; 
     1216            segmentCount+=separator.length; 
    11811217        } else { 
    1182             newChars[charCount + segmentCount] = oldChars[charCount++]; 
     1218            newChars[charCount + segmentCount] = oldChars[charCount]; 
     1219            charCount++; 
    11831220        } 
    11841221    } 
    11851222    if (segmentCount < nSegments) { 
    11861223        segments[segmentCount] = charCount; 
    1187         newChars[charCount + segmentCount++] = separator; 
     1224        newChars[charCount + segmentCount .. charCount + segmentCount + separator.length ] = separator; 
     1225        segmentCount+=separator.length; 
    11881226    } 
    11891227    return newChars[ 0 .. Math.min(charCount + segmentCount, newChars.length) ]; 
     
    14251463    if (font !is null && font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 
    14261464    if (this.font is font) return; 
    1427     if (font !is null && font ==/*eq*/ this.font ) return; 
     1465    if (font !is null && font.opEquals(this.font)) return; 
    14281466    this.font = font; 
    14291467    OS.pango_layout_set_font_description(layout, font !is null ? font.handle : null); 
     
    15551593 */ 
    15561594public void setStyle (TextStyle style, int start, int end) { 
     1595    char[] styleTxt = "<null>"; 
     1596    if( style !is null ){ 
     1597        styleTxt = style.toString; 
     1598    } 
    15571599    checkLayout(); 
    15581600    int length = text.length; 
     
    15611603    start = Math.min(Math.max(0, start), length - 1); 
    15621604    end = Math.min(Math.max(0, end), length - 1); 
     1605    start = text.utf8AdjustOffset( start ); 
     1606    end = text.utf8AdjustOffset( end ); 
     1607 
    15631608 
    15641609    /* 
     
    15691614    * NOTE that fix only LamAlef ligatures. 
    15701615    */ 
    1571     if (start > 0 && isAlef(text[start]) && isLam(text[start - 1])) { 
    1572         start--; 
    1573     } 
    1574     if (end < length - 1 && isLam(text[end]) && isAlef(text[end + 1])) { 
    1575         end++; 
     1616    int relIndex; 
     1617    if ((start > 0 ) && isAlef(text[ start .. $ ].firstCodePoint()) && isLam(text.getRelativeCodePoint( start, -1, relIndex ))) { 
     1618        start += relIndex; 
     1619    } 
     1620    if ((end < length - 1) && isLam(text[ end .. $ ].firstCodePoint()) && isAlef(text.getRelativeCodePoint(end, 1,relIndex))) { 
     1621        end += relIndex; 
    15761622    } 
    15771623 
     
    15921638                if (item.style is null) return; 
    15931639            } else { 
    1594                 if (style ==/*eq*/ item.style) return; 
     1640                if (style.opEquals(item.style)) return; 
    15951641            } 
    15961642        } 
     
    16951741public void setText (char[] text) { 
    16961742    checkLayout (); 
    1697     if (text ==/*eq*/this.text) return; 
     1743    if (text.equals(this.text)) return; 
    16981744    freeRuns(); 
    16991745    this.text = text; 
     
    17931839} 
    17941840 
    1795 int validateOffset(int offset, int step) { 
     1841int validateOffset( char[] cont, int offset, int step) { 
    17961842    if (invalidOffsets is null) return offset + step; 
    17971843    int i = step > 0 ? 0 : invalidOffsets.length - 1; 
    17981844    do { 
    1799         offset += step; 
     1845        if( offset is 0 && step < 0 ){ 
     1846            offset += step; 
     1847        } 
     1848        else{ 
     1849            offset += cont.getRelativeCodePointOffset( offset, step ); 
     1850        } 
    18001851        while (0 <= i && i < invalidOffsets.length) { 
    18011852            if (invalidOffsets[i] is offset) break;