/* * Copyright (C) 2016-2019 Muhammad Tayyab Akram * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "BidiTypeLookup.h" #include "GeneralCategoryLookup.h" #include "PairingLookup.h" #include "ScriptLookup.h" #include "SBBase.h" #define TAG(a, b, c, d) \ (SBUInt32) \ ( \ ((SBUInt8)(a) << 24) \ | ((SBUInt8)(b) << 16) \ | ((SBUInt8)(c) << 8) \ | ((SBUInt8)(d) << 0) \ ) SB_INTERNAL void SBUIntegerNormalizeRange(SBUInteger actualLength, SBUInteger *rangeOffset, SBUInteger *rangeLength) { /** * Assume: * Actual Length = 10 * * Case 1: * Offset = 0, Length = 10 * Result: * Offset = 0, Length = 10 * * Case 2: * Offset = 0, Length = 11 * Result: * Offset = 0, Length = 10 * * Case 3: * Offset = 1, Length = -1 (MAX) * Result: * Offset = 1, Length = 9 * * Case 4: * Offset = 10, Length = 0 * Result: * Offset = Invalid, Length = 0 * * Case 5: * Offset = -1 (MAX), Length = 1 * Result: * Offset = Invalid, Length = 0 */ if (*rangeOffset < actualLength) { SBUInteger possibleLimit = *rangeOffset + *rangeLength; if (*rangeOffset <= possibleLimit && possibleLimit <= actualLength) { /* The range is valid. Nothing to do here. */ } else { *rangeLength = actualLength - *rangeOffset; } } else { *rangeOffset = SBInvalidIndex; *rangeLength = 0; } } SB_INTERNAL SBBoolean SBUIntegerVerifyRange(SBUInteger actualLength, SBUInteger rangeOffset, SBUInteger rangeLength) { SBUInteger possibleLimit = rangeOffset + rangeLength; return rangeOffset < actualLength && rangeOffset <= possibleLimit && possibleLimit <= actualLength; } SBBidiType SBCodepointGetBidiType(SBCodepoint codepoint) { return LookupBidiType(codepoint); } SBGeneralCategory SBCodepointGetGeneralCategory(SBCodepoint codepoint) { return LookupGeneralCategory(codepoint); } SBCodepoint SBCodepointGetMirror(SBCodepoint codepoint) { return LookupMirror(codepoint); } SBScript SBCodepointGetScript(SBCodepoint codepoint) { return LookupScript(codepoint); } SBUInt32 SBScriptGetOpenTypeTag(SBScript script) { /* Reference: https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags */ /* Dated: 07/24/2017 */ switch (script) { case SBScriptADLM: return TAG('a', 'd', 'l', 'm'); case SBScriptAHOM: return TAG('a', 'h', 'o', 'm'); case SBScriptHLUW: return TAG('h', 'l', 'u', 'w'); case SBScriptARAB: return TAG('a', 'r', 'a', 'b'); case SBScriptARMN: return TAG('a', 'r', 'm', 'n'); case SBScriptAVST: return TAG('a', 'v', 's', 't'); case SBScriptBALI: return TAG('b', 'a', 'l', 'i'); case SBScriptBAMU: return TAG('b', 'a', 'm', 'u'); case SBScriptBASS: return TAG('b', 'a', 's', 's'); case SBScriptBATK: return TAG('b', 'a', 't', 'k'); /* case SBScriptBENG: return TAG('b', 'e', 'n', 'g'); */ case SBScriptBENG: return TAG('b', 'n', 'g', '2'); case SBScriptBHKS: return TAG('b', 'h', 'k', 's'); case SBScriptBOPO: return TAG('b', 'o', 'p', 'o'); case SBScriptBRAH: return TAG('b', 'r', 'a', 'h'); case SBScriptBRAI: return TAG('b', 'r', 'a', 'i'); case SBScriptBUGI: return TAG('b', 'u', 'g', 'i'); case SBScriptBUHD: return TAG('b', 'u', 'h', 'd'); /* case SBScriptBYZM: return TAG('b', 'y', 'z', 'm'); */ case SBScriptCANS: return TAG('c', 'a', 'n', 's'); case SBScriptCARI: return TAG('c', 'a', 'r', 'i'); case SBScriptAGHB: return TAG('a', 'g', 'h', 'b'); case SBScriptCAKM: return TAG('c', 'a', 'k', 'm'); case SBScriptCHAM: return TAG('c', 'h', 'a', 'm'); case SBScriptCHER: return TAG('c', 'h', 'e', 'r'); case SBScriptHANI: return TAG('h', 'a', 'n', 'i'); case SBScriptCOPT: return TAG('c', 'o', 'p', 't'); case SBScriptCPRT: return TAG('c', 'p', 'r', 't'); case SBScriptCYRL: return TAG('c', 'y', 'r', 'l'); /* case SBScriptDFLT: return TAG('D', 'F', 'L', 'T'); */ case SBScriptDSRT: return TAG('d', 's', 'r', 't'); /* case SBScriptDEVA: return TAG('d', 'e', 'v', 'a'); */ case SBScriptDEVA: return TAG('d', 'e', 'v', '2'); case SBScriptDUPL: return TAG('d', 'u', 'p', 'l'); case SBScriptEGYP: return TAG('e', 'g', 'y', 'p'); case SBScriptELBA: return TAG('e', 'l', 'b', 'a'); case SBScriptETHI: return TAG('e', 't', 'h', 'i'); case SBScriptGEOR: return TAG('g', 'e', 'o', 'r'); case SBScriptGLAG: return TAG('g', 'l', 'a', 'g'); case SBScriptGOTH: return TAG('g', 'o', 't', 'h'); case SBScriptGRAN: return TAG('g', 'r', 'a', 'n'); case SBScriptGREK: return TAG('g', 'r', 'e', 'k'); /* case SBScriptGUJR: return TAG('g', 'u', 'j', 'r'); */ case SBScriptGUJR: return TAG('g', 'j', 'r', '2'); /* case SBScriptGURU: return TAG('g', 'u', 'r', 'u'); */ case SBScriptGURU: return TAG('g', 'u', 'r', '2'); case SBScriptHANG: return TAG('h', 'a', 'n', 'g'); /* case SBScriptJAMO: return TAG('j', 'a', 'm', 'o'); */ case SBScriptHANO: return TAG('h', 'a', 'n', 'o'); case SBScriptHATR: return TAG('h', 'a', 't', 'r'); case SBScriptHEBR: return TAG('h', 'e', 'b', 'r'); case SBScriptHIRA: return TAG('k', 'a', 'n', 'a'); case SBScriptARMI: return TAG('a', 'r', 'm', 'i'); case SBScriptPHLI: return TAG('p', 'h', 'l', 'i'); case SBScriptPRTI: return TAG('p', 'r', 't', 'i'); case SBScriptJAVA: return TAG('j', 'a', 'v', 'a'); case SBScriptKTHI: return TAG('k', 't', 'h', 'i'); /* case SBScriptKNDA: return TAG('k', 'n', 'd', 'a'); */ case SBScriptKNDA: return TAG('k', 'n', 'd', '2'); case SBScriptKANA: return TAG('k', 'a', 'n', 'a'); case SBScriptKALI: return TAG('k', 'a', 'l', 'i'); case SBScriptKHAR: return TAG('k', 'h', 'a', 'r'); case SBScriptKHMR: return TAG('k', 'h', 'm', 'r'); case SBScriptKHOJ: return TAG('k', 'h', 'o', 'j'); case SBScriptSIND: return TAG('s', 'i', 'n', 'd'); case SBScriptLAOO: return TAG('l', 'a', 'o', ' '); case SBScriptLATN: return TAG('l', 'a', 't', 'n'); case SBScriptLEPC: return TAG('l', 'e', 'p', 'c'); case SBScriptLIMB: return TAG('l', 'i', 'm', 'b'); case SBScriptLINA: return TAG('l', 'i', 'n', 'a'); case SBScriptLINB: return TAG('l', 'i', 'n', 'b'); case SBScriptLISU: return TAG('l', 'i', 's', 'u'); case SBScriptLYCI: return TAG('l', 'y', 'c', 'i'); case SBScriptLYDI: return TAG('l', 'y', 'd', 'i'); case SBScriptMAHJ: return TAG('m', 'a', 'h', 'j'); /* case SBScriptMLYM: return TAG('m', 'l', 'y', 'm'); */ case SBScriptMLYM: return TAG('m', 'l', 'm', '2'); case SBScriptMAND: return TAG('m', 'a', 'n', 'd'); case SBScriptMANI: return TAG('m', 'a', 'n', 'i'); case SBScriptMARC: return TAG('m', 'a', 'r', 'c'); /* case SBScriptMATH: return TAG('m', 'a', 't', 'h'); */ case SBScriptMTEI: return TAG('m', 't', 'e', 'i'); case SBScriptMEND: return TAG('m', 'e', 'n', 'd'); case SBScriptMERC: return TAG('m', 'e', 'r', 'c'); case SBScriptMERO: return TAG('m', 'e', 'r', 'o'); case SBScriptPLRD: return TAG('p', 'l', 'r', 'd'); case SBScriptMODI: return TAG('m', 'o', 'd', 'i'); case SBScriptMONG: return TAG('m', 'o', 'n', 'g'); case SBScriptMROO: return TAG('m', 'r', 'o', 'o'); case SBScriptMULT: return TAG('m', 'u', 'l', 't'); /* case SBScriptMUSC: return TAG('m', 'u', 's', 'c'); */ /* case SBScriptMYMR: return TAG('m', 'y', 'm', 'r'); */ case SBScriptMYMR: return TAG('m', 'y', 'm', '2'); case SBScriptNBAT: return TAG('n', 'b', 'a', 't'); case SBScriptNEWA: return TAG('n', 'e', 'w', 'a'); case SBScriptTALU: return TAG('t', 'a', 'l', 'u'); case SBScriptNKOO: return TAG('n', 'k', 'o', ' '); /* case SBScriptORYA: return TAG('o', 'r', 'y', 'a'); */ case SBScriptORYA: return TAG('o', 'r', 'y', '2'); case SBScriptOGAM: return TAG('o', 'g', 'a', 'm'); case SBScriptOLCK: return TAG('o', 'l', 'c', 'k'); case SBScriptITAL: return TAG('i', 't', 'a', 'l'); case SBScriptHUNG: return TAG('h', 'u', 'n', 'g'); case SBScriptNARB: return TAG('n', 'a', 'r', 'b'); case SBScriptPERM: return TAG('p', 'e', 'r', 'm'); case SBScriptXPEO: return TAG('x', 'p', 'e', 'o'); case SBScriptSARB: return TAG('s', 'a', 'r', 'b'); case SBScriptORKH: return TAG('o', 'r', 'k', 'h'); case SBScriptOSGE: return TAG('o', 's', 'g', 'e'); case SBScriptOSMA: return TAG('o', 's', 'm', 'a'); case SBScriptHMNG: return TAG('h', 'm', 'n', 'g'); case SBScriptPALM: return TAG('p', 'a', 'l', 'm'); case SBScriptPAUC: return TAG('p', 'a', 'u', 'c'); case SBScriptPHAG: return TAG('p', 'h', 'a', 'g'); case SBScriptPHNX: return TAG('p', 'h', 'n', 'x'); case SBScriptPHLP: return TAG('p', 'h', 'l', 'p'); case SBScriptRJNG: return TAG('r', 'j', 'n', 'g'); case SBScriptRUNR: return TAG('r', 'u', 'n', 'r'); case SBScriptSAMR: return TAG('s', 'a', 'm', 'r'); case SBScriptSAUR: return TAG('s', 'a', 'u', 'r'); case SBScriptSHRD: return TAG('s', 'h', 'r', 'd'); case SBScriptSHAW: return TAG('s', 'h', 'a', 'w'); case SBScriptSIDD: return TAG('s', 'i', 'd', 'd'); case SBScriptSGNW: return TAG('s', 'g', 'n', 'w'); case SBScriptSINH: return TAG('s', 'i', 'n', 'h'); case SBScriptSORA: return TAG('s', 'o', 'r', 'a'); case SBScriptXSUX: return TAG('x', 's', 'u', 'x'); case SBScriptSUND: return TAG('s', 'u', 'n', 'd'); case SBScriptSYLO: return TAG('s', 'y', 'l', 'o'); case SBScriptSYRC: return TAG('s', 'y', 'r', 'c'); case SBScriptTGLG: return TAG('t', 'g', 'l', 'g'); case SBScriptTAGB: return TAG('t', 'a', 'g', 'b'); case SBScriptTALE: return TAG('t', 'a', 'l', 'e'); case SBScriptLANA: return TAG('l', 'a', 'n', 'a'); case SBScriptTAVT: return TAG('t', 'a', 'v', 't'); case SBScriptTAKR: return TAG('t', 'a', 'k', 'r'); /* case SBScriptTAML: return TAG('t', 'a', 'm', 'l'); */ case SBScriptTAML: return TAG('t', 'm', 'l', '2'); case SBScriptTANG: return TAG('t', 'a', 'n', 'g'); /* case SBScriptTELU: return TAG('t', 'e', 'l', 'u'); */ case SBScriptTELU: return TAG('t', 'e', 'l', '2'); case SBScriptTHAA: return TAG('t', 'h', 'a', 'a'); case SBScriptTHAI: return TAG('t', 'h', 'a', 'i'); case SBScriptTIBT: return TAG('t', 'i', 'b', 't'); case SBScriptTFNG: return TAG('t', 'f', 'n', 'g'); case SBScriptTIRH: return TAG('t', 'i', 'r', 'h'); case SBScriptUGAR: return TAG('u', 'g', 'a', 'r'); case SBScriptVAII: return TAG('v', 'a', 'i', ' '); case SBScriptWARA: return TAG('w', 'a', 'r', 'a'); case SBScriptYIII: return TAG('y', 'i', ' ', ' '); default: return TAG('D', 'F', 'L', 'T'); } }