Index: third_party/harfbuzz/src/harfbuzz-indic.cpp |
diff --git a/third_party/harfbuzz/src/harfbuzz-indic.cpp b/third_party/harfbuzz/src/harfbuzz-indic.cpp |
deleted file mode 100644 |
index 3c9df93787e31bbd5aacd0b107d3099f906b325e..0000000000000000000000000000000000000000 |
--- a/third_party/harfbuzz/src/harfbuzz-indic.cpp |
+++ /dev/null |
@@ -1,1873 +0,0 @@ |
-/* |
- * 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 <assert.h> |
-#include <stdio.h> |
- |
-#define FLAG(x) (1 << (x)) |
- |
-static HB_Bool isLetter(HB_UChar16 ucs) |
-{ |
- const int test = FLAG(HB_Letter_Uppercase) | |
- FLAG(HB_Letter_Lowercase) | |
- FLAG(HB_Letter_Titlecase) | |
- FLAG(HB_Letter_Modifier) | |
- FLAG(HB_Letter_Other); |
- return FLAG(HB_GetUnicodeCharCategory(ucs)) & test; |
-} |
- |
-static HB_Bool isMark(HB_UChar16 ucs) |
-{ |
- const int test = FLAG(HB_Mark_NonSpacing) | |
- FLAG(HB_Mark_SpacingCombining) | |
- FLAG(HB_Mark_Enclosing); |
- return FLAG(HB_GetUnicodeCharCategory(ucs)) & test; |
-} |
- |
-enum Form { |
- Invalid = 0x0, |
- UnknownForm = Invalid, |
- Consonant, |
- Nukta, |
- Halant, |
- Matra, |
- VowelMark, |
- StressMark, |
- IndependentVowel, |
- LengthMark, |
- Control, |
- Other |
-}; |
- |
-static const unsigned char indicForms[0xe00-0x900] = { |
- // Devangari |
- Invalid, VowelMark, VowelMark, VowelMark, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Nukta, Other, Matra, Matra, |
- |
- Matra, Matra, Matra, Matra, |
- Matra, Matra, Matra, Matra, |
- Matra, Matra, Matra, Matra, |
- Matra, Halant, UnknownForm, UnknownForm, |
- |
- Other, StressMark, StressMark, StressMark, |
- StressMark, UnknownForm, UnknownForm, UnknownForm, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- IndependentVowel, IndependentVowel, VowelMark, VowelMark, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Consonant, |
- Consonant, Consonant /* ??? */, Consonant, Consonant, |
- |
- // Bengali |
- Invalid, VowelMark, VowelMark, VowelMark, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, Invalid, Invalid, IndependentVowel, |
- |
- IndependentVowel, Invalid, Invalid, IndependentVowel, |
- IndependentVowel, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Invalid, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Invalid, Consonant, Invalid, |
- Invalid, Invalid, Consonant, Consonant, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Nukta, Other, Matra, Matra, |
- |
- Matra, Matra, Matra, Matra, |
- Matra, Invalid, Invalid, Matra, |
- Matra, Invalid, Invalid, Matra, |
- Matra, Halant, Consonant, UnknownForm, |
- |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, VowelMark, |
- Invalid, Invalid, Invalid, Invalid, |
- Consonant, Consonant, Invalid, Consonant, |
- |
- IndependentVowel, IndependentVowel, VowelMark, VowelMark, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- Consonant, Consonant, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- // Gurmukhi |
- Invalid, VowelMark, VowelMark, VowelMark, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, Invalid, |
- Invalid, Invalid, Invalid, IndependentVowel, |
- |
- IndependentVowel, Invalid, Invalid, IndependentVowel, |
- IndependentVowel, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Invalid, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Invalid, Consonant, Consonant, |
- Invalid, Consonant, Consonant, Invalid, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Nukta, Other, Matra, Matra, |
- |
- Matra, Matra, Matra, Invalid, |
- Invalid, Invalid, Invalid, Matra, |
- Matra, Invalid, Invalid, Matra, |
- Matra, Halant, UnknownForm, UnknownForm, |
- |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, UnknownForm, UnknownForm, UnknownForm, |
- Invalid, Consonant, Consonant, Consonant, |
- Consonant, Invalid, Consonant, Invalid, |
- |
- Other, Other, Invalid, Invalid, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- StressMark, StressMark, Consonant, Consonant, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- // Gujarati |
- Invalid, VowelMark, VowelMark, VowelMark, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, Invalid, IndependentVowel, |
- |
- IndependentVowel, IndependentVowel, Invalid, IndependentVowel, |
- IndependentVowel, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Invalid, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Invalid, Consonant, Consonant, |
- Invalid, Consonant, Consonant, Consonant, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Nukta, Other, Matra, Matra, |
- |
- Matra, Matra, Matra, Matra, |
- Matra, Matra, Invalid, Matra, |
- Matra, Matra, Invalid, Matra, |
- Matra, Halant, UnknownForm, UnknownForm, |
- |
- Other, UnknownForm, UnknownForm, UnknownForm, |
- UnknownForm, UnknownForm, UnknownForm, UnknownForm, |
- UnknownForm, UnknownForm, UnknownForm, UnknownForm, |
- UnknownForm, UnknownForm, UnknownForm, UnknownForm, |
- |
- IndependentVowel, IndependentVowel, VowelMark, VowelMark, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- // Oriya |
- Invalid, VowelMark, VowelMark, VowelMark, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, Invalid, Invalid, IndependentVowel, |
- |
- IndependentVowel, Invalid, Invalid, IndependentVowel, |
- IndependentVowel, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Invalid, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Invalid, Consonant, Consonant, |
- Invalid, Consonant, Consonant, Consonant, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Nukta, Other, Matra, Matra, |
- |
- Matra, Matra, Matra, Matra, |
- Invalid, Invalid, Invalid, Matra, |
- Matra, Invalid, Invalid, Matra, |
- Matra, Halant, UnknownForm, UnknownForm, |
- |
- Other, Invalid, Invalid, Invalid, |
- Invalid, UnknownForm, LengthMark, LengthMark, |
- Invalid, Invalid, Invalid, Invalid, |
- Consonant, Consonant, Invalid, Consonant, |
- |
- IndependentVowel, IndependentVowel, Invalid, Invalid, |
- Invalid, Invalid, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- Other, Consonant, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- //Tamil |
- Invalid, Invalid, VowelMark, Other, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, Invalid, |
- Invalid, Invalid, IndependentVowel, IndependentVowel, |
- |
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel, |
- IndependentVowel, Consonant, Invalid, Invalid, |
- Invalid, Consonant, Consonant, Invalid, |
- Consonant, Invalid, Consonant, Consonant, |
- |
- Invalid, Invalid, Invalid, Consonant, |
- Consonant, Invalid, Invalid, Invalid, |
- Consonant, Consonant, Consonant, Invalid, |
- Invalid, Invalid, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Invalid, Invalid, Matra, Matra, |
- |
- Matra, Matra, Matra, Invalid, |
- Invalid, Invalid, Matra, Matra, |
- Matra, Invalid, Matra, Matra, |
- Matra, Halant, Invalid, Invalid, |
- |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, LengthMark, |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, Invalid, |
- |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- // Telugu |
- Invalid, VowelMark, VowelMark, VowelMark, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel, |
- |
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel, |
- IndependentVowel, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Invalid, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Invalid, Consonant, Consonant, Consonant, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Invalid, Invalid, Matra, Matra, |
- |
- Matra, Matra, Matra, Matra, |
- Matra, Invalid, Matra, Matra, |
- Matra, Invalid, Matra, Matra, |
- Matra, Halant, Invalid, Invalid, |
- |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, LengthMark, Matra, Invalid, |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, Invalid, |
- |
- IndependentVowel, IndependentVowel, Invalid, Invalid, |
- Invalid, Invalid, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- // Kannada |
- Invalid, Invalid, VowelMark, VowelMark, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel, |
- |
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel, |
- IndependentVowel, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Invalid, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Invalid, Consonant, Consonant, Consonant, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Nukta, Other, Matra, Matra, |
- |
- Matra, Matra, Matra, Matra, |
- Matra, Invalid, Matra, Matra, |
- Matra, Invalid, Matra, Matra, |
- Matra, Halant, Invalid, Invalid, |
- |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, LengthMark, LengthMark, Invalid, |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Consonant, Invalid, |
- |
- IndependentVowel, IndependentVowel, VowelMark, VowelMark, |
- Invalid, Invalid, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- // Malayalam |
- Invalid, Invalid, VowelMark, VowelMark, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel, |
- |
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel, |
- IndependentVowel, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Invalid, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, UnknownForm, UnknownForm, |
- Invalid, Invalid, Matra, Matra, |
- |
- Matra, Matra, Matra, Matra, |
- Invalid, Invalid, Matra, Matra, |
- Matra, Invalid, Matra, Matra, |
- Matra, Halant, Invalid, Invalid, |
- |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, Matra, |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, Invalid, |
- |
- IndependentVowel, IndependentVowel, Invalid, Invalid, |
- Invalid, Invalid, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- |
- // Sinhala |
- Invalid, Invalid, VowelMark, VowelMark, |
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- |
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel, |
- IndependentVowel, IndependentVowel, IndependentVowel, Invalid, |
- Invalid, Invalid, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- |
- Consonant, Consonant, Invalid, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Consonant, |
- Invalid, Consonant, Invalid, Invalid, |
- |
- Consonant, Consonant, Consonant, Consonant, |
- Consonant, Consonant, Consonant, Invalid, |
- Invalid, Invalid, Halant, Invalid, |
- Invalid, Invalid, Invalid, Matra, |
- |
- Matra, Matra, Matra, Matra, |
- Matra, Invalid, Matra, Invalid, |
- Matra, Matra, Matra, Matra, |
- Matra, Matra, Matra, Matra, |
- |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, Invalid, |
- Invalid, Invalid, Invalid, Invalid, |
- |
- Invalid, Invalid, Matra, Matra, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
- Other, Other, Other, Other, |
-}; |
- |
-enum Position { |
- None, |
- Pre, |
- Above, |
- Below, |
- Post, |
- Split, |
- Base, |
- Reph, |
- Vattu, |
- Inherit |
-}; |
- |
-static const unsigned char indicPosition[0xe00-0x900] = { |
- // Devanagari |
- None, Above, Above, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- Below, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, Post, Pre, |
- |
- Post, Below, Below, Below, |
- Below, Above, Above, Above, |
- Above, Post, Post, Post, |
- Post, None, None, None, |
- |
- None, Above, Below, Above, |
- Above, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, Below, Below, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Bengali |
- None, Above, Post, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- Below, None, None, Post, |
- |
- Below, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- Below, None, Post, Pre, |
- |
- Post, Below, Below, Below, |
- Below, None, None, Pre, |
- Pre, None, None, Split, |
- Split, Below, None, None, |
- |
- None, None, None, None, |
- None, None, None, Post, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, Below, Below, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- Below, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Gurmukhi |
- None, Above, Above, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, Post, |
- |
- Below, None, None, None, |
- None, Below, None, None, |
- None, Below, None, None, |
- Below, None, Post, Pre, |
- |
- Post, Below, Below, None, |
- None, None, None, Above, |
- Above, None, None, Above, |
- Above, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- Above, Above, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Gujarati |
- None, Above, Above, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- Below, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, Post, Pre, |
- |
- Post, Below, Below, Below, |
- Below, Above, None, Above, |
- Above, Post, None, Post, |
- Post, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, Below, Below, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Oriya |
- None, Above, Post, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- Below, None, None, None, |
- Below, None, None, None, |
- Below, Below, Below, Post, |
- |
- Below, None, Below, Below, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, Post, Above, |
- |
- Post, Below, Below, Below, |
- None, None, None, Pre, |
- Split, None, None, Split, |
- Split, None, None, None, |
- |
- None, None, None, None, |
- None, None, Above, Post, |
- None, None, None, None, |
- None, None, None, Post, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, Below, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Tamil |
- None, None, Above, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, Post, Post, |
- |
- Above, Below, Below, None, |
- None, None, Pre, Pre, |
- Pre, None, Split, Split, |
- Split, Halant, None, None, |
- |
- None, None, None, None, |
- None, None, None, Post, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Telugu |
- None, Post, Post, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, Below, Below, Below, |
- Below, Below, Below, Below, |
- Below, Below, Below, Below, |
- |
- Below, Below, Below, Below, |
- Below, Below, Below, Below, |
- Below, None, Below, Below, |
- Below, Below, Below, Below, |
- |
- Below, None, Below, Below, |
- None, Below, Below, Below, |
- Below, Below, None, None, |
- None, None, Post, Above, |
- |
- Above, Post, Post, Post, |
- Post, None, Above, Above, |
- Split, None, Post, Above, |
- Above, Halant, None, None, |
- |
- None, None, None, None, |
- None, Above, Below, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Kannada |
- None, None, Post, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, Below, Below, Below, |
- Below, Below, Below, Below, |
- Below, Below, Below, Below, |
- |
- Below, Below, Below, Below, |
- Below, Below, Below, Below, |
- Below, Below, Below, Below, |
- Below, Below, Below, Below, |
- |
- Below, None, Below, Below, |
- None, Below, Below, Below, |
- Below, Below, None, None, |
- None, None, Post, Above, |
- |
- Split, Post, Post, Post, |
- Post, None, Above, Split, |
- Split, None, Split, Split, |
- Above, Halant, None, None, |
- |
- None, None, None, None, |
- None, Post, Post, None, |
- None, None, None, None, |
- None, None, Below, None, |
- |
- None, None, Below, Below, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Malayalam |
- None, None, Post, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, Post, |
- |
- Post, None, Below, None, |
- None, Post, None, None, |
- None, None, None, None, |
- None, None, Post, Post, |
- |
- Post, Post, Post, Post, |
- None, None, Pre, Pre, |
- Pre, None, Split, Split, |
- Split, Halant, None, None, |
- |
- None, None, None, None, |
- None, None, None, Post, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- // Sinhala |
- None, None, Post, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, Post, |
- |
- Post, Post, Above, Above, |
- Below, None, Below, None, |
- Post, Pre, Split, Pre, |
- Split, Split, Split, Post, |
- |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None, |
- |
- None, None, Post, Post, |
- None, None, None, None, |
- None, None, None, None, |
- None, None, None, None |
-}; |
- |
-static inline Form form(unsigned short uc) { |
- if (uc < 0x900 || uc > 0xdff) { |
- if (uc == 0x25cc) |
- return Consonant; |
- if (uc == 0x200c || uc == 0x200d) |
- return Control; |
- return Other; |
- } |
- return (Form)indicForms[uc-0x900]; |
-} |
- |
-static inline Position indic_position(unsigned short uc) { |
- if (uc < 0x900 || uc > 0xdff) |
- return None; |
- return (Position) indicPosition[uc-0x900]; |
-} |
- |
- |
-enum IndicScriptProperties { |
- HasReph = 0x01, |
- HasSplit = 0x02 |
-}; |
- |
-const hb_uint8 scriptProperties[10] = { |
- // Devanagari, |
- HasReph, |
- // Bengali, |
- HasReph|HasSplit, |
- // Gurmukhi, |
- 0, |
- // Gujarati, |
- HasReph, |
- // Oriya, |
- HasReph|HasSplit, |
- // Tamil, |
- HasSplit, |
- // Telugu, |
- HasSplit, |
- // Kannada, |
- HasSplit|HasReph, |
- // Malayalam, |
- HasSplit, |
- // Sinhala, |
- HasSplit |
-}; |
- |
-struct IndicOrdering { |
- Form form; |
- Position position; |
-}; |
- |
-static const IndicOrdering devanagari_order [] = { |
- { Consonant, Below }, |
- { Matra, Below }, |
- { VowelMark, Below }, |
- { StressMark, Below }, |
- { Matra, Above }, |
- { Matra, Post }, |
- { Consonant, Reph }, |
- { VowelMark, Above }, |
- { StressMark, Above }, |
- { VowelMark, Post }, |
- { (Form)0, None } |
-}; |
- |
-static const IndicOrdering bengali_order [] = { |
- { Consonant, Below }, |
- { Matra, Below }, |
- { Matra, Above }, |
- { Consonant, Reph }, |
- { VowelMark, Above }, |
- { Consonant, Post }, |
- { Matra, Post }, |
- { VowelMark, Post }, |
- { (Form)0, None } |
-}; |
- |
-static const IndicOrdering gurmukhi_order [] = { |
- { Consonant, Below }, |
- { Matra, Below }, |
- { Matra, Above }, |
- { Consonant, Post }, |
- { Matra, Post }, |
- { VowelMark, Above }, |
- { (Form)0, None } |
-}; |
- |
-static const IndicOrdering tamil_order [] = { |
- { Matra, Above }, |
- { Matra, Post }, |
- { VowelMark, Post }, |
- { (Form)0, None } |
-}; |
- |
-static const IndicOrdering telugu_order [] = { |
- { Matra, Above }, |
- { Matra, Below }, |
- { Matra, Post }, |
- { Consonant, Below }, |
- { Consonant, Post }, |
- { VowelMark, Post }, |
- { (Form)0, None } |
-}; |
- |
-static const IndicOrdering kannada_order [] = { |
- { Matra, Above }, |
- { Matra, Post }, |
- { Consonant, Below }, |
- { Consonant, Post }, |
- { LengthMark, Post }, |
- { Consonant, Reph }, |
- { VowelMark, Post }, |
- { (Form)0, None } |
-}; |
- |
-static const IndicOrdering malayalam_order [] = { |
- { Consonant, Below }, |
- { Matra, Below }, |
- { Consonant, Reph }, |
- { Consonant, Post }, |
- { Matra, Post }, |
- { VowelMark, Post }, |
- { (Form)0, None } |
-}; |
- |
-static const IndicOrdering sinhala_order [] = { |
- { Matra, Below }, |
- { Matra, Above }, |
- { Matra, Post }, |
- { VowelMark, Post }, |
- { (Form)0, None } |
-}; |
- |
-static const IndicOrdering * const indic_order[] = { |
- devanagari_order, // Devanagari |
- bengali_order, // Bengali |
- gurmukhi_order, // Gurmukhi |
- devanagari_order, // Gujarati |
- bengali_order, // Oriya |
- tamil_order, // Tamil |
- telugu_order, // Telugu |
- kannada_order, // Kannada |
- malayalam_order, // Malayalam |
- sinhala_order // Sinhala |
-}; |
- |
- |
- |
-// vowel matras that have to be split into two parts. |
-static const unsigned short split_matras[] = { |
- // matra, split1, split2, split3 |
- |
- // bengalis |
- 0x9cb, 0x9c7, 0x9be, 0x0, |
- 0x9cc, 0x9c7, 0x9d7, 0x0, |
- // oriya |
- 0xb48, 0xb47, 0xb56, 0x0, |
- 0xb4b, 0xb47, 0xb3e, 0x0, |
- 0xb4c, 0xb47, 0xb57, 0x0, |
- // tamil |
- 0xbca, 0xbc6, 0xbbe, 0x0, |
- 0xbcb, 0xbc7, 0xbbe, 0x0, |
- 0xbcc, 0xbc6, 0xbd7, 0x0, |
- // telugu |
- 0xc48, 0xc46, 0xc56, 0x0, |
- // kannada |
- 0xcc0, 0xcbf, 0xcd5, 0x0, |
- 0xcc7, 0xcc6, 0xcd5, 0x0, |
- 0xcc8, 0xcc6, 0xcd6, 0x0, |
- 0xcca, 0xcc6, 0xcc2, 0x0, |
- 0xccb, 0xcc6, 0xcc2, 0xcd5, |
- // malayalam |
- 0xd4a, 0xd46, 0xd3e, 0x0, |
- 0xd4b, 0xd47, 0xd3e, 0x0, |
- 0xd4c, 0xd46, 0xd57, 0x0, |
- // sinhala |
- 0xdda, 0xdd9, 0xdca, 0x0, |
- 0xddc, 0xdd9, 0xdcf, 0x0, |
- 0xddd, 0xdd9, 0xdcf, 0xdca, |
- 0xdde, 0xdd9, 0xddf, 0x0, |
- 0xffff |
-}; |
- |
-static inline void splitMatra(unsigned short *reordered, int matra, int &len) |
-{ |
- unsigned short matra_uc = reordered[matra]; |
- //qDebug("matra=%d, reordered[matra]=%x", matra, reordered[matra]); |
- |
- const unsigned short *split = split_matras; |
- while (split[0] < matra_uc) |
- split += 4; |
- |
- assert(*split == matra_uc); |
- ++split; |
- |
- int added_chars = split[2] == 0x0 ? 1 : 2; |
- |
- memmove(reordered + matra + added_chars, reordered + matra, (len-matra)*sizeof(unsigned short)); |
- reordered[matra] = split[0]; |
- reordered[matra+1] = split[1]; |
- if(added_chars == 2) |
- reordered[matra+2] = split[2]; |
- len += added_chars; |
-} |
- |
-#ifndef NO_OPENTYPE |
-static const HB_OpenTypeFeature indic_features[] = { |
- { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, |
- { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty }, |
- { HB_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty }, |
- { HB_MAKE_TAG('a', 'k', 'h', 'n'), AkhantProperty }, |
- { HB_MAKE_TAG('r', 'p', 'h', 'f'), RephProperty }, |
- { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty }, |
- { HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty }, |
- { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty }, |
- { HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty }, |
- { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty }, |
- { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty }, |
- { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty }, |
- { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty }, |
- { HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty }, |
- { 0, 0 } |
-}; |
-#endif |
- |
-// #define INDIC_DEBUG |
-#ifdef INDIC_DEBUG |
-#define IDEBUG hb_debug |
-#include <stdarg.h> |
- |
-static void hb_debug(const char *msg, ...) |
-{ |
- va_list ap; |
- va_start(ap, msg); // use variable arg list |
- vfprintf(stderr, msg, ap); |
- va_end(ap); |
- fprintf(stderr, "\n"); |
-} |
- |
-#else |
-#define IDEBUG if(0) printf |
-#endif |
- |
-#if 0 //def INDIC_DEBUG |
-static QString propertiesToString(int properties) |
-{ |
- QString res; |
- properties = ~properties; |
- if (properties & CcmpProperty) |
- res += "Ccmp "; |
- if (properties & InitProperty) |
- res += "Init "; |
- if (properties & NuktaProperty) |
- res += "Nukta "; |
- if (properties & AkhantProperty) |
- res += "Akhant "; |
- if (properties & RephProperty) |
- res += "Reph "; |
- if (properties & PreFormProperty) |
- res += "PreForm "; |
- if (properties & BelowFormProperty) |
- res += "BelowForm "; |
- if (properties & AboveFormProperty) |
- res += "AboveForm "; |
- if (properties & HalfFormProperty) |
- res += "HalfForm "; |
- if (properties & PostFormProperty) |
- res += "PostForm "; |
- if (properties & VattuProperty) |
- res += "Vattu "; |
- if (properties & PreSubstProperty) |
- res += "PreSubst "; |
- if (properties & BelowSubstProperty) |
- res += "BelowSubst "; |
- if (properties & AboveSubstProperty) |
- res += "AboveSubst "; |
- if (properties & PostSubstProperty) |
- res += "PostSubst "; |
- if (properties & HalantProperty) |
- res += "Halant "; |
- if (properties & CligProperty) |
- res += "Clig "; |
- return res; |
-} |
-#endif |
- |
-static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool invalid) |
-{ |
- HB_Script script = item->item.script; |
- assert(script >= HB_Script_Devanagari && script <= HB_Script_Sinhala); |
- const unsigned short script_base = 0x0900 + 0x80*(script-HB_Script_Devanagari); |
- const unsigned short ra = script_base + 0x30; |
- const unsigned short halant = script_base + 0x4d; |
- const unsigned short nukta = script_base + 0x3c; |
- bool control = false; |
- |
- int len = (int)item->item.length; |
- IDEBUG(">>>>> indic shape: from=%d, len=%d invalid=%d", item->item.pos, item->item.length, invalid); |
- |
- if ((int)item->num_glyphs < len+4) { |
- item->num_glyphs = len+4; |
- return false; |
- } |
- |
- HB_STACKARRAY(HB_UChar16, reordered, len + 4); |
- HB_STACKARRAY(hb_uint8, position, len + 4); |
- |
- unsigned char properties = scriptProperties[script-HB_Script_Devanagari]; |
- |
- if (invalid) { |
- *reordered = 0x25cc; |
- memcpy(reordered+1, item->string + item->item.pos, len*sizeof(HB_UChar16)); |
- len++; |
- } else { |
- memcpy(reordered, item->string + item->item.pos, len*sizeof(HB_UChar16)); |
- } |
- if (reordered[len-1] == 0x200c) // zero width non joiner |
- len--; |
- |
- int i; |
- int base = 0; |
- int reph = -1; |
- |
-#ifdef INDIC_DEBUG |
- IDEBUG("original:"); |
- for (i = 0; i < len; i++) { |
- IDEBUG(" %d: %4x", i, reordered[i]); |
- } |
-#endif |
- |
- if (len != 1) { |
- HB_UChar16 *uc = reordered; |
- bool beginsWithRa = false; |
- |
- // Rule 1: find base consonant |
- // |
- // The shaping engine finds the base consonant of the |
- // syllable, using the following algorithm: starting from the |
- // end of the syllable, move backwards until a consonant is |
- // found that does not have a below-base or post-base form |
- // (post-base forms have to follow below-base forms), or |
- // arrive at the first consonant. The consonant stopped at |
- // will be the base. |
- // |
- // * If the syllable starts with Ra + H (in a script that has |
- // 'Reph'), Ra is excluded from candidates for base |
- // consonants. |
- // |
- // * In Kannada and Telugu, the base consonant cannot be |
- // farther than 3 consonants from the end of the syllable. |
- // #### replace the HasReph property by testing if the feature exists in the font! |
- if (form(*uc) == Consonant || (script == HB_Script_Bengali && form(*uc) == IndependentVowel)) { |
- if ((properties & HasReph) && (len > 2) && |
- (*uc == ra || *uc == 0x9f0) && *(uc+1) == halant) |
- beginsWithRa = true; |
- |
- if (beginsWithRa && form(*(uc+2)) == Control) |
- beginsWithRa = false; |
- |
- base = (beginsWithRa ? 2 : 0); |
- IDEBUG(" length = %d, beginsWithRa = %d, base=%d", len, beginsWithRa, base); |
- |
- int lastConsonant = 0; |
- int matra = -1; |
- // we remember: |
- // * the last consonant since we need it for rule 2 |
- // * the matras position for rule 3 and 4 |
- |
- // figure out possible base glyphs |
- memset(position, 0, len); |
- if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) { |
- bool vattu = false; |
- for (i = base; i < len; ++i) { |
- position[i] = form(uc[i]); |
- if (position[i] == Consonant) { |
- lastConsonant = i; |
- vattu = (!vattu && uc[i] == ra); |
- if (vattu) { |
- IDEBUG("excluding vattu glyph at %d from base candidates", i); |
- position[i] = Vattu; |
- } |
- } else if (position[i] == Matra) { |
- matra = i; |
- } |
- } |
- } else { |
- for (i = base; i < len; ++i) { |
- position[i] = form(uc[i]); |
- if (position[i] == Consonant) |
- lastConsonant = i; |
- else if (matra < 0 && position[i] == Matra) |
- matra = i; |
- } |
- } |
- int skipped = 0; |
- Position pos = Post; |
- for (i = len-1; i > base; i--) { |
- if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada)) |
- continue; |
- |
- Position charPosition = indic_position(uc[i]); |
- if (pos == Post && charPosition == Post) { |
- pos = Post; |
- } else if ((pos == Post || pos == Below) && charPosition == Below) { |
- if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) |
- base = i; |
- pos = Below; |
- } else { |
- base = i; |
- break; |
- } |
- if (skipped == 2 && (script == HB_Script_Kannada || script == HB_Script_Telugu)) { |
- base = i; |
- break; |
- } |
- ++skipped; |
- } |
- |
- IDEBUG(" base consonant at %d skipped=%d, lastConsonant=%d", base, skipped, lastConsonant); |
- |
- // Rule 2: |
- // |
- // If the base consonant is not the last one, Uniscribe |
- // moves the halant from the base consonant to the last |
- // one. |
- if (lastConsonant > base) { |
- int halantPos = 0; |
- if (uc[base+1] == halant) |
- halantPos = base + 1; |
- else if (uc[base+1] == nukta && uc[base+2] == halant) |
- halantPos = base + 2; |
- if (halantPos > 0) { |
- IDEBUG(" moving halant from %d to %d!", base+1, lastConsonant); |
- for (i = halantPos; i < lastConsonant; i++) |
- uc[i] = uc[i+1]; |
- uc[lastConsonant] = halant; |
- } |
- } |
- |
- // Rule 3: |
- // |
- // If the syllable starts with Ra + H, Uniscribe moves |
- // this combination so that it follows either: |
- |
- // * the post-base 'matra' (if any) or the base consonant |
- // (in scripts that show similarity to Devanagari, i.e., |
- // Devanagari, Gujarati, Bengali) |
- // * the base consonant (other scripts) |
- // * the end of the syllable (Kannada) |
- |
- Position matra_position = None; |
- if (matra > 0) |
- matra_position = indic_position(uc[matra]); |
- IDEBUG(" matra at %d with form %d, base=%d", matra, matra_position, base); |
- |
- if (beginsWithRa && base != 0) { |
- int toPos = base+1; |
- if (toPos < len && uc[toPos] == nukta) |
- toPos++; |
- if (toPos < len && uc[toPos] == halant) |
- toPos++; |
- if (toPos < len && uc[toPos] == 0x200d) |
- toPos++; |
- if (toPos < len-1 && uc[toPos] == ra && uc[toPos+1] == halant) |
- toPos += 2; |
- if (script == HB_Script_Devanagari || script == HB_Script_Gujarati || script == HB_Script_Bengali) { |
- if (matra_position == Post || matra_position == Split) { |
- toPos = matra+1; |
- matra -= 2; |
- } |
- } else if (script == HB_Script_Kannada) { |
- toPos = len; |
- matra -= 2; |
- } |
- |
- IDEBUG("moving leading ra+halant to position %d", toPos); |
- for (i = 2; i < toPos; i++) |
- uc[i-2] = uc[i]; |
- uc[toPos-2] = ra; |
- uc[toPos-1] = halant; |
- base -= 2; |
- if (properties & HasReph) |
- reph = toPos-2; |
- } |
- |
- // Rule 4: |
- |
- // Uniscribe splits two- or three-part matras into their |
- // parts. This splitting is a character-to-character |
- // operation). |
- // |
- // Uniscribe describes some moving operations for these |
- // matras here. For shaping however all pre matras need |
- // to be at the beginning of the syllable, so we just move |
- // them there now. |
- if (matra_position == Split) { |
- splitMatra(uc, matra, len); |
- // Handle three-part matras (0xccb in Kannada) |
- matra_position = indic_position(uc[matra]); |
- } |
- |
- if (matra_position == Pre) { |
- unsigned short m = uc[matra]; |
- while (matra--) |
- uc[matra+1] = uc[matra]; |
- uc[0] = m; |
- base++; |
- } |
- } |
- |
- // Rule 5: |
- // |
- // Uniscribe classifies consonants and 'matra' parts as |
- // pre-base, above-base (Reph), below-base or post-base. This |
- // classification exists on the character code level and is |
- // language-dependent, not font-dependent. |
- for (i = 0; i < base; ++i) |
- position[i] = Pre; |
- position[base] = Base; |
- for (i = base+1; i < len; ++i) { |
- position[i] = indic_position(uc[i]); |
- // #### replace by adjusting table |
- if (uc[i] == nukta || uc[i] == halant) |
- position[i] = Inherit; |
- } |
- if (reph > 0) { |
- // recalculate reph, it might have changed. |
- for (i = base+1; i < len; ++i) |
- if (uc[i] == ra) |
- reph = i; |
- position[reph] = Reph; |
- position[reph+1] = Inherit; |
- } |
- |
- // all reordering happens now to the chars after the base |
- int fixed = base+1; |
- if (fixed < len && uc[fixed] == nukta) |
- fixed++; |
- if (fixed < len && uc[fixed] == halant) |
- fixed++; |
- if (fixed < len && uc[fixed] == 0x200d) |
- fixed++; |
- |
-#ifdef INDIC_DEBUG |
- for (i = fixed; i < len; ++i) |
- IDEBUG("position[%d] = %d, form=%d uc=%x", i, position[i], form(uc[i]), uc[i]); |
-#endif |
- // we continuosly position the matras and vowel marks and increase the fixed |
- // until we reached the end. |
- const IndicOrdering *finalOrder = indic_order[script-HB_Script_Devanagari]; |
- |
- IDEBUG(" reordering pass:"); |
- IDEBUG(" base=%d fixed=%d", base, fixed); |
- int toMove = 0; |
- while (finalOrder[toMove].form && fixed < len-1) { |
- IDEBUG(" fixed = %d, toMove=%d, moving form %d with pos %d", fixed, toMove, finalOrder[toMove].form, finalOrder[toMove].position); |
- for (i = fixed; i < len; i++) { |
-// IDEBUG() << " i=" << i << "uc=" << hex << uc[i] << "form=" << form(uc[i]) |
-// << "position=" << position[i]; |
- if (form(uc[i]) == finalOrder[toMove].form && |
- position[i] == finalOrder[toMove].position) { |
- // need to move this glyph |
- int to = fixed; |
- if (i < len-1 && position[i+1] == Inherit) { |
- IDEBUG(" moving two chars from %d to %d", i, to); |
- unsigned short ch = uc[i]; |
- unsigned short ch2 = uc[i+1]; |
- unsigned char pos = position[i]; |
- for (int j = i+1; j > to+1; j--) { |
- uc[j] = uc[j-2]; |
- position[j] = position[j-2]; |
- } |
- uc[to] = ch; |
- uc[to+1] = ch2; |
- position[to] = pos; |
- position[to+1] = pos; |
- fixed += 2; |
- } else { |
- IDEBUG(" moving one char from %d to %d", i, to); |
- unsigned short ch = uc[i]; |
- unsigned char pos = position[i]; |
- for (int j = i; j > to; j--) { |
- uc[j] = uc[j-1]; |
- position[j] = position[j-1]; |
- } |
- uc[to] = ch; |
- position[to] = pos; |
- fixed++; |
- } |
- } |
- } |
- toMove++; |
- } |
- |
- } |
- |
- if (reph > 0) { |
- // recalculate reph, it might have changed. |
- for (i = base+1; i < len; ++i) |
- if (reordered[i] == ra) |
- reph = i; |
- } |
- |
-#ifndef NO_OPENTYPE |
- const int availableGlyphs = item->num_glyphs; |
-#endif |
- if (!item->font->klass->convertStringToGlyphIndices(item->font, |
- reordered, len, |
- item->glyphs, &item->num_glyphs, |
- item->item.bidiLevel % 2)) |
- goto error; |
- |
- |
- IDEBUG(" base=%d, reph=%d", base, reph); |
- IDEBUG("reordered:"); |
- for (i = 0; i < len; i++) { |
- item->attributes[i].mark = false; |
- item->attributes[i].clusterStart = false; |
- item->attributes[i].justification = 0; |
- item->attributes[i].zeroWidth = false; |
- IDEBUG(" %d: %4x", i, reordered[i]); |
- } |
- |
- // now we have the syllable in the right order, and can start running it through open type. |
- |
- for (i = 0; i < len; ++i) |
- control |= (form(reordered[i]) == Control); |
- |
-#ifndef NO_OPENTYPE |
- if (openType) { |
- |
- // we need to keep track of where the base glyph is for some |
- // scripts and use the cluster feature for this. This |
- // also means we have to correct the logCluster output from |
- // the open type engine manually afterwards. for indic this |
- // is rather simple, as all chars just point to the first |
- // glyph in the syllable. |
- HB_STACKARRAY(unsigned short, clusters, len); |
- HB_STACKARRAY(unsigned int, properties, len); |
- |
- for (i = 0; i < len; ++i) |
- clusters[i] = i; |
- |
- // features we should always apply |
- for (i = 0; i < len; ++i) |
- properties[i] = ~(CcmpProperty |
- | NuktaProperty |
- | VattuProperty |
- | PreSubstProperty |
- | BelowSubstProperty |
- | AboveSubstProperty |
- | PostSubstProperty |
- | HalantProperty |
- | PositioningProperties); |
- |
- // Ccmp always applies |
- // Init |
- if (item->item.pos == 0 |
- || !(isLetter(item->string[item->item.pos-1]) || isMark(item->string[item->item.pos-1]))) |
- properties[0] &= ~InitProperty; |
- |
- // Nukta always applies |
- // Akhant |
- for (i = 0; i <= base; ++i) |
- properties[i] &= ~AkhantProperty; |
- // Reph |
- if (reph >= 0) { |
- properties[reph] &= ~RephProperty; |
- properties[reph+1] &= ~RephProperty; |
- } |
- // BelowForm |
- for (i = base+1; i < len; ++i) |
- properties[i] &= ~BelowFormProperty; |
- |
- if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) { |
- // vattu glyphs need this aswell |
- bool vattu = false; |
- for (i = base-2; i > 1; --i) { |
- if (form(reordered[i]) == Consonant) { |
- vattu = (!vattu && reordered[i] == ra); |
- if (vattu) { |
- IDEBUG("forming vattu ligature at %d", i); |
- properties[i] &= ~BelowFormProperty; |
- properties[i+1] &= ~BelowFormProperty; |
- } |
- } |
- } |
- } |
- // HalfFormProperty |
- for (i = 0; i < base; ++i) |
- properties[i] &= ~HalfFormProperty; |
- if (control) { |
- for (i = 2; i < len; ++i) { |
- if (reordered[i] == 0x200d /* ZWJ */) { |
- properties[i-1] &= ~HalfFormProperty; |
- properties[i-2] &= ~HalfFormProperty; |
- } else if (reordered[i] == 0x200c /* ZWNJ */) { |
- properties[i-1] &= ~HalfFormProperty; |
- properties[i-2] &= ~HalfFormProperty; |
- } |
- } |
- } |
- // PostFormProperty |
- for (i = base+1; i < len; ++i) |
- properties[i] &= ~PostFormProperty; |
- // vattu always applies |
- // pres always applies |
- // blws always applies |
- // abvs always applies |
- // psts always applies |
- // halant always applies |
- |
-#ifdef INDIC_DEBUG |
-// { |
-// IDEBUG("OT properties:"); |
-// for (int i = 0; i < len; ++i) |
-// qDebug(" i: %s", ::propertiesToString(properties[i]).toLatin1().data()); |
-// } |
-#endif |
- |
- // initialize |
- item->log_clusters = clusters; |
- HB_OpenTypeShape(item, properties); |
- |
- int newLen = item->face->buffer->in_length; |
- HB_GlyphItem otl_glyphs = item->face->buffer->in_string; |
- |
- // move the left matra back to its correct position in malayalam and tamil |
- if ((script == HB_Script_Malayalam || script == HB_Script_Tamil) && (form(reordered[0]) == Matra)) { |
-// qDebug("reordering matra, len=%d", newLen); |
- // need to find the base in the shaped string and move the matra there |
- int basePos = 0; |
- while (basePos < newLen && (int)otl_glyphs[basePos].cluster <= base) |
- basePos++; |
- --basePos; |
- if (basePos < newLen && basePos > 1) { |
-// qDebug("moving prebase matra to position %d in syllable newlen=%d", basePos, newLen); |
- HB_GlyphItemRec m = otl_glyphs[0]; |
- --basePos; |
- for (i = 0; i < basePos; ++i) |
- otl_glyphs[i] = otl_glyphs[i+1]; |
- otl_glyphs[basePos] = m; |
- } |
- } |
- |
- HB_Bool positioned = HB_OpenTypePosition(item, availableGlyphs, false); |
- |
- HB_FREE_STACKARRAY(clusters); |
- HB_FREE_STACKARRAY(properties); |
- |
- if (!positioned) |
- goto error; |
- |
- if (control) { |
- IDEBUG("found a control char in the syllable"); |
- hb_uint32 i = 0, j = 0; |
- while (i < item->num_glyphs) { |
- if (form(reordered[otl_glyphs[i].cluster]) == Control) { |
- ++i; |
- if (i >= item->num_glyphs) |
- break; |
- } |
- item->glyphs[j] = item->glyphs[i]; |
- item->attributes[j] = item->attributes[i]; |
- ++i; |
- ++j; |
- } |
- item->num_glyphs = j; |
- } |
- |
- } else { |
- HB_HeuristicPosition(item); |
- } |
-#endif // NO_OPENTYPE |
- item->attributes[0].clusterStart = true; |
- |
- HB_FREE_STACKARRAY(reordered); |
- HB_FREE_STACKARRAY(position); |
- |
- IDEBUG("<<<<<<"); |
- return true; |
- |
-error: |
- HB_FREE_STACKARRAY(reordered); |
- HB_FREE_STACKARRAY(position); |
- return false; |
-} |
- |
-/* syllables are of the form: |
- |
- (Consonant Nukta? Halant)* Consonant Matra? VowelMark? StressMark? |
- (Consonant Nukta? Halant)* Consonant Halant |
- IndependentVowel VowelMark? StressMark? |
- |
- We return syllable boundaries on invalid combinations aswell |
-*/ |
-static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int start, int end, bool *invalid) |
-{ |
- *invalid = false; |
- IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", start, end); |
- const HB_UChar16 *uc = s+start; |
- |
- int pos = 0; |
- Form state = form(uc[pos]); |
- IDEBUG("state[%d]=%d (uc=%4x)", pos, state, uc[pos]); |
- pos++; |
- |
- if (state != Consonant && state != IndependentVowel) { |
- if (state != Other) |
- *invalid = true; |
- goto finish; |
- } |
- |
- while (pos < end - start) { |
- Form newState = form(uc[pos]); |
- IDEBUG("state[%d]=%d (uc=%4x)", pos, newState, uc[pos]); |
- switch(newState) { |
- case Control: |
- newState = state; |
- if (state == Halant && uc[pos] == 0x200d /* ZWJ */) |
- break; |
- // the control character should be the last char in the item |
- ++pos; |
- goto finish; |
- case Consonant: |
- if (state == Halant && (script != HB_Script_Sinhala || uc[pos-1] == 0x200d /* ZWJ */)) |
- break; |
- goto finish; |
- case Halant: |
- if (state == Nukta || state == Consonant) |
- break; |
- // Bengali has a special exception allowing the combination Vowel_A/E + Halant + Ya |
- if (script == HB_Script_Bengali && pos == 1 && |
- (uc[0] == 0x0985 || uc[0] == 0x098f)) |
- break; |
- // Sinhala uses the Halant as a component of certain matras. Allow these, but keep the state on Matra. |
- if (script == HB_Script_Sinhala && state == Matra) { |
- ++pos; |
- continue; |
- } |
- if (script == HB_Script_Malayalam && state == Matra && uc[pos-1] == 0x0d41) { |
- ++pos; |
- continue; |
- } |
- goto finish; |
- case Nukta: |
- if (state == Consonant) |
- break; |
- goto finish; |
- case StressMark: |
- if (state == VowelMark) |
- break; |
- // fall through |
- case VowelMark: |
- if (state == Matra || state == LengthMark || state == IndependentVowel) |
- break; |
- // fall through |
- case Matra: |
- if (state == Consonant || state == Nukta) |
- break; |
- if (state == Matra) { |
- // ### needs proper testing for correct two/three part matras |
- break; |
- } |
- // ### not sure if this is correct. If it is, does it apply only to Bengali or should |
- // it work for all Indic languages? |
- // the combination Independent_A + Vowel Sign AA is allowed. |
- if (script == HB_Script_Bengali && uc[pos] == 0x9be && uc[pos-1] == 0x985) |
- break; |
- if (script == HB_Script_Tamil && state == Matra) { |
- if (uc[pos-1] == 0x0bc6 && |
- (uc[pos] == 0xbbe || uc[pos] == 0xbd7)) |
- break; |
- if (uc[pos-1] == 0x0bc7 && uc[pos] == 0xbbe) |
- break; |
- } |
- goto finish; |
- |
- case LengthMark: |
- if (state == Matra) { |
- // ### needs proper testing for correct two/three part matras |
- break; |
- } |
- case IndependentVowel: |
- case Invalid: |
- case Other: |
- goto finish; |
- } |
- state = newState; |
- pos++; |
- } |
- finish: |
- return pos+start; |
-} |
- |
-HB_Bool HB_IndicShape(HB_ShaperItem *item) |
-{ |
- assert(item->item.script >= HB_Script_Devanagari && item->item.script <= HB_Script_Sinhala); |
- |
- HB_Bool openType = false; |
-#ifndef NO_OPENTYPE |
- openType = HB_SelectScript(item, indic_features); |
-#endif |
- unsigned short *logClusters = item->log_clusters; |
- |
- HB_ShaperItem syllable = *item; |
- int first_glyph = 0; |
- |
- int sstart = item->item.pos; |
- int end = sstart + item->item.length; |
- IDEBUG("indic_shape: from %d length %d", item->item.pos, item->item.length); |
- while (sstart < end) { |
- bool invalid; |
- int send = indic_nextSyllableBoundary(item->item.script, item->string, sstart, end, &invalid); |
- IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart, |
- invalid ? "true" : "false"); |
- syllable.item.pos = sstart; |
- syllable.item.length = send-sstart; |
- syllable.glyphs = item->glyphs + first_glyph; |
- syllable.attributes = item->attributes + first_glyph; |
- syllable.offsets = item->offsets + first_glyph; |
- syllable.advances = item->advances + first_glyph; |
- syllable.num_glyphs = item->num_glyphs - first_glyph; |
- if (!indic_shape_syllable(openType, &syllable, invalid)) { |
- IDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs); |
- item->num_glyphs += syllable.num_glyphs; |
- return false; |
- } |
- // fix logcluster array |
- IDEBUG("syllable:"); |
- hb_uint32 g; |
- for (g = first_glyph; g < first_glyph + syllable.num_glyphs; ++g) |
- IDEBUG(" %d -> glyph %x", g, item->glyphs[g]); |
- IDEBUG(" logclusters:"); |
- int i; |
- for (i = sstart; i < send; ++i) { |
- IDEBUG(" %d -> glyph %d", i, first_glyph); |
- logClusters[i-item->item.pos] = first_glyph; |
- } |
- sstart = send; |
- first_glyph += syllable.num_glyphs; |
- } |
- item->num_glyphs = first_glyph; |
- return true; |
-} |
- |
-void HB_IndicAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes) |
-{ |
- int end = from + len; |
- const HB_UChar16 *uc = text + from; |
- attributes += from; |
- hb_uint32 i = 0; |
- while (i < len) { |
- bool invalid; |
- hb_uint32 boundary = indic_nextSyllableBoundary(script, text, from+i, end, &invalid) - from; |
- attributes[i].charStop = true; |
- |
- if (boundary > len-1) boundary = len; |
- i++; |
- while (i < boundary) { |
- attributes[i].charStop = false; |
- ++uc; |
- ++i; |
- } |
- assert(i == boundary); |
- } |
- |
- |
-} |
- |
- |