Changeset 113


Ignore:
Timestamp:
Sep 2, 2006, 4:34:30 PM (15 years ago)
Author:
Eugene Romanenko
Message:

replace ligatures when converting text from unicode to system codepage (closes #45)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Lucide/SOURCE/plugins/ludoc/cpconv.cpp

    r40 r113  
    244244            case 0x2019:
    245245            case 0x2032:
    246                 *uni = 0x0027;
     246                *uni = 0x0027; // '
    247247                break;
    248248            case 0x201C:
     
    250250            case 0x00AB:
    251251            case 0x00BB:
    252                 *uni = 0x0022;
     252                *uni = 0x0022; // "
    253253                break;
    254254            case 0x2014:
    255                 *uni = 0x002D;
     255                *uni = 0x002D; // -
    256256                break;
    257257        }
     
    260260}
    261261
     262
     263// Ligatures table
     264struct Ligature { UniChar unicode;  wchar_t *equivalent;  int equivalentLength; };
     265
     266// Table from [http://en.wikipedia.org/wiki/Ligature_(typography)#Unicode]
     267#define NUM_LIGATURES   38
     268static Ligature ligatures[ NUM_LIGATURES ] = {
     269    { 0x00DF, L"fs",  2 }, { 0x00E6, L"AE",  2 }, { 0x00C6, L"ae",  2 },
     270    { 0x0152, L"OE",  2 }, { 0x0153, L"oe",  2 }, { 0x0276, L"oe",  2 },
     271    { 0x0132, L"IJ",  2 }, { 0x0133, L"ij",  2 }, { 0x014A, L"Ng",  2 },
     272    { 0x014B, L"ng",  2 }, { 0x01F6, L"Hv",  2 }, { 0x0195, L"hv",  2 },
     273    { 0x01C4, L"DZ",  2 }, { 0x01C5, L"Dz",  2 }, { 0x01C6, L"dz",  2 },
     274    { 0x01C7, L"LJ",  2 }, { 0x01C8, L"Lj",  2 }, { 0x01C9, L"lj",  2 },
     275    { 0x01CA, L"NJ",  2 }, { 0x01CB, L"Nj",  2 }, { 0x01CC, L"nj",  2 },
     276    { 0x01F1, L"DZ",  2 }, { 0x01F2, L"Dz",  2 }, { 0x01F3, L"dz",  2 },
     277    { 0x02A3, L"dz",  2 }, { 0x02A6, L"ts",  2 }, { 0x02A9, L"fng", 3 },
     278    { 0x02AA, L"ls",  2 }, { 0x02AB, L"lz",  2 }, { 0x02AC, L"ww",  2 },
     279    { 0x1D6B, L"ue",  2 }, { 0xFB00, L"ff",  2 }, { 0xFB01, L"fi",  2 },
     280    { 0xFB02, L"fl",  2 }, { 0xFB03, L"ffi", 3 }, { 0xFB04, L"ffl", 3 },
     281    { 0xFB05, L"ft",  2 }, { 0xFB06, L"st",  2 }
     282};
     283
     284// If unichar is ligature - returns number of additional chars
     285// which replaces the ligature, zero otherwise.
     286inline int isLigature( UniChar ch )
     287{
     288    for ( int i = 0; i < NUM_LIGATURES; i++ ) {
     289        if ( ch == ligatures[ i ].unicode ) {
     290            return ligatures[ i ].equivalentLength - 1;
     291        }
     292    }
     293    return 0;
     294}
     295
     296// If unichar is ligature - returns pointer to struct Ligature
     297// which contains replacement for ligature, NULL otherwise.
     298inline Ligature *getReplLigature( UniChar ch )
     299{
     300    for ( int i = 0; i < NUM_LIGATURES; i++ ) {
     301        if ( ch == ligatures[ i ].unicode ) {
     302            return &( ligatures[ i ] );
     303        }
     304    }
     305    return NULL;
     306}
     307
     308// Return number of chars which should be added to string
     309// length to fit the string with converted ligatures.
     310// If no ligatures in string - returns zero.
     311static int ligaturesLength( UniChar *str )
     312{
     313    int llen = 0;
     314    while ( *str != 0 ) {
     315        llen += isLigature( *str++ );
     316    }
     317    return llen;
     318}
     319
     320// replaces ligatures in src into dst
     321// src remains unchanged
     322static void replLigatures( UniChar *src, UniChar *dst )
     323{
     324    while ( *src != 0 )
     325    {
     326        Ligature *lig = getReplLigature( *src );
     327        if ( lig == NULL ) {
     328            *dst++ = *src++;
     329        }
     330        else {
     331            for ( int i = 0; i < lig->equivalentLength; i++ ) {
     332                *dst++ = lig->equivalent[ i ];
     333            }
     334            *src++;
     335        }
     336    }
     337}
    262338
    263339extern "C" LONG APIENTRY cnvUTF8ToSys( const char **in, unsigned *in_left,
     
    272348    uni = savuni;
    273349    ulen = savulen;
     350    int liglen = ligaturesLength( (UniChar *)uni );
     351    if ( liglen > 0 )  // string contain ligature(s)
     352    {
     353        unsigned ulen_tmp = ulen + ( liglen * 2 );
     354        char *uni_tmp = new char[ ulen_tmp ];
     355        replLigatures( (UniChar *)uni, (UniChar *)uni_tmp );
     356        delete uni;
     357        uni = uni_tmp;
     358        ulen = ulen_tmp;
     359    }
    274360    convSpchars( (UniChar *)uni );
    275361    cpconv c( 1200 );
Note: See TracChangeset for help on using the changeset viewer.