/* * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * This is part of HarfBuzz, an OpenType Layout engine library. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ #include "harfbuzz-shaper.h" #include "harfbuzz-shaper-private.h" #include "harfbuzz-external.h" #include #include typedef int (*th_brk_def)(const char*, int[], int); static th_brk_def th_brk = 0; static int libthai_resolved = 0; static void resolve_libthai() { if (!th_brk) th_brk = (th_brk_def)HB_Library_Resolve("thai", 0, "th_brk"); libthai_resolved = 1; } static void to_tis620(const HB_UChar16 *string, hb_uint32 len, const char *cstr) { hb_uint32 i; unsigned char *result = (unsigned char *)cstr; for (i = 0; i < len; ++i) { if (string[i] <= 0xa0) result[i] = (unsigned char)string[i]; if (string[i] >= 0xe01 && string[i] <= 0xe5b) result[i] = (unsigned char)(string[i] - 0xe00 + 0xa0); else result[i] = '?'; } result[len] = 0; } static void thaiWordBreaks(const HB_UChar16 *string, hb_uint32 len, HB_CharAttributes *attributes) { char s[128]; char *cstr = s; int brp[128]; int *break_positions = brp; hb_uint32 numbreaks; hb_uint32 i; if (!libthai_resolved) resolve_libthai(); if (!th_brk) return; if (len >= 128) cstr = (char *)malloc(len*sizeof(char) + 1); to_tis620(string, len, cstr); numbreaks = th_brk(cstr, break_positions, 128); if (numbreaks > 128) { break_positions = (int *)malloc(numbreaks * sizeof(int)); numbreaks = th_brk(cstr, break_positions, numbreaks); } for (i = 0; i < len; ++i) { attributes[i].lineBreakType = HB_NoBreak; attributes[i].wordBoundary = FALSE; } for (i = 0; i < numbreaks; ++i) { if (break_positions[i] > 0) { attributes[break_positions[i]-1].lineBreakType = HB_Break; attributes[break_positions[i]-1].wordBoundary = TRUE; } } if (break_positions != brp) free(break_positions); if (len >= 128) free(cstr); } void HB_ThaiAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes) { assert(script == HB_Script_Thai); attributes += from; thaiWordBreaks(text + from, len, attributes); }