Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
      3  *
      4  * This is part of HarfBuzz, an OpenType Layout engine library.
      5  *
      6  * Permission is hereby granted, without written agreement and without
      7  * license or royalty fees, to use, copy, modify, and distribute this
      8  * software and its documentation for any purpose, provided that the
      9  * above copyright notice and the following two paragraphs appear in
     10  * all copies of this software.
     11  *
     12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     16  * DAMAGE.
     17  *
     18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     23  */
     24 
     25 #include "harfbuzz-shaper.h"
     26 #include "harfbuzz-shaper-private.h"
     27 #include "harfbuzz-external.h"
     28 
     29 #include <assert.h>
     30 #include <stdio.h>
     31 
     32 typedef int (*th_brk_def)(const char*, int[], int);
     33 static th_brk_def th_brk = 0;
     34 static int libthai_resolved = 0;
     35 
     36 static void resolve_libthai()
     37 {
     38     if (!th_brk)
     39         th_brk = (th_brk_def)HB_Library_Resolve("thai", 0, "th_brk");
     40     libthai_resolved = 1;
     41 }
     42 
     43 static void to_tis620(const HB_UChar16 *string, hb_uint32 len, const char *cstr)
     44 {
     45     hb_uint32 i;
     46     unsigned char *result = (unsigned char *)cstr;
     47 
     48     for (i = 0; i < len; ++i) {
     49         if (string[i] <= 0xa0)
     50             result[i] = (unsigned char)string[i];
     51         if (string[i] >= 0xe01 && string[i] <= 0xe5b)
     52             result[i] = (unsigned char)(string[i] - 0xe00 + 0xa0);
     53         else
     54             result[i] = '?';
     55     }
     56 
     57     result[len] = 0;
     58 }
     59 
     60 static void thaiWordBreaks(const HB_UChar16 *string, hb_uint32 len, HB_CharAttributes *attributes)
     61 {
     62     char s[128];
     63     char *cstr = s;
     64     int brp[128];
     65     int *break_positions = brp;
     66     hb_uint32 numbreaks;
     67     hb_uint32 i;
     68 
     69     if (!libthai_resolved)
     70         resolve_libthai();
     71 
     72     if (!th_brk)
     73         return;
     74 
     75     if (len >= 128)
     76         cstr = (char *)malloc(len*sizeof(char) + 1);
     77 
     78     to_tis620(string, len, cstr);
     79 
     80     numbreaks = th_brk(cstr, break_positions, 128);
     81     if (numbreaks > 128) {
     82         break_positions = (int *)malloc(numbreaks * sizeof(int));
     83         numbreaks = th_brk(cstr, break_positions, numbreaks);
     84     }
     85 
     86     for (i = 0; i < len; ++i) {
     87         attributes[i].lineBreakType = HB_NoBreak;
     88         attributes[i].wordBoundary = FALSE;
     89     }
     90 
     91     for (i = 0; i < numbreaks; ++i) {
     92         if (break_positions[i] > 0) {
     93             attributes[break_positions[i]-1].lineBreakType = HB_Break;
     94             attributes[i].wordBoundary = TRUE;
     95         }
     96     }
     97 
     98     if (break_positions != brp)
     99         free(break_positions);
    100 
    101     if (len >= 128)
    102         free(cstr);
    103 }
    104 
    105 void HB_ThaiAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
    106 {
    107     assert(script == HB_Script_Thai);
    108     attributes += from;
    109     thaiWordBreaks(text + from, len, attributes);
    110 }
    111 
    112