15569331642446be05292e3e1f8a51218827168cdclaireho/*
25569331642446be05292e3e1f8a51218827168cdclaireho * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
35569331642446be05292e3e1f8a51218827168cdclaireho *
45569331642446be05292e3e1f8a51218827168cdclaireho * This is part of HarfBuzz, an OpenType Layout engine library.
55569331642446be05292e3e1f8a51218827168cdclaireho *
65569331642446be05292e3e1f8a51218827168cdclaireho * Permission is hereby granted, without written agreement and without
75569331642446be05292e3e1f8a51218827168cdclaireho * license or royalty fees, to use, copy, modify, and distribute this
85569331642446be05292e3e1f8a51218827168cdclaireho * software and its documentation for any purpose, provided that the
95569331642446be05292e3e1f8a51218827168cdclaireho * above copyright notice and the following two paragraphs appear in
105569331642446be05292e3e1f8a51218827168cdclaireho * all copies of this software.
115569331642446be05292e3e1f8a51218827168cdclaireho *
125569331642446be05292e3e1f8a51218827168cdclaireho * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
135569331642446be05292e3e1f8a51218827168cdclaireho * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
145569331642446be05292e3e1f8a51218827168cdclaireho * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
155569331642446be05292e3e1f8a51218827168cdclaireho * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
165569331642446be05292e3e1f8a51218827168cdclaireho * DAMAGE.
175569331642446be05292e3e1f8a51218827168cdclaireho *
185569331642446be05292e3e1f8a51218827168cdclaireho * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
195569331642446be05292e3e1f8a51218827168cdclaireho * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
205569331642446be05292e3e1f8a51218827168cdclaireho * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
215569331642446be05292e3e1f8a51218827168cdclaireho * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
225569331642446be05292e3e1f8a51218827168cdclaireho * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
235569331642446be05292e3e1f8a51218827168cdclaireho */
245569331642446be05292e3e1f8a51218827168cdclaireho
255569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-shaper.h"
265569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-shaper-private.h"
275569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-external.h"
285569331642446be05292e3e1f8a51218827168cdclaireho
295569331642446be05292e3e1f8a51218827168cdclaireho#include <assert.h>
3057e6107a9d66a9a97b146def0ef38c010f954be6claireho#include <stdio.h>
3157e6107a9d66a9a97b146def0ef38c010f954be6claireho
3257e6107a9d66a9a97b146def0ef38c010f954be6clairehotypedef int (*th_brk_def)(const char*, int[], int);
3357e6107a9d66a9a97b146def0ef38c010f954be6clairehostatic th_brk_def th_brk = 0;
3457e6107a9d66a9a97b146def0ef38c010f954be6clairehostatic int libthai_resolved = 0;
3557e6107a9d66a9a97b146def0ef38c010f954be6claireho
3657e6107a9d66a9a97b146def0ef38c010f954be6clairehostatic void resolve_libthai()
3757e6107a9d66a9a97b146def0ef38c010f954be6claireho{
3857e6107a9d66a9a97b146def0ef38c010f954be6claireho    if (!th_brk)
3957e6107a9d66a9a97b146def0ef38c010f954be6claireho        th_brk = (th_brk_def)HB_Library_Resolve("thai", 0, "th_brk");
4057e6107a9d66a9a97b146def0ef38c010f954be6claireho    libthai_resolved = 1;
4157e6107a9d66a9a97b146def0ef38c010f954be6claireho}
4257e6107a9d66a9a97b146def0ef38c010f954be6claireho
4357e6107a9d66a9a97b146def0ef38c010f954be6clairehostatic void to_tis620(const HB_UChar16 *string, hb_uint32 len, const char *cstr)
4457e6107a9d66a9a97b146def0ef38c010f954be6claireho{
4557e6107a9d66a9a97b146def0ef38c010f954be6claireho    hb_uint32 i;
4657e6107a9d66a9a97b146def0ef38c010f954be6claireho    unsigned char *result = (unsigned char *)cstr;
4757e6107a9d66a9a97b146def0ef38c010f954be6claireho
4857e6107a9d66a9a97b146def0ef38c010f954be6claireho    for (i = 0; i < len; ++i) {
4957e6107a9d66a9a97b146def0ef38c010f954be6claireho        if (string[i] <= 0xa0)
5057e6107a9d66a9a97b146def0ef38c010f954be6claireho            result[i] = (unsigned char)string[i];
5157e6107a9d66a9a97b146def0ef38c010f954be6claireho        if (string[i] >= 0xe01 && string[i] <= 0xe5b)
5257e6107a9d66a9a97b146def0ef38c010f954be6claireho            result[i] = (unsigned char)(string[i] - 0xe00 + 0xa0);
5357e6107a9d66a9a97b146def0ef38c010f954be6claireho        else
5457e6107a9d66a9a97b146def0ef38c010f954be6claireho            result[i] = '?';
5557e6107a9d66a9a97b146def0ef38c010f954be6claireho    }
5657e6107a9d66a9a97b146def0ef38c010f954be6claireho
5757e6107a9d66a9a97b146def0ef38c010f954be6claireho    result[len] = 0;
5857e6107a9d66a9a97b146def0ef38c010f954be6claireho}
595569331642446be05292e3e1f8a51218827168cdclaireho
605569331642446be05292e3e1f8a51218827168cdclairehostatic void thaiWordBreaks(const HB_UChar16 *string, hb_uint32 len, HB_CharAttributes *attributes)
615569331642446be05292e3e1f8a51218827168cdclaireho{
6257e6107a9d66a9a97b146def0ef38c010f954be6claireho    char s[128];
6357e6107a9d66a9a97b146def0ef38c010f954be6claireho    char *cstr = s;
645569331642446be05292e3e1f8a51218827168cdclaireho    int brp[128];
655569331642446be05292e3e1f8a51218827168cdclaireho    int *break_positions = brp;
665569331642446be05292e3e1f8a51218827168cdclaireho    hb_uint32 numbreaks;
675569331642446be05292e3e1f8a51218827168cdclaireho    hb_uint32 i;
685569331642446be05292e3e1f8a51218827168cdclaireho
6957e6107a9d66a9a97b146def0ef38c010f954be6claireho    if (!libthai_resolved)
7057e6107a9d66a9a97b146def0ef38c010f954be6claireho        resolve_libthai();
715569331642446be05292e3e1f8a51218827168cdclaireho
725569331642446be05292e3e1f8a51218827168cdclaireho    if (!th_brk)
735569331642446be05292e3e1f8a51218827168cdclaireho        return;
745569331642446be05292e3e1f8a51218827168cdclaireho
7557e6107a9d66a9a97b146def0ef38c010f954be6claireho    if (len >= 128)
7657e6107a9d66a9a97b146def0ef38c010f954be6claireho        cstr = (char *)malloc(len*sizeof(char) + 1);
7757e6107a9d66a9a97b146def0ef38c010f954be6claireho
7857e6107a9d66a9a97b146def0ef38c010f954be6claireho    to_tis620(string, len, cstr);
795569331642446be05292e3e1f8a51218827168cdclaireho
805569331642446be05292e3e1f8a51218827168cdclaireho    numbreaks = th_brk(cstr, break_positions, 128);
815569331642446be05292e3e1f8a51218827168cdclaireho    if (numbreaks > 128) {
825569331642446be05292e3e1f8a51218827168cdclaireho        break_positions = (int *)malloc(numbreaks * sizeof(int));
835569331642446be05292e3e1f8a51218827168cdclaireho        numbreaks = th_brk(cstr, break_positions, numbreaks);
845569331642446be05292e3e1f8a51218827168cdclaireho    }
855569331642446be05292e3e1f8a51218827168cdclaireho
8657e6107a9d66a9a97b146def0ef38c010f954be6claireho    for (i = 0; i < len; ++i) {
875569331642446be05292e3e1f8a51218827168cdclaireho        attributes[i].lineBreakType = HB_NoBreak;
8857e6107a9d66a9a97b146def0ef38c010f954be6claireho        attributes[i].wordBoundary = FALSE;
8957e6107a9d66a9a97b146def0ef38c010f954be6claireho    }
905569331642446be05292e3e1f8a51218827168cdclaireho
915569331642446be05292e3e1f8a51218827168cdclaireho    for (i = 0; i < numbreaks; ++i) {
9257e6107a9d66a9a97b146def0ef38c010f954be6claireho        if (break_positions[i] > 0) {
935569331642446be05292e3e1f8a51218827168cdclaireho            attributes[break_positions[i]-1].lineBreakType = HB_Break;
945b51d0c851af1852ecc7562790cbbbee156c2c44claireho            attributes[break_positions[i]-1].wordBoundary = TRUE;
9557e6107a9d66a9a97b146def0ef38c010f954be6claireho        }
965569331642446be05292e3e1f8a51218827168cdclaireho    }
975569331642446be05292e3e1f8a51218827168cdclaireho
985569331642446be05292e3e1f8a51218827168cdclaireho    if (break_positions != brp)
995569331642446be05292e3e1f8a51218827168cdclaireho        free(break_positions);
1005569331642446be05292e3e1f8a51218827168cdclaireho
10157e6107a9d66a9a97b146def0ef38c010f954be6claireho    if (len >= 128)
10257e6107a9d66a9a97b146def0ef38c010f954be6claireho        free(cstr);
1035569331642446be05292e3e1f8a51218827168cdclaireho}
1045569331642446be05292e3e1f8a51218827168cdclaireho
1055569331642446be05292e3e1f8a51218827168cdclairehovoid HB_ThaiAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
1065569331642446be05292e3e1f8a51218827168cdclaireho{
1075569331642446be05292e3e1f8a51218827168cdclaireho    assert(script == HB_Script_Thai);
1085569331642446be05292e3e1f8a51218827168cdclaireho    attributes += from;
1095569331642446be05292e3e1f8a51218827168cdclaireho    thaiWordBreaks(text + from, len, attributes);
1105569331642446be05292e3e1f8a51218827168cdclaireho}
1115569331642446be05292e3e1f8a51218827168cdclaireho
112