Changeset 278:3f53ebb05b5b

Show
Ignore:
Timestamp:
08/04/08 19:07:44 (4 months ago)
Author:
Frank Benoit <benoit@tionex.de>
Children:

279:e4b7af6b8e7e 280:4ec36c3a04a3

branch:
default
Message:

Fix: make MARK copy work correctly mit multiple chars.
Fix: getLocation, getOffset (codepoint vs. chars)
Fix: itemize() translation of utf16 to utf8 indices

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • dwt/graphics/TextLayout.d

    r249 r278  
    3434 
    3535import tango.text.convert.Format; 
     36import Utf = tango.text.convert.Utf; 
    3637import dwt.dwthelper.utils; 
    3738import dwt.dwthelper.System; 
     
    9394    void* mLangFontLink2; 
    9495 
    95     static const wchar LTR_MARK = '\u200E', RTL_MARK = '\u200F'; 
     96    static const dchar LTR_MARK = '\u200E', RTL_MARK = '\u200F'; 
     97    static const String STR_LTR_MARK = "\u200E", STR_RTL_MARK = "\u200F"; 
     98    static const int MARK_SIZE = 3; 
    9699    static const int SCRIPT_VISATTR_SIZEOF = 2; 
    97100    static const int GOFFSET_SIZEOF = 8; 
     
    120123    class StyleItem { 
    121124        TextStyle style; 
     125        // DWT: start, lenght relative to segmentsText 
    122126        int start, length; 
    123127        bool lineBreak, softBreak, tab; 
     
    17921796                width = (trailing || (offset is length)) ? run.width : 0; 
    17931797            } else { 
    1794                 int runOffset = offset - run.start; 
     1798                // DWT: runOffset now in codepoints 
     1799                int runOffset = segmentsText[ run.start .. $ ].indexToCodepointIndex( offset - run.start ); 
    17951800                int cChars = run.length; 
    17961801                int gGlyphs = run.glyphCount; 
     
    18401845    length = segmentsText.length; 
    18411846    offset = translateOffset(offset); 
    1842     SCRIPT_LOGATTR* logAttr = new SCRIPT_LOGATTR()
    1843     SCRIPT_PROPERTIES* properties = new SCRIPT_PROPERTIES()
     1847    SCRIPT_LOGATTR* logAttr
     1848    SCRIPT_PROPERTIES* properties
    18441849    int i = forward ? 0 : allRuns.length - 1; 
    18451850    offset = validadeOffset(offset, step); 
     
    18491854            if (run.lineBreak && !run.softBreak) return untranslateOffset(run.start); 
    18501855            if (run.tab) return untranslateOffset(run.start); 
    1851             OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof)
     1856            properties = device.scripts[run.analysis.eScript]
    18521857            bool isComplex = properties.fNeedsCaretInfo || properties.fNeedsWordBreaking; 
    18531858            if (isComplex) breakRun(run); 
    18541859            while (run.start <= offset && offset < run.start + run.length) { 
    18551860                if (isComplex) { 
    1856                     OS.MoveMemory(logAttr, run.psla + (offset - run.start), SCRIPT_LOGATTR.sizeof); 
     1861                    logAttr = run.psla + (offset - run.start); 
    18571862                } 
    18581863                switch (movement) { 
     
    19581963    computeRuns(null); 
    19591964    if (trailing !is null && trailing.length < 1) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 
     1965 
    19601966    int line; 
    19611967    int lineCount = runs.length; 
     
    20032009            OS.ScriptXtoCP(xRun, cChars, cGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piCP, &piTrailing); 
    20042010            if (trailing !is null) trailing[0] = piTrailing; 
    2005             return untranslateOffset(run.start + piCP); 
     2011 
     2012            // DWT: back from codepoints to utf8 index 
     2013            int offsetIndex = segmentsText[ run.start .. $ ].codepointIndexToIndex( piCP ); 
     2014            return untranslateOffset(run.start + offsetIndex); 
    20062015        } 
    20072016    } 
     
    21052114    char[] oldChars = new char[length_]; 
    21062115    text.getChars(0, length_, oldChars, 0); 
    2107     char[] newChars = new char[length_ + nSegments]; 
     2116    // DWT: MARK is now 3 chars long 
     2117    String separator = orientation is DWT.RIGHT_TO_LEFT ? STR_RTL_MARK : STR_LTR_MARK; 
     2118    assert( separator.length is MARK_SIZE ); 
     2119    char[] newChars = new char[length_ + nSegments*MARK_SIZE]; 
    21082120    int charCount = 0, segmentCount = 0; 
    2109     wchar separator = orientation is DWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK; 
    21102121    while (charCount < length_) { 
    21112122        if (segmentCount < nSegments && charCount is segments[segmentCount]) { 
    2112             newChars[charCount + segmentCount++] = separator; 
     2123            int start = charCount + (segmentCount*MARK_SIZE); 
     2124            newChars[ start .. start + MARK_SIZE ] = separator; 
     2125            segmentCount++; 
    21132126        } else { 
    2114             newChars[charCount + segmentCount] = oldChars[charCount++]; 
     2127            newChars[charCount + (segmentCount*MARK_SIZE)] = oldChars[charCount]; 
     2128            charCount++; 
    21152129        } 
    21162130    } 
    21172131    if (segmentCount < nSegments) { 
    21182132        segments[segmentCount] = charCount; 
    2119         newChars[charCount + segmentCount++] = separator; 
    2120     } 
    2121     return newChars[ 0 .. Math.min(charCount + segmentCount, newChars.length)].dup; 
     2133        int start = charCount + (segmentCount*MARK_SIZE); 
     2134        newChars[ start .. start + MARK_SIZE ] = separator; 
     2135        segmentCount++; 
     2136    } 
     2137    return newChars[ 0 .. Math.min(charCount + (segmentCount*MARK_SIZE), newChars.length)].dup; 
    21222138} 
    21232139 
     
    22532269 */ 
    22542270StyleItem[] itemize () { 
     2271    // DWT: itemize is the process of finding changes in direction 
    22552272    segmentsText = getSegmentsText(); 
    22562273    int length = segmentsText.length; 
     
    22742291    OS.ScriptItemize(chars.ptr, chars.length, MAX_ITEM, &scriptControl, &scriptState, pItems, &pcItems); 
    22752292//  if (hr is E_OUTOFMEMORY) //TODO handle it 
     2293    // DWT pcItems is not inclusive the trailing item 
    22762294 
    22772295    // Translate the utf16 indices to utf8 indices 
    22782296    int utf8idx = 0; 
     2297    int utf16idx = 0; 
     2298    int i = 0; 
    22792299    SCRIPT_ITEM* si = pItems; 
    2280     foreach( uint utf16idx, char c; chars ){ 
     2300    while( utf16idx < chars.length ){ 
     2301 
    22812302        if( si.iCharPos is utf16idx ){ 
    22822303            si.iCharPos = utf8idx; 
     2304            i++; 
    22832305            si++; 
    22842306        } 
    2285         utf8idx++; 
    2286     } 
     2307 
     2308        // goto next codepoint 
     2309        uint ate16; 
     2310        dchar[1] buf32; 
     2311        dchar[] res32 = Utf.toString32( chars[ utf16idx .. $ ], buf32, &ate16 ); 
     2312        uint ate32; 
     2313        char[4] buf8; 
     2314        char[] res8 = Utf.toString( res32, buf8, &ate32 ); 
     2315        utf16idx += ate16; 
     2316        utf8idx += res8.length; 
     2317    } 
     2318    assert( si.iCharPos is chars.length ); 
     2319    si.iCharPos = utf8idx; 
     2320    assert( si.iCharPos is segmentsText.length ); 
     2321    assert( i is pcItems ); 
    22872322 
    22882323    StyleItem[] runs = merge(pItems, pcItems); 
     
    23022337    int count = 0, start = 0, end = segmentsText.length, itemIndex = 0, styleIndex = 0; 
    23032338    StyleItem[] runs = new StyleItem[itemCount + stylesCount]; 
    2304     SCRIPT_ITEM* scriptItem = new SCRIPT_ITEM()
     2339    SCRIPT_ITEM* scriptItem
    23052340    bool linkBefore = false; 
    23062341    while (start < end) { 
     
    23092344        item.style = styles[styleIndex].style; 
    23102345        runs[count++] = item; 
    2311         OS.MoveMemory(scriptItem, (cast(void*)items) + itemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof)
     2346        scriptItem = items + itemIndex
    23122347        item.analysis = scriptItem.a; 
    23132348        if (linkBefore) { 
     
    23162351        } 
    23172352        //scriptItem.a = new SCRIPT_ANALYSIS(); 
    2318         OS.MoveMemory(scriptItem, (cast(void*)items) + (itemIndex + 1) * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); 
     2353        scriptItem = items + (itemIndex + 1); 
    23192354        int itemLimit = scriptItem.iCharPos; 
    23202355        int styleLimit = translateOffset(styles[styleIndex + 1].start); 
     
    23392374    StyleItem item = new StyleItem(); 
    23402375    item.start = end; 
    2341     OS.MoveMemory(scriptItem, (cast(void*)items) + itemCount * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof)
     2376    scriptItem = items + itemCount
    23422377    item.analysis = scriptItem.a; 
    23432378    runs[count++] = item; 
     
    28342869 */ 
    28352870void shape (HDC hdc, StyleItem run) { 
    2836     final int[] buffer = new int[1]
    2837     final char[] chars = new char[run.length]; 
     2871    int[1] buffer
     2872    char[] chars = new char[run.length]; 
    28382873    segmentsText.getChars(run.start, run.start + run.length, chars, 0); 
    28392874    wchar[] wchars = StrToWCHARs( chars ); 
     
    29943029 
    29953030int validadeOffset(int offset, int step) { 
    2996     offset += step
     3031    offset += segmentsText.getRelativeCodePointOffset( offset, step )
    29973032    if (segments !is null && segments.length > 2) { 
    29983033        for (int i = 0; i < segments.length; i++) { 
     
    30273062    } 
    30283063    for (int i = 0; i < nSegments && offset - i >= segments[i]; i++) { 
    3029         offset++
     3064        offset+=MARK_SIZE
    30303065    } 
    30313066    return offset; 
     
    30423077    } 
    30433078    for (int i = 0; i < nSegments && offset > segments[i]; i++) { 
    3044         offset--
     3079        offset-=MARK_SIZE
    30453080    } 
    30463081    return offset;