summaryrefslogtreecommitdiffstats
path: root/khtml/rendering/break_lines.cpp
blob: 483455127fe2504d1c81793907ad07e45b925af9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <break_lines.h>
#include <klibloader.h>
#include "qcstring.h"
#include <qtextcodec.h>
#include <qcleanuphandler.h>
#include <config.h>


/* If HAVE_LIBTHAI is defined, libkhtml will link against 
 * libthai since compile time. Otherwise it will try to 
 * dlopen at run-time
 *
 * Ott Pattara Nov 14, 2004
 */

#ifndef HAVE_LIBTHAI
typedef int (*th_brk_def)(const unsigned char*, int[], int);
static th_brk_def th_brk;
#else
#include <thai/thailib.h>
#include <thai/thbrk.h>
#endif

namespace khtml {
    struct ThaiCache
    {
        ThaiCache() {
            string = 0;
            allocated = 0x400;
            wbrpos = (int *) malloc(allocated*sizeof(int));
            numwbrpos = 0;
            numisbreakable = 0x400;
            isbreakable = (int *) malloc(numisbreakable*sizeof(int));
	    library = 0;
        }
        ~ThaiCache() {
            free(wbrpos);
            free(isbreakable);
            if (library) library->unload();
        }
        const QChar *string;
        int *wbrpos;
        int *isbreakable;
        int allocated;
        int numwbrpos,numisbreakable;
        KLibrary *library;
    };
    static ThaiCache *cache = 0;

    void cleanup_thaibreaks()
    {
        delete cache;
        cache = 0;
#ifndef HAVE_LIBTHAI
        th_brk = 0;
#endif
    }

    bool isBreakableThai( const QChar *string, const int pos, const int len)
    {
        static QTextCodec *thaiCodec = QTextCodec::codecForMib(2259);
	//printf("Entering isBreakableThai with pos = %d\n", pos);

#ifndef HAVE_LIBTHAI
	
	KLibrary *lib = 0;

        /* load libthai dynamically */
	if (( !th_brk ) && thaiCodec  ) {
	    printf("Try to load libthai dynamically...\n");
            KLibLoader *loader = KLibLoader::self();
            lib = loader->library("libthai");
            if (lib && lib->hasSymbol("th_brk")) {
                th_brk = (th_brk_def) lib->symbol("th_brk");
            } else {
                // indication that loading failed and we shouldn't try to load again
		printf("Error, can't load libthai...\n");
                thaiCodec = 0;
                if (lib)
                    lib->unload();
            }
        }

        if (!th_brk ) {
            return true;
        }
#endif

	if (!cache ) {
            cache = new ThaiCache;
#ifndef HAVE_LIBTHAI
            cache->library = lib;
#endif
	}

        // build up string of thai chars
        if ( string != cache->string ) {
            //fprintf(stderr,"new string found (not in cache), calling libthai\n");
            QCString cstr = thaiCodec->fromUnicode( QConstString(string,len).string());
            //printf("About to call libthai::th_brk with str: %s",cstr.data());

            cache->numwbrpos = th_brk((const unsigned char*) cstr.data(), cache->wbrpos, cache->allocated);
            //fprintf(stderr,"libthai returns with value %d\n",cache->numwbrpos);
            if (cache->numwbrpos > cache->allocated) {
                cache->allocated = cache->numwbrpos;
                cache->wbrpos = (int *)realloc(cache->wbrpos, cache->allocated*sizeof(int));
                cache->numwbrpos = th_brk((const unsigned char*) cstr.data(), cache->wbrpos, cache->allocated);
            }
	    if ( len > cache->numisbreakable ) {
		cache->numisbreakable=len;
                cache->isbreakable = (int *)realloc(cache->isbreakable, cache->numisbreakable*sizeof(int));
	    }
	    for (int i = 0 ; i < len ; ++i) {
		cache->isbreakable[i] = 0;
	    }
            if ( cache->numwbrpos > 0 ) {
            	for (int i = cache->numwbrpos-1; i >= 0; --i) {
                	cache->isbreakable[cache->wbrpos[i]] = 1;
		}
	    }
            cache->string = string;
        }
	//printf("Returning %d\n", cache->isbreakable[pos]);
	return cache->isbreakable[pos];
    }
}