mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
SheenBidi: Add sources
This commit is contained in:
parent
a3a4813107
commit
d77d5801d9
85 changed files with 15845 additions and 0 deletions
110
modules/juce_graphics/unicode/sheenbidi/Source/BidiChain.c
Normal file
110
modules/juce_graphics/unicode/sheenbidi/Source/BidiChain.c
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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 <SBConfig.h>
|
||||
|
||||
#include "SBBase.h"
|
||||
#include "BidiChain.h"
|
||||
|
||||
SB_INTERNAL void BidiChainInitialize(BidiChainRef chain,
|
||||
SBBidiType *types, SBLevel *levels, BidiLink *links)
|
||||
{
|
||||
chain->types = types;
|
||||
chain->levels = levels;
|
||||
chain->links = links;
|
||||
chain->roller = 0;
|
||||
chain->last = 0;
|
||||
|
||||
/* Make first link empty. */
|
||||
chain->types[0] = SBBidiTypeNil;
|
||||
chain->levels[0] = SBLevelInvalid;
|
||||
chain->links[0] = BidiLinkNone;
|
||||
}
|
||||
|
||||
SB_INTERNAL void BidiChainAdd(BidiChainRef chain, SBBidiType type, SBUInteger length)
|
||||
{
|
||||
BidiLink last = chain->last;
|
||||
BidiLink current = last + (SBUInt32)length;
|
||||
|
||||
chain->types[current] = type;
|
||||
chain->links[current] = chain->roller;
|
||||
|
||||
chain->links[last] = current;
|
||||
chain->last = current;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean BidiChainIsSingle(BidiChainRef chain, BidiLink link)
|
||||
{
|
||||
BidiLink next = chain->links[link];
|
||||
|
||||
/* Check the type of in between code units. */
|
||||
while (++link != next) {
|
||||
if (chain->types[link] != SBBidiTypeBN) {
|
||||
return SBFalse;
|
||||
}
|
||||
}
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBidiType BidiChainGetType(BidiChainRef chain, BidiLink link)
|
||||
{
|
||||
return chain->types[link];
|
||||
}
|
||||
|
||||
SB_INTERNAL void BidiChainSetType(BidiChainRef chain, BidiLink link, SBBidiType type)
|
||||
{
|
||||
chain->types[link] = type;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBLevel BidiChainGetLevel(BidiChainRef chain, BidiLink link)
|
||||
{
|
||||
return chain->levels[link];
|
||||
}
|
||||
|
||||
SB_INTERNAL void BidiChainSetLevel(BidiChainRef chain, BidiLink link, SBLevel level)
|
||||
{
|
||||
chain->levels[link] = level;
|
||||
}
|
||||
|
||||
SB_INTERNAL BidiLink BidiChainGetNext(BidiChainRef chain, BidiLink link)
|
||||
{
|
||||
return chain->links[link];
|
||||
}
|
||||
|
||||
SB_INTERNAL void BidiChainSetNext(BidiChainRef chain, BidiLink link, BidiLink next)
|
||||
{
|
||||
chain->links[link] = next;
|
||||
}
|
||||
|
||||
SB_INTERNAL void BidiChainAbandonNext(BidiChainRef chain, BidiLink link)
|
||||
{
|
||||
BidiLink next = chain->links[link];
|
||||
BidiLink limit = chain->links[next];
|
||||
|
||||
chain->links[link] = limit;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean BidiChainMergeIfEqual(BidiChainRef chain, BidiLink first, BidiLink second)
|
||||
{
|
||||
if (chain->types[first] == chain->types[second]
|
||||
&& chain->levels[first] == chain->levels[second]) {
|
||||
chain->links[first] = chain->links[second];
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
return SBFalse;
|
||||
}
|
||||
60
modules/juce_graphics/unicode/sheenbidi/Source/BidiChain.h
Normal file
60
modules/juce_graphics/unicode/sheenbidi/Source/BidiChain.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_BIDI_CHAIN_H
|
||||
#define _SB_INTERNAL_BIDI_CHAIN_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
#include "SBBase.h"
|
||||
|
||||
typedef SBUInt32 BidiLink;
|
||||
|
||||
#define BidiLinkNone (SBUInt32)(-1)
|
||||
|
||||
typedef struct _BidiChain {
|
||||
SBBidiType *types;
|
||||
SBLevel *levels;
|
||||
BidiLink *links;
|
||||
BidiLink roller;
|
||||
BidiLink last;
|
||||
} BidiChain, *BidiChainRef;
|
||||
|
||||
SB_INTERNAL void BidiChainInitialize(BidiChainRef chain,
|
||||
SBBidiType *types, SBLevel *levels, BidiLink *links);
|
||||
SB_INTERNAL void BidiChainAdd(BidiChainRef chain, SBBidiType type, SBUInteger length);
|
||||
|
||||
#define BidiChainGetOffset(chain, link) \
|
||||
( \
|
||||
(link) - 1 \
|
||||
)
|
||||
|
||||
SB_INTERNAL SBBoolean BidiChainIsSingle(BidiChainRef chain, BidiLink link);
|
||||
|
||||
SB_INTERNAL SBBidiType BidiChainGetType(BidiChainRef chain, BidiLink link);
|
||||
SB_INTERNAL void BidiChainSetType(BidiChainRef chain, BidiLink link, SBBidiType type);
|
||||
|
||||
SB_INTERNAL SBLevel BidiChainGetLevel(BidiChainRef chain, BidiLink link);
|
||||
SB_INTERNAL void BidiChainSetLevel(BidiChainRef chain, BidiLink link, SBLevel level);
|
||||
|
||||
SB_INTERNAL BidiLink BidiChainGetNext(BidiChainRef chain, BidiLink link);
|
||||
SB_INTERNAL void BidiChainSetNext(BidiChainRef chain, BidiLink link, BidiLink next);
|
||||
SB_INTERNAL void BidiChainAbandonNext(BidiChainRef chain, BidiLink link);
|
||||
SB_INTERNAL SBBoolean BidiChainMergeIfEqual(BidiChainRef chain, BidiLink first, BidiLink second);
|
||||
|
||||
#define BidiChainForEach(chain, roller, link) \
|
||||
for (link = chain->links[roller]; link != roller; link = chain->links[link])
|
||||
|
||||
#endif
|
||||
1153
modules/juce_graphics/unicode/sheenbidi/Source/BidiTypeLookup.c
Normal file
1153
modules/juce_graphics/unicode/sheenbidi/Source/BidiTypeLookup.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Automatically generated by SheenBidiGenerator tool.
|
||||
* DO NOT EDIT!!
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_BIDI_TYPE_LOOKUP_H
|
||||
#define _SB_INTERNAL_BIDI_TYPE_LOOKUP_H
|
||||
|
||||
#include <SBBidiType.h>
|
||||
#include <SBConfig.h>
|
||||
|
||||
#include "SBBase.h"
|
||||
|
||||
SB_INTERNAL SBBidiType LookupBidiType(SBCodepoint codepoint);
|
||||
|
||||
#endif
|
||||
242
modules/juce_graphics/unicode/sheenbidi/Source/BracketQueue.c
Normal file
242
modules/juce_graphics/unicode/sheenbidi/Source/BracketQueue.c
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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 <SBConfig.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "BidiChain.h"
|
||||
#include "SBAssert.h"
|
||||
#include "SBBase.h"
|
||||
#include "BracketQueue.h"
|
||||
|
||||
static SBBoolean BracketQueueInsertElement(BracketQueueRef queue)
|
||||
{
|
||||
if (queue->_rearTop != BracketQueueList_MaxIndex) {
|
||||
queue->_rearTop += 1;
|
||||
} else {
|
||||
BracketQueueListRef previousList = queue->_rearList;
|
||||
BracketQueueListRef rearList = previousList->next;
|
||||
|
||||
if (!rearList) {
|
||||
rearList = malloc(sizeof(BracketQueueList));
|
||||
if (!rearList) {
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
rearList->previous = previousList;
|
||||
rearList->next = NULL;
|
||||
|
||||
previousList->next = rearList;
|
||||
}
|
||||
|
||||
queue->_rearList = rearList;
|
||||
queue->_rearTop = 0;
|
||||
}
|
||||
queue->count += 1;
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
static void BracketQueueFinalizePairs(BracketQueueRef queue, BracketQueueListRef list, SBInteger top)
|
||||
{
|
||||
do {
|
||||
SBInteger limit = (list == queue->_rearList ? queue->_rearTop : BracketQueueList_MaxIndex);
|
||||
|
||||
while (++top <= limit) {
|
||||
if (list->openingLink[top] != BidiLinkNone
|
||||
&& list->closingLink[top] == BidiLinkNone) {
|
||||
list->openingLink[top] = BidiLinkNone;
|
||||
}
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
top = 0;
|
||||
} while (list);
|
||||
}
|
||||
|
||||
SB_INTERNAL void BracketQueueInitialize(BracketQueueRef queue)
|
||||
{
|
||||
queue->_firstList.previous = NULL;
|
||||
queue->_firstList.next = NULL;
|
||||
queue->_frontList = NULL;
|
||||
queue->_rearList = NULL;
|
||||
queue->count = 0;
|
||||
queue->shouldDequeue = SBFalse;
|
||||
}
|
||||
|
||||
SB_INTERNAL void BracketQueueReset(BracketQueueRef queue, SBBidiType direction)
|
||||
{
|
||||
queue->_frontList = &queue->_firstList;
|
||||
queue->_rearList = &queue->_firstList;
|
||||
queue->_frontTop = 0;
|
||||
queue->_rearTop = -1;
|
||||
queue->count = 0;
|
||||
queue->shouldDequeue = SBFalse;
|
||||
queue->_direction = direction;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean BracketQueueEnqueue(BracketQueueRef queue,
|
||||
BidiLink priorStrongLink, BidiLink openingLink, SBCodepoint bracket)
|
||||
{
|
||||
/* The queue can only take a maximum of 63 elements. */
|
||||
SBAssert(queue->count < BracketQueueGetMaxCapacity());
|
||||
|
||||
if (BracketQueueInsertElement(queue)) {
|
||||
BracketQueueListRef list = queue->_rearList;
|
||||
SBInteger top = queue->_rearTop;
|
||||
|
||||
list->priorStrongLink[top] = priorStrongLink;
|
||||
list->openingLink[top] = openingLink;
|
||||
list->closingLink[top] = BidiLinkNone;
|
||||
list->bracket[top] = bracket;
|
||||
list->strongType[top] = SBBidiTypeNil;
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
SB_INTERNAL void BracketQueueDequeue(BracketQueueRef queue)
|
||||
{
|
||||
/* The queue must NOT be empty. */
|
||||
SBAssert(queue->count != 0);
|
||||
|
||||
if (queue->_frontTop != BracketQueueList_MaxIndex) {
|
||||
queue->_frontTop += 1;
|
||||
} else {
|
||||
BracketQueueListRef frontList = queue->_frontList;
|
||||
|
||||
if (frontList == queue->_rearList) {
|
||||
queue->_rearTop = -1;
|
||||
} else {
|
||||
queue->_frontList = frontList->next;
|
||||
}
|
||||
|
||||
queue->_frontTop = 0;
|
||||
}
|
||||
|
||||
queue->count -= 1;
|
||||
}
|
||||
|
||||
SB_INTERNAL void BracketQueueSetStrongType(BracketQueueRef queue, SBBidiType strongType)
|
||||
{
|
||||
BracketQueueListRef list = queue->_rearList;
|
||||
SBInteger top = queue->_rearTop;
|
||||
|
||||
while (1) {
|
||||
SBInteger limit = (list == queue->_frontList ? queue->_frontTop : 0);
|
||||
|
||||
do {
|
||||
if (list->closingLink[top] == BidiLinkNone
|
||||
&& list->strongType[top] != queue->_direction) {
|
||||
list->strongType[top] = strongType;
|
||||
}
|
||||
} while (top-- > limit);
|
||||
|
||||
if (list == queue->_frontList) {
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->previous;
|
||||
top = BracketQueueList_MaxIndex;
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void BracketQueueClosePair(BracketQueueRef queue, BidiLink closingLink, SBCodepoint bracket)
|
||||
{
|
||||
BracketQueueListRef list = queue->_rearList;
|
||||
SBInteger top = queue->_rearTop;
|
||||
SBCodepoint canonical;
|
||||
|
||||
switch (bracket) {
|
||||
case 0x232A:
|
||||
canonical = 0x3009;
|
||||
break;
|
||||
|
||||
case 0x3009:
|
||||
canonical = 0x232A;
|
||||
break;
|
||||
|
||||
default:
|
||||
canonical = bracket;
|
||||
break;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
SBBoolean isFrontList = (list == queue->_frontList);
|
||||
SBInteger limit = (isFrontList ? queue->_frontTop : 0);
|
||||
|
||||
do {
|
||||
if (list->openingLink[top] != BidiLinkNone
|
||||
&& list->closingLink[top] == BidiLinkNone
|
||||
&& (list->bracket[top] == bracket || list->bracket[top] == canonical)) {
|
||||
list->closingLink[top] = closingLink;
|
||||
BracketQueueFinalizePairs(queue, list, top);
|
||||
|
||||
if (isFrontList && top == queue->_frontTop) {
|
||||
queue->shouldDequeue = SBTrue;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
} while (top-- > limit);
|
||||
|
||||
if (isFrontList) {
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->previous;
|
||||
top = BracketQueueList_MaxIndex;
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean BracketQueueShouldDequeue(BracketQueueRef queue)
|
||||
{
|
||||
return queue->shouldDequeue;
|
||||
}
|
||||
|
||||
SB_INTERNAL BidiLink BracketQueueGetPriorStrongLink(BracketQueueRef queue)
|
||||
{
|
||||
return queue->_frontList->priorStrongLink[queue->_frontTop];
|
||||
}
|
||||
|
||||
SB_INTERNAL BidiLink BracketQueueGetOpeningLink(BracketQueueRef queue)
|
||||
{
|
||||
return queue->_frontList->openingLink[queue->_frontTop];
|
||||
}
|
||||
|
||||
SB_INTERNAL BidiLink BracketQueueGetClosingLink(BracketQueueRef queue)
|
||||
{
|
||||
return queue->_frontList->closingLink[queue->_frontTop];
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBidiType BracketQueueGetStrongType(BracketQueueRef queue)
|
||||
{
|
||||
return queue->_frontList->strongType[queue->_frontTop];
|
||||
}
|
||||
|
||||
SB_INTERNAL void BracketQueueFinalize(BracketQueueRef queue)
|
||||
{
|
||||
BracketQueueListRef list = queue->_firstList.next;
|
||||
|
||||
while (list) {
|
||||
BracketQueueListRef next = list->next;
|
||||
free(list);
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_BRACKET_QUEUE_H
|
||||
#define _SB_INTERNAL_BRACKET_QUEUE_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
|
||||
#include "BidiChain.h"
|
||||
#include "SBBase.h"
|
||||
|
||||
#define BracketQueueList_Length 8
|
||||
#define BracketQueueList_MaxIndex (BracketQueueList_Length - 1)
|
||||
|
||||
typedef struct _BracketQueueList {
|
||||
SBCodepoint bracket[BracketQueueList_Length];
|
||||
BidiLink priorStrongLink[BracketQueueList_Length];
|
||||
BidiLink openingLink[BracketQueueList_Length];
|
||||
BidiLink closingLink[BracketQueueList_Length];
|
||||
SBBidiType strongType[BracketQueueList_Length];
|
||||
|
||||
struct _BracketQueueList *previous;
|
||||
struct _BracketQueueList *next;
|
||||
} BracketQueueList, *BracketQueueListRef;
|
||||
|
||||
typedef struct _BracketQueue {
|
||||
BracketQueueList _firstList;
|
||||
BracketQueueListRef _frontList;
|
||||
BracketQueueListRef _rearList;
|
||||
SBInteger _frontTop;
|
||||
SBInteger _rearTop;
|
||||
SBUInteger count;
|
||||
SBBoolean shouldDequeue;
|
||||
SBBidiType _direction;
|
||||
} BracketQueue, *BracketQueueRef;
|
||||
|
||||
#define BracketQueueGetMaxCapacity() 63
|
||||
|
||||
SB_INTERNAL void BracketQueueInitialize(BracketQueueRef queue);
|
||||
SB_INTERNAL void BracketQueueReset(BracketQueueRef queue, SBBidiType direction);
|
||||
|
||||
SB_INTERNAL SBBoolean BracketQueueEnqueue(BracketQueueRef queue,
|
||||
BidiLink priorStrongLink, BidiLink openingLink, SBCodepoint bracket);
|
||||
SB_INTERNAL void BracketQueueDequeue(BracketQueueRef queue);
|
||||
|
||||
SB_INTERNAL void BracketQueueSetStrongType(BracketQueueRef queue, SBBidiType strongType);
|
||||
SB_INTERNAL void BracketQueueClosePair(BracketQueueRef queue,
|
||||
BidiLink closingLink, SBCodepoint bracket);
|
||||
|
||||
SB_INTERNAL SBBoolean BracketQueueShouldDequeue(BracketQueueRef queue);
|
||||
|
||||
SB_INTERNAL BidiLink BracketQueueGetPriorStrongLink(BracketQueueRef queue);
|
||||
SB_INTERNAL BidiLink BracketQueueGetOpeningLink(BracketQueueRef queue);
|
||||
SB_INTERNAL BidiLink BracketQueueGetClosingLink(BracketQueueRef queue);
|
||||
SB_INTERNAL SBBidiType BracketQueueGetStrongType(BracketQueueRef queue);
|
||||
|
||||
SB_INTERNAL void BracketQueueFinalize(BracketQueueRef queue);
|
||||
|
||||
#endif
|
||||
32
modules/juce_graphics/unicode/sheenbidi/Source/BracketType.h
Normal file
32
modules/juce_graphics/unicode/sheenbidi/Source/BracketType.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_BRACKET_TYPE_H
|
||||
#define _SB_INTERNAL_BRACKET_TYPE_H
|
||||
|
||||
#include "SBBase.h"
|
||||
|
||||
enum {
|
||||
BracketTypeNone = 0x00,
|
||||
BracketTypeOpen = 0x40, /**< Opening paired bracket. */
|
||||
BracketTypeClose = 0x80, /**< Closing paired bracket. */
|
||||
|
||||
BracketTypePrimaryMask = BracketTypeOpen | BracketTypeClose,
|
||||
BracketTypeInverseMask = ~BracketTypePrimaryMask
|
||||
};
|
||||
typedef SBUInt8 BracketType;
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Automatically generated by SheenBidiGenerator tool.
|
||||
* DO NOT EDIT!!
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_GENERAL_CATEGORY_LOOKUP_H
|
||||
#define _SB_INTERNAL_GENERAL_CATEGORY_LOOKUP_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
#include <SBGeneralCategory.h>
|
||||
|
||||
#include "SBBase.h"
|
||||
|
||||
SB_INTERNAL SBGeneralCategory LookupGeneralCategory(SBCodepoint codepoint);
|
||||
|
||||
#endif
|
||||
537
modules/juce_graphics/unicode/sheenbidi/Source/IsolatingRun.c
Normal file
537
modules/juce_graphics/unicode/sheenbidi/Source/IsolatingRun.c
Normal file
|
|
@ -0,0 +1,537 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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 <SBConfig.h>
|
||||
|
||||
#include "BidiChain.h"
|
||||
#include "BracketQueue.h"
|
||||
#include "BracketType.h"
|
||||
#include "LevelRun.h"
|
||||
#include "PairingLookup.h"
|
||||
#include "SBAssert.h"
|
||||
#include "SBBase.h"
|
||||
#include "SBLog.h"
|
||||
#include "IsolatingRun.h"
|
||||
|
||||
static void ResolveAvailableBracketPairs(IsolatingRunRef isolatingRun);
|
||||
|
||||
static void AttachLevelRunLinks(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BidiChainRef chain = isolatingRun->bidiChain;
|
||||
LevelRunRef baseLevelRun = isolatingRun->baseLevelRun;
|
||||
LevelRunRef current;
|
||||
LevelRunRef next;
|
||||
|
||||
isolatingRun->_originalLink = BidiChainGetNext(chain, chain->roller);
|
||||
BidiChainSetNext(chain, chain->roller, baseLevelRun->firstLink);
|
||||
|
||||
/* Iterate over level runs and attach their links to form an isolating run. */
|
||||
for (current = baseLevelRun; (next = current->next); current = next) {
|
||||
BidiChainSetNext(chain, current->lastLink, next->firstLink);
|
||||
}
|
||||
BidiChainSetNext(chain, current->lastLink, chain->roller);
|
||||
|
||||
isolatingRun->_lastLevelRun = current;
|
||||
isolatingRun->_sos = RunExtrema_SOR(baseLevelRun->extrema);
|
||||
|
||||
if (!RunKindIsPartialIsolate(baseLevelRun->kind)) {
|
||||
isolatingRun->_eos = RunExtrema_EOR(current->extrema);
|
||||
} else {
|
||||
SBLevel paragraphLevel = isolatingRun->paragraphLevel;
|
||||
SBLevel runLevel = baseLevelRun->level;
|
||||
SBLevel eosLevel = (runLevel > paragraphLevel ? runLevel : paragraphLevel);
|
||||
isolatingRun->_eos = ((eosLevel & 1) ? SBBidiTypeR : SBBidiTypeL);
|
||||
}
|
||||
}
|
||||
|
||||
static void AttachOriginalLinks(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BidiChainRef chain = isolatingRun->bidiChain;
|
||||
LevelRunRef current;
|
||||
|
||||
BidiChainSetNext(chain, chain->roller, isolatingRun->_originalLink);
|
||||
|
||||
/* Iterate over level runs and attach original subsequent links. */
|
||||
for (current = isolatingRun->baseLevelRun; current; current = current->next) {
|
||||
BidiChainSetNext(chain, current->lastLink, current->subsequentLink);
|
||||
}
|
||||
}
|
||||
|
||||
static BidiLink ResolveWeakTypes(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BidiChainRef chain = isolatingRun->bidiChain;
|
||||
BidiLink roller = chain->roller;
|
||||
BidiLink link;
|
||||
|
||||
BidiLink priorLink;
|
||||
SBBidiType sos;
|
||||
|
||||
SBBidiType w1PriorType;
|
||||
SBBidiType w2StrongType;
|
||||
SBBidiType w4PriorType;
|
||||
SBBidiType w5PriorType;
|
||||
SBBidiType w7StrongType;
|
||||
|
||||
priorLink = roller;
|
||||
sos = isolatingRun->_sos;
|
||||
|
||||
w1PriorType = sos;
|
||||
w2StrongType = sos;
|
||||
|
||||
BidiChainForEach(chain, roller, link) {
|
||||
SBBidiType type = BidiChainGetType(chain, link);
|
||||
SBBoolean forceMerge = SBFalse;
|
||||
|
||||
/* Rule W1 */
|
||||
if (type == SBBidiTypeNSM) {
|
||||
/* Change the 'type' variable as well because it can be EN on which W2 depends. */
|
||||
type = (SBBidiTypeIsIsolate(w1PriorType) ? SBBidiTypeON : w1PriorType);
|
||||
BidiChainSetType(chain, link, type);
|
||||
|
||||
/* Fix for 3rd point of rule N0. */
|
||||
if (w1PriorType == SBBidiTypeON) {
|
||||
forceMerge = SBTrue;
|
||||
}
|
||||
}
|
||||
w1PriorType = type;
|
||||
|
||||
/* Rule W2 */
|
||||
if (type == SBBidiTypeEN) {
|
||||
if (w2StrongType == SBBidiTypeAL) {
|
||||
BidiChainSetType(chain, link, SBBidiTypeAN);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Rule W3
|
||||
* NOTE: It is safe to apply W3 in 'else-if' statement because it only depends on type AL.
|
||||
* Even if W2 changes EN to AN, there won't be any harm.
|
||||
*/
|
||||
else if (type == SBBidiTypeAL) {
|
||||
BidiChainSetType(chain, link, SBBidiTypeR);
|
||||
}
|
||||
|
||||
if (SBBidiTypeIsStrong(type)) {
|
||||
/* Save the strong type as it is checked in W2. */
|
||||
w2StrongType = type;
|
||||
}
|
||||
|
||||
if ((type != SBBidiTypeON && BidiChainGetType(chain, priorLink) == type) || forceMerge) {
|
||||
BidiChainAbandonNext(chain, priorLink);
|
||||
} else {
|
||||
priorLink = link;
|
||||
}
|
||||
}
|
||||
|
||||
priorLink = roller;
|
||||
w4PriorType = sos;
|
||||
w5PriorType = sos;
|
||||
w7StrongType = sos;
|
||||
|
||||
BidiChainForEach(chain, roller, link) {
|
||||
SBBidiType type = BidiChainGetType(chain, link);
|
||||
SBBidiType nextType = BidiChainGetType(chain, BidiChainGetNext(chain, link));
|
||||
|
||||
/* Rule W4 */
|
||||
if (BidiChainIsSingle(chain, link)
|
||||
&& SBBidiTypeIsNumberSeparator(type)
|
||||
&& SBBidiTypeIsNumber(w4PriorType)
|
||||
&& (w4PriorType == nextType)
|
||||
&& (w4PriorType == SBBidiTypeEN || type == SBBidiTypeCS))
|
||||
{
|
||||
/* Change the current type as well because it can be EN on which W5 depends. */
|
||||
type = w4PriorType;
|
||||
BidiChainSetType(chain, link, type);
|
||||
}
|
||||
w4PriorType = type;
|
||||
|
||||
/* Rule W5 */
|
||||
if (type == SBBidiTypeET && (w5PriorType == SBBidiTypeEN || nextType == SBBidiTypeEN)) {
|
||||
/* Change the current type as well because it is EN on which W7 depends. */
|
||||
type = SBBidiTypeEN;
|
||||
BidiChainSetType(chain, link, type);
|
||||
}
|
||||
w5PriorType = type;
|
||||
|
||||
switch (type) {
|
||||
/* Rule W6 */
|
||||
case SBBidiTypeET:
|
||||
case SBBidiTypeCS:
|
||||
case SBBidiTypeES:
|
||||
BidiChainSetType(chain, link, SBBidiTypeON);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Rule W7
|
||||
* NOTE: W7 is expected to be applied after W6. However this is not the case here. The
|
||||
* reason is that W6 can only create the type ON which is not tested in W7 by any
|
||||
* means. So it won't affect the algorithm.
|
||||
*/
|
||||
case SBBidiTypeEN:
|
||||
if (w7StrongType == SBBidiTypeL) {
|
||||
BidiChainSetType(chain, link, SBBidiTypeL);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Save the strong type for W7.
|
||||
* NOTE: The strong type is expected to be saved after applying W7 because W7 itself creates
|
||||
* a strong type. However the strong type being saved here is based on the type after
|
||||
* W5. This won't effect the algorithm because a single link contains all consecutive
|
||||
* EN types. This means that even if W7 creates a strong type, it will be saved in
|
||||
* next iteration.
|
||||
*/
|
||||
case SBBidiTypeL:
|
||||
case SBBidiTypeR:
|
||||
w7StrongType = type;
|
||||
break;
|
||||
}
|
||||
|
||||
if (type != SBBidiTypeON && BidiChainGetType(chain, priorLink) == type) {
|
||||
BidiChainAbandonNext(chain, priorLink);
|
||||
} else {
|
||||
priorLink = link;
|
||||
}
|
||||
}
|
||||
|
||||
return priorLink;
|
||||
}
|
||||
|
||||
static SBBoolean ResolveBrackets(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
const SBCodepointSequence *sequence = isolatingRun->codepointSequence;
|
||||
SBUInteger paragraphOffset = isolatingRun->paragraphOffset;
|
||||
BracketQueueRef queue = &isolatingRun->_bracketQueue;
|
||||
BidiChainRef chain = isolatingRun->bidiChain;
|
||||
BidiLink roller = chain->roller;
|
||||
BidiLink link;
|
||||
|
||||
BidiLink priorStrongLink;
|
||||
SBLevel runLevel;
|
||||
|
||||
priorStrongLink = BidiLinkNone;
|
||||
runLevel = isolatingRun->baseLevelRun->level;
|
||||
|
||||
BracketQueueReset(queue, SBLevelAsNormalBidiType(runLevel));
|
||||
|
||||
BidiChainForEach(chain, roller, link) {
|
||||
SBUInteger stringIndex;
|
||||
SBCodepoint codepoint;
|
||||
SBBidiType type;
|
||||
|
||||
SBCodepoint bracketValue;
|
||||
BracketType bracketType;
|
||||
|
||||
type = BidiChainGetType(chain, link);
|
||||
|
||||
switch (type) {
|
||||
case SBBidiTypeON:
|
||||
stringIndex = BidiChainGetOffset(chain, link) + paragraphOffset;
|
||||
codepoint = SBCodepointSequenceGetCodepointAt(sequence, &stringIndex);
|
||||
bracketValue = LookupBracketPair(codepoint, &bracketType);
|
||||
|
||||
switch (bracketType) {
|
||||
case BracketTypeOpen:
|
||||
if (queue->count < BracketQueueGetMaxCapacity()) {
|
||||
if (!BracketQueueEnqueue(queue, priorStrongLink, link, bracketValue)) {
|
||||
return SBFalse;
|
||||
}
|
||||
} else {
|
||||
goto Resolve;
|
||||
}
|
||||
break;
|
||||
|
||||
case BracketTypeClose:
|
||||
if (queue->count != 0) {
|
||||
BracketQueueClosePair(queue, link, codepoint);
|
||||
|
||||
if (BracketQueueShouldDequeue(queue)) {
|
||||
ResolveAvailableBracketPairs(isolatingRun);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SBBidiTypeEN:
|
||||
case SBBidiTypeAN:
|
||||
type = SBBidiTypeR;
|
||||
|
||||
case SBBidiTypeR:
|
||||
case SBBidiTypeL:
|
||||
if (queue->count != 0) {
|
||||
BracketQueueSetStrongType(queue, type);
|
||||
}
|
||||
|
||||
priorStrongLink = link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Resolve:
|
||||
ResolveAvailableBracketPairs(isolatingRun);
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
static void ResolveAvailableBracketPairs(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BracketQueueRef queue = &isolatingRun->_bracketQueue;
|
||||
BidiChainRef chain = isolatingRun->bidiChain;
|
||||
|
||||
SBLevel runLevel;
|
||||
SBBidiType embeddingDirection;
|
||||
SBBidiType oppositeDirection;
|
||||
|
||||
runLevel = isolatingRun->baseLevelRun->level;
|
||||
embeddingDirection = SBLevelAsNormalBidiType(runLevel);
|
||||
oppositeDirection = SBLevelAsOppositeBidiType(runLevel);
|
||||
|
||||
while (queue->count != 0) {
|
||||
BidiLink openingLink = BracketQueueGetOpeningLink(queue);
|
||||
BidiLink closingLink = BracketQueueGetClosingLink(queue);
|
||||
|
||||
if ((openingLink != BidiLinkNone) && (closingLink != BidiLinkNone)) {
|
||||
SBBidiType innerStrongType;
|
||||
SBBidiType pairType;
|
||||
|
||||
innerStrongType = BracketQueueGetStrongType(queue);
|
||||
|
||||
/* Rule: N0.b */
|
||||
if (innerStrongType == embeddingDirection) {
|
||||
pairType = innerStrongType;
|
||||
}
|
||||
/* Rule: N0.c */
|
||||
else if (innerStrongType == oppositeDirection) {
|
||||
BidiLink priorStrongLink;
|
||||
SBBidiType priorStrongType;
|
||||
|
||||
priorStrongLink = BracketQueueGetPriorStrongLink(queue);
|
||||
|
||||
if (priorStrongLink != BidiLinkNone) {
|
||||
BidiLink link;
|
||||
|
||||
priorStrongType = BidiChainGetType(chain, priorStrongLink);
|
||||
if (SBBidiTypeIsNumber(priorStrongType)) {
|
||||
priorStrongType = SBBidiTypeR;
|
||||
}
|
||||
|
||||
link = BidiChainGetNext(chain, priorStrongLink);
|
||||
|
||||
while (link != openingLink) {
|
||||
SBBidiType type = BidiChainGetType(chain, link);
|
||||
if (type == SBBidiTypeL || type == SBBidiTypeR) {
|
||||
priorStrongType = type;
|
||||
}
|
||||
|
||||
link = BidiChainGetNext(chain, link);
|
||||
}
|
||||
} else {
|
||||
priorStrongType = isolatingRun->_sos;
|
||||
}
|
||||
|
||||
/* Rule: N0.c.1 */
|
||||
if (priorStrongType == oppositeDirection) {
|
||||
pairType = oppositeDirection;
|
||||
}
|
||||
/* Rule: N0.c.2 */
|
||||
else {
|
||||
pairType = embeddingDirection;
|
||||
}
|
||||
}
|
||||
/* Rule: N0.d */
|
||||
else {
|
||||
pairType = SBBidiTypeNil;
|
||||
}
|
||||
|
||||
if (pairType != SBBidiTypeNil) {
|
||||
/* Do the substitution */
|
||||
BidiChainSetType(chain, openingLink, pairType);
|
||||
BidiChainSetType(chain, closingLink, pairType);
|
||||
}
|
||||
}
|
||||
|
||||
BracketQueueDequeue(queue);
|
||||
}
|
||||
}
|
||||
|
||||
static void ResolveNeutrals(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BidiChainRef chain = isolatingRun->bidiChain;
|
||||
BidiLink roller = chain->roller;
|
||||
BidiLink link;
|
||||
|
||||
SBLevel runLevel;
|
||||
SBBidiType strongType;
|
||||
BidiLink neutralLink;
|
||||
|
||||
runLevel = isolatingRun->baseLevelRun->level;
|
||||
strongType = isolatingRun->_sos;
|
||||
neutralLink = BidiLinkNone;
|
||||
|
||||
BidiChainForEach(chain, roller, link) {
|
||||
SBBidiType type = BidiChainGetType(chain, link);
|
||||
SBBidiType nextType;
|
||||
|
||||
SBAssert(SBBidiTypeIsStrongOrNumber(type) || SBBidiTypeIsNeutralOrIsolate(type));
|
||||
|
||||
switch (type) {
|
||||
case SBBidiTypeL:
|
||||
strongType = SBBidiTypeL;
|
||||
break;
|
||||
|
||||
case SBBidiTypeR:
|
||||
case SBBidiTypeEN:
|
||||
case SBBidiTypeAN:
|
||||
strongType = SBBidiTypeR;
|
||||
break;
|
||||
|
||||
case SBBidiTypeB:
|
||||
case SBBidiTypeS:
|
||||
case SBBidiTypeWS:
|
||||
case SBBidiTypeON:
|
||||
case SBBidiTypeLRI:
|
||||
case SBBidiTypeRLI:
|
||||
case SBBidiTypeFSI:
|
||||
case SBBidiTypePDI:
|
||||
if (neutralLink == BidiLinkNone) {
|
||||
neutralLink = link;
|
||||
}
|
||||
|
||||
nextType = BidiChainGetType(chain, BidiChainGetNext(chain, link));
|
||||
if (SBBidiTypeIsNumber(nextType)) {
|
||||
nextType = SBBidiTypeR;
|
||||
} else if (nextType == SBBidiTypeNil) {
|
||||
nextType = isolatingRun->_eos;
|
||||
}
|
||||
|
||||
if (SBBidiTypeIsStrong(nextType)) {
|
||||
/* Rules N1, N2 */
|
||||
SBBidiType resolvedType = (strongType == nextType
|
||||
? strongType
|
||||
: SBLevelAsNormalBidiType(runLevel));
|
||||
|
||||
do {
|
||||
BidiChainSetType(chain, neutralLink, resolvedType);
|
||||
neutralLink = BidiChainGetNext(chain, neutralLink);
|
||||
} while (neutralLink != BidiChainGetNext(chain, link));
|
||||
|
||||
neutralLink = BidiLinkNone;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ResolveImplicitLevels(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BidiChainRef chain = isolatingRun->bidiChain;
|
||||
BidiLink roller = chain->roller;
|
||||
BidiLink link;
|
||||
|
||||
SBLevel runLevel = isolatingRun->baseLevelRun->level;
|
||||
|
||||
if ((runLevel & 1) == 0) {
|
||||
BidiChainForEach(chain, roller, link) {
|
||||
SBBidiType type = BidiChainGetType(chain, link);
|
||||
SBLevel level = BidiChainGetLevel(chain, link);
|
||||
|
||||
SBAssert(SBBidiTypeIsStrongOrNumber(type));
|
||||
|
||||
/* Rule I1 */
|
||||
if (type == SBBidiTypeR) {
|
||||
BidiChainSetLevel(chain, link, level + 1);
|
||||
} else if (type != SBBidiTypeL) {
|
||||
BidiChainSetLevel(chain, link, level + 2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BidiChainForEach(chain, roller, link) {
|
||||
SBBidiType type = BidiChainGetType(chain, link);
|
||||
SBLevel level = BidiChainGetLevel(chain, link);
|
||||
|
||||
SBAssert(SBBidiTypeIsStrongOrNumber(type));
|
||||
|
||||
/* Rule I2 */
|
||||
if (type != SBBidiTypeR) {
|
||||
BidiChainSetLevel(chain, link, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void IsolatingRunInitialize(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BracketQueueInitialize(&isolatingRun->_bracketQueue);
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean IsolatingRunResolve(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BidiLink lastLink;
|
||||
BidiLink subsequentLink;
|
||||
|
||||
SB_LOG_BLOCK_OPENER("Identified Isolating Run");
|
||||
|
||||
/* Attach level run links to form isolating run. */
|
||||
AttachLevelRunLinks(isolatingRun);
|
||||
/* Save last subsequent link. */
|
||||
subsequentLink = isolatingRun->_lastLevelRun->subsequentLink;
|
||||
|
||||
SB_LOG_STATEMENT("Range", 1, SB_LOG_RUN_RANGE(isolatingRun));
|
||||
SB_LOG_STATEMENT("Types", 1, SB_LOG_RUN_TYPES(isolatingRun));
|
||||
SB_LOG_STATEMENT("Level", 1, SB_LOG_LEVEL(isolatingRun->baseLevelRun->level));
|
||||
SB_LOG_STATEMENT("SOS", 1, SB_LOG_BIDI_TYPE(isolatingRun->_sos));
|
||||
SB_LOG_STATEMENT("EOS", 1, SB_LOG_BIDI_TYPE(isolatingRun->_eos));
|
||||
|
||||
/* Rules W1-W7 */
|
||||
lastLink = ResolveWeakTypes(isolatingRun);
|
||||
SB_LOG_BLOCK_OPENER("Resolved Weak Types");
|
||||
SB_LOG_STATEMENT("Types", 1, SB_LOG_RUN_TYPES(isolatingRun));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
/* Rule N0 */
|
||||
if (!ResolveBrackets(isolatingRun)) {
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
SB_LOG_BLOCK_OPENER("Resolved Brackets");
|
||||
SB_LOG_STATEMENT("Types", 1, SB_LOG_RUN_TYPES(isolatingRun));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
/* Rules N1, N2 */
|
||||
ResolveNeutrals(isolatingRun);
|
||||
SB_LOG_BLOCK_OPENER("Resolved Neutrals");
|
||||
SB_LOG_STATEMENT("Types", 1, SB_LOG_RUN_TYPES(isolatingRun));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
/* Rules I1, I2 */
|
||||
ResolveImplicitLevels(isolatingRun);
|
||||
SB_LOG_BLOCK_OPENER("Resolved Implicit Levels");
|
||||
SB_LOG_STATEMENT("Levels", 1, SB_LOG_RUN_LEVELS(isolatingRun));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
/* Re-attach original links. */
|
||||
AttachOriginalLinks(isolatingRun);
|
||||
/* Attach new final link (of isolating run) with last subsequent link. */
|
||||
BidiChainSetNext(isolatingRun->bidiChain, lastLink, subsequentLink);
|
||||
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
SB_INTERNAL void IsolatingRunFinalize(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
BracketQueueFinalize(&isolatingRun->_bracketQueue);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_ISOLATING_RUN_H
|
||||
#define _SB_INTERNAL_ISOLATING_RUN_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
|
||||
#include "BidiChain.h"
|
||||
#include "BracketQueue.h"
|
||||
#include "LevelRun.h"
|
||||
#include "SBBase.h"
|
||||
#include "SBCodepointSequence.h"
|
||||
|
||||
typedef struct _IsolatingRun {
|
||||
const SBCodepointSequence *codepointSequence;
|
||||
const SBBidiType *bidiTypes;
|
||||
BidiChainRef bidiChain;
|
||||
LevelRunRef baseLevelRun;
|
||||
LevelRunRef _lastLevelRun;
|
||||
BracketQueue _bracketQueue;
|
||||
SBUInteger paragraphOffset;
|
||||
BidiLink _originalLink;
|
||||
SBBidiType _sos;
|
||||
SBBidiType _eos;
|
||||
SBLevel paragraphLevel;
|
||||
} IsolatingRun, *IsolatingRunRef;
|
||||
|
||||
SB_INTERNAL void IsolatingRunInitialize(IsolatingRunRef isolatingRun);
|
||||
SB_INTERNAL SBBoolean IsolatingRunResolve(IsolatingRunRef isolatingRun);
|
||||
|
||||
SB_INTERNAL void IsolatingRunFinalize(IsolatingRunRef isolatingRun);
|
||||
|
||||
#endif
|
||||
68
modules/juce_graphics/unicode/sheenbidi/Source/LevelRun.c
Normal file
68
modules/juce_graphics/unicode/sheenbidi/Source/LevelRun.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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 <SBConfig.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "BidiChain.h"
|
||||
#include "RunExtrema.h"
|
||||
#include "RunKind.h"
|
||||
#include "SBAssert.h"
|
||||
#include "LevelRun.h"
|
||||
|
||||
SB_INTERNAL void LevelRunInitialize(LevelRunRef levelRun,
|
||||
BidiChainRef bidiChain, BidiLink firstLink, BidiLink lastLink,
|
||||
SBBidiType sor, SBBidiType eor)
|
||||
{
|
||||
SBBidiType firstType = BidiChainGetType(bidiChain, firstLink);
|
||||
SBBidiType lastType = BidiChainGetType(bidiChain, lastLink);
|
||||
|
||||
levelRun->next = NULL;
|
||||
levelRun->firstLink = firstLink;
|
||||
levelRun->lastLink = lastLink;
|
||||
levelRun->subsequentLink = BidiChainGetNext(bidiChain, lastLink);
|
||||
levelRun->extrema = RunExtremaMake(sor, eor);
|
||||
levelRun->kind = RunKindMake
|
||||
(
|
||||
SBBidiTypeIsIsolateInitiator(lastType),
|
||||
SBBidiTypeIsIsolateTerminator(firstType)
|
||||
);
|
||||
levelRun->level = BidiChainGetLevel(bidiChain, firstLink);
|
||||
}
|
||||
|
||||
SB_INTERNAL void LevelRunAttach(LevelRunRef levelRun, LevelRunRef next)
|
||||
{
|
||||
/* Only the runs of same level can be attached. */
|
||||
SBAssert(levelRun->level == next->level);
|
||||
/* No other run can be attached with a simple run. */
|
||||
SBAssert(!RunKindIsSimple(levelRun->kind));
|
||||
/* No other run can be attached with a complete isolating run. */
|
||||
SBAssert(!RunKindIsCompleteIsolate(levelRun->kind));
|
||||
/* Only a terminating run can be attached with an isolating run. */
|
||||
SBAssert(RunKindIsIsolate(levelRun->kind) && RunKindIsTerminating(next->kind));
|
||||
/* The next run must be unattached. */
|
||||
SBAssert(!RunKindIsAttachedTerminating(next->kind));
|
||||
|
||||
if (RunKindIsTerminating(next->kind)) {
|
||||
RunKindMakeAttached(next->kind);
|
||||
}
|
||||
|
||||
if (RunKindIsIsolate(levelRun->kind)) {
|
||||
RunKindMakeComplete(levelRun->kind);
|
||||
}
|
||||
|
||||
levelRun->next = next;
|
||||
}
|
||||
42
modules/juce_graphics/unicode/sheenbidi/Source/LevelRun.h
Normal file
42
modules/juce_graphics/unicode/sheenbidi/Source/LevelRun.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_LEVEL_RUN_H
|
||||
#define _SB_INTERNAL_LEVEL_RUN_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
|
||||
#include "BidiChain.h"
|
||||
#include "RunExtrema.h"
|
||||
#include "RunKind.h"
|
||||
#include "SBBase.h"
|
||||
|
||||
typedef struct _LevelRun {
|
||||
struct _LevelRun *next; /**< Reference to the next sequence of run links. */
|
||||
BidiLink firstLink; /**< First link of the run. */
|
||||
BidiLink lastLink; /**< Last link of the run. */
|
||||
BidiLink subsequentLink; /**< Subsequent link of the run. */
|
||||
RunExtrema extrema;
|
||||
RunKind kind;
|
||||
SBLevel level;
|
||||
} LevelRun, *LevelRunRef;
|
||||
|
||||
SB_INTERNAL void LevelRunInitialize(LevelRunRef levelRun,
|
||||
BidiChainRef bidiChain, BidiLink firstLink, BidiLink lastLink,
|
||||
SBBidiType sor, SBBidiType eor);
|
||||
SB_INTERNAL void LevelRunAttach(LevelRunRef levelRun, LevelRunRef next);
|
||||
|
||||
#endif
|
||||
267
modules/juce_graphics/unicode/sheenbidi/Source/PairingLookup.c
Normal file
267
modules/juce_graphics/unicode/sheenbidi/Source/PairingLookup.c
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* Automatically generated by SheenBidiGenerator tool.
|
||||
* DO NOT EDIT!!
|
||||
*
|
||||
* REQUIRED MEMORY: (37)+2310+(617*2) = 3618 Bytes
|
||||
*/
|
||||
|
||||
#include "PairingLookup.h"
|
||||
|
||||
static const SBInt16 PairDifferences[37] = {
|
||||
0, 1, -1, 2, -2, 16, -16, 3, -3, 2016, 2527, 1923, 1914, 1918,
|
||||
2250, 138, 7, -7, 1824, 2104, 2108, 2106, 1316, -138, 8, -8, -1316,
|
||||
-1914, -1918, -1923, -1824, -2016, -2104, -2106, -2108, -2250, -2527
|
||||
};
|
||||
|
||||
static const SBUInt8 PairData[2310] = {
|
||||
/* DATA_BLOCK: -- 0x0000..0x0069 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 65, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 132, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x006A..0x00D3 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0,
|
||||
132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x00D4..0x013D -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x013E..0x01A7 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 65, 130, 65, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x01A8..0x0211 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 65, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x0212..0x027B -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 65, 130, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x027C..0x02E5 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 130, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 65, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x02E6..0x034F -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 7, 7, 7, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
|
||||
0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 1,
|
||||
2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x0350..0x03B9 -- */
|
||||
0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 1, 2, 1,
|
||||
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
|
||||
1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 0, 1, 2, 1, 2, 0, 0, 0, 0,
|
||||
0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 19, 0, 20, 21,
|
||||
0, 21, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2, 22, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x03BA..0x0423 -- */
|
||||
0, 1, 2, 1, 2, 23, 0, 0, 1, 2, 0, 0, 0, 0, 1, 2, 1, 2, 1,
|
||||
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
|
||||
0, 0, 1, 2, 24, 24, 24, 0, 16, 16, 0, 0, 25, 25, 25, 17, 17, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 65, 130, 65, 130, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 65, 130, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x0424..0x048D -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65,
|
||||
130, 65, 130, 65, 130, 65, 130, 65, 130, 65, 130, 65, 130, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x048E..0x04F7 -- */
|
||||
0, 0, 0, 1, 2, 65, 130, 0, 1, 2, 0, 3, 0, 4, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 2, 0, 0, 0, 0, 0, 26, 1, 2, 0, 0, 0, 1, 2, 1, 2,
|
||||
65, 130, 65, 130, 65, 130, 65, 130, 65, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x04F8..0x0561 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 65, 130, 65, 130, 65, 130, 65, 130, 65, 130, 71,
|
||||
129, 66, 136, 65, 130, 65, 130, 65, 130, 65, 130, 0, 0, 27, 0, 0, 0, 0, 28,
|
||||
0, 0, 29, 1, 2, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 2, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1,
|
||||
/* DATA_BLOCK: -- 0x0562..0x05CB -- */
|
||||
2, 0, 1, 2, 0, 0, 65, 130, 65, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0,
|
||||
1, 2, 0, 0, 65, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0,
|
||||
0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x05CC..0x0635 -- */
|
||||
1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
|
||||
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
|
||||
1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x0636..0x069F -- */
|
||||
1, 2, 1, 2, 1, 2, 1, 2, 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
|
||||
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
|
||||
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 32,
|
||||
0, 0, 0, 0, 33, 34, 33, 0, 0, 0, 0, 0, 0, 1, 2, 35, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x06A0..0x0709 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x070A..0x0773 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 0,
|
||||
1, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 2, 0, 0, 1, 2, 65, 130, 65, 130, 65, 130, 65, 130, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
65, 130, 65, 130, 65, 130, 65, 130, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x0774..0x07DD -- */
|
||||
65, 130, 65, 130, 65, 130, 65, 130, 65, 130, 0, 0, 65, 130, 65, 130, 65, 130, 65,
|
||||
130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x07DE..0x0847 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 130, 65, 130, 65, 130, 0, 0, 0,
|
||||
0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x0848..0x08B1 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 65, 130, 0, 0, 0, 0, 0, 0,
|
||||
/* DATA_BLOCK: -- 0x08B2..0x0905 -- */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 67, 0, 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,
|
||||
0, 132, 0, 65, 130, 0, 65, 130,
|
||||
};
|
||||
|
||||
static const SBUInt16 PairIndexes[617] = {
|
||||
0x0000, 0x006A, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x013E, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x01A8, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x0212, 0x027C, 0x00D4, 0x00D4, 0x00D4, 0x02E6, 0x0350,
|
||||
0x03BA, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x0424,
|
||||
0x048E, 0x00D4, 0x00D4, 0x00D4, 0x04F8, 0x0562, 0x05CC, 0x0636, 0x00D4, 0x00D4, 0x06A0, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x070A, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x0774, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4,
|
||||
0x00D4, 0x00D4, 0x07DE, 0x0848, 0x08B2
|
||||
};
|
||||
|
||||
SB_INTERNAL SBCodepoint LookupMirror(SBCodepoint codepoint)
|
||||
{
|
||||
if (codepoint <= 0xFF63) {
|
||||
SBInt16 diff = PairDifferences[
|
||||
PairData[
|
||||
PairIndexes[
|
||||
codepoint / 0x06A
|
||||
] + (codepoint % 0x06A)
|
||||
] & BracketTypeInverseMask
|
||||
];
|
||||
|
||||
if (diff != 0) {
|
||||
return (codepoint + diff);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBCodepoint LookupBracketPair(SBCodepoint codepoint, BracketType *type)
|
||||
{
|
||||
if (codepoint <= 0xFF63) {
|
||||
SBUInt8 data = PairData[
|
||||
PairIndexes[
|
||||
codepoint / 0x06A
|
||||
] + (codepoint % 0x06A)
|
||||
];
|
||||
*type = (data & BracketTypePrimaryMask);
|
||||
|
||||
if (*type != 0) {
|
||||
SBInt16 diff = PairDifferences[
|
||||
data & BracketTypeInverseMask
|
||||
];
|
||||
return (codepoint + diff);
|
||||
}
|
||||
} else {
|
||||
*type = BracketTypeNone;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Automatically generated by SheenBidiGenerator tool.
|
||||
* DO NOT EDIT!!
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_PAIRING_LOOKUP_H
|
||||
#define _SB_INTERNAL_PAIRING_LOOKUP_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
|
||||
#include "BracketType.h"
|
||||
#include "SBBase.h"
|
||||
|
||||
SB_INTERNAL SBCodepoint LookupMirror(SBCodepoint codepoint);
|
||||
SB_INTERNAL SBCodepoint LookupBracketPair(SBCodepoint codepoint, BracketType *bracketType);
|
||||
|
||||
#endif
|
||||
50
modules/juce_graphics/unicode/sheenbidi/Source/RunExtrema.h
Normal file
50
modules/juce_graphics/unicode/sheenbidi/Source/RunExtrema.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_RUN_EXTREMA_H
|
||||
#define _SB_INTERNAL_RUN_EXTREMA_H
|
||||
|
||||
#include "SBBase.h"
|
||||
|
||||
enum {
|
||||
RunExtremaLeadingL = SBBidiTypeL << 0,
|
||||
RunExtremaLeadingR = SBBidiTypeR << 0,
|
||||
|
||||
RunExtremaTrailingL = SBBidiTypeL << 4,
|
||||
RunExtremaTrailingR = SBBidiTypeR << 4
|
||||
};
|
||||
typedef SBUInt8 RunExtrema;
|
||||
|
||||
#define RunExtremaMake(sor, eor) \
|
||||
(RunExtrema) \
|
||||
( \
|
||||
((sor) << 0) \
|
||||
| ((eor) << 4) \
|
||||
)
|
||||
|
||||
#define RunExtrema_SOR(e) \
|
||||
(RunExtrema) \
|
||||
( \
|
||||
(e) & 0xF \
|
||||
)
|
||||
|
||||
#define RunExtrema_EOR(e) \
|
||||
(RunExtrema) \
|
||||
( \
|
||||
(e) >> 4 \
|
||||
)
|
||||
|
||||
#endif
|
||||
81
modules/juce_graphics/unicode/sheenbidi/Source/RunKind.h
Normal file
81
modules/juce_graphics/unicode/sheenbidi/Source/RunKind.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_RUN_KIND_H
|
||||
#define _SB_INTERNAL_RUN_KIND_H
|
||||
|
||||
#include "SBBase.h"
|
||||
|
||||
enum {
|
||||
RunKindSimple = 0x00,
|
||||
|
||||
RunKindIsolate = 0x01,
|
||||
RunKindPartial = 0x02,
|
||||
RunKindPartialIsolate = RunKindIsolate | RunKindPartial,
|
||||
|
||||
RunKindTerminating = 0x04,
|
||||
RunKindAttached = 0x08
|
||||
};
|
||||
typedef SBUInt8 RunKind;
|
||||
|
||||
#define RunKindMake(i, t) \
|
||||
( \
|
||||
((i) ? RunKindPartialIsolate : 0) \
|
||||
| ((t) ? RunKindTerminating : 0) \
|
||||
)
|
||||
|
||||
#define RunKindMakeComplete(k) \
|
||||
( \
|
||||
(k) &= ~RunKindPartial \
|
||||
)
|
||||
|
||||
#define RunKindMakeAttached(k) \
|
||||
( \
|
||||
(k) |= RunKindAttached \
|
||||
)
|
||||
|
||||
#define RunKindIsSimple(k) \
|
||||
( \
|
||||
(k) == RunKindSimple \
|
||||
)
|
||||
|
||||
#define RunKindIsIsolate(k) \
|
||||
( \
|
||||
(k) & RunKindIsolate \
|
||||
)
|
||||
|
||||
#define RunKindIsTerminating(k) \
|
||||
( \
|
||||
(k) & RunKindTerminating \
|
||||
)
|
||||
|
||||
#define RunKindIsPartialIsolate(k) \
|
||||
( \
|
||||
(k) & RunKindPartial \
|
||||
)
|
||||
|
||||
#define RunKindIsCompleteIsolate(k) \
|
||||
( \
|
||||
((k) & RunKindPartialIsolate) \
|
||||
== RunKindIsolate \
|
||||
)
|
||||
|
||||
#define RunKindIsAttachedTerminating(k) \
|
||||
( \
|
||||
(k) & RunKindAttached \
|
||||
)
|
||||
|
||||
#endif
|
||||
161
modules/juce_graphics/unicode/sheenbidi/Source/RunQueue.c
Normal file
161
modules/juce_graphics/unicode/sheenbidi/Source/RunQueue.c
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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 <SBConfig.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "LevelRun.h"
|
||||
#include "SBAssert.h"
|
||||
#include "SBBase.h"
|
||||
#include "RunQueue.h"
|
||||
|
||||
static SBBoolean RunQueueInsertElement(RunQueueRef queue)
|
||||
{
|
||||
if (queue->_rearTop != RunQueueList_MaxIndex) {
|
||||
queue->_rearTop += 1;
|
||||
} else {
|
||||
RunQueueListRef previousList = queue->_rearList;
|
||||
RunQueueListRef rearList = previousList->next;
|
||||
|
||||
if (!rearList) {
|
||||
rearList = malloc(sizeof(RunQueueList));
|
||||
if (!rearList) {
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
rearList->previous = previousList;
|
||||
rearList->next = NULL;
|
||||
|
||||
previousList->next = rearList;
|
||||
}
|
||||
|
||||
queue->_rearList = rearList;
|
||||
queue->_rearTop = 0;
|
||||
}
|
||||
queue->count += 1;
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
static void FindPreviousPartialRun(RunQueueRef queue)
|
||||
{
|
||||
RunQueueListRef list = queue->_partialList;
|
||||
SBInteger top = queue->_partialTop;
|
||||
|
||||
do {
|
||||
SBInteger limit = (list == queue->_frontList ? queue->_frontTop : 0);
|
||||
|
||||
do {
|
||||
LevelRunRef levelRun = &list->elements[top];
|
||||
if (RunKindIsPartialIsolate(levelRun->kind)) {
|
||||
queue->_partialList = list;
|
||||
queue->_partialTop = top;
|
||||
return;
|
||||
}
|
||||
} while (top-- > limit);
|
||||
|
||||
list = list->previous;
|
||||
top = RunQueueList_MaxIndex;
|
||||
} while (list);
|
||||
|
||||
queue->_partialList = NULL;
|
||||
queue->_partialTop = -1;
|
||||
queue->shouldDequeue = SBFalse;
|
||||
}
|
||||
|
||||
SB_INTERNAL void RunQueueInitialize(RunQueueRef queue)
|
||||
{
|
||||
/* Initialize first list. */
|
||||
queue->_firstList.previous = NULL;
|
||||
queue->_firstList.next = NULL;
|
||||
|
||||
/* Initialize front and rear lists with first list. */
|
||||
queue->_frontList = &queue->_firstList;
|
||||
queue->_rearList = &queue->_firstList;
|
||||
queue->_partialList = NULL;
|
||||
|
||||
/* Initialize list indexes. */
|
||||
queue->_frontTop = 0;
|
||||
queue->_rearTop = -1;
|
||||
queue->_partialTop = -1;
|
||||
|
||||
/* Initialize rest of the elements. */
|
||||
queue->count = 0;
|
||||
queue->peek = &queue->_frontList->elements[queue->_frontTop];
|
||||
queue->shouldDequeue = SBFalse;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean RunQueueEnqueue(RunQueueRef queue, const LevelRunRef levelRun)
|
||||
{
|
||||
if (RunQueueInsertElement(queue)) {
|
||||
LevelRunRef element = &queue->_rearList->elements[queue->_rearTop];
|
||||
|
||||
/* Copy the level run into the current element. */
|
||||
*element = *levelRun;
|
||||
|
||||
/* Complete the latest isolating run with this terminating run. */
|
||||
if (queue->_partialTop != -1 && RunKindIsTerminating(element->kind)) {
|
||||
LevelRunRef incompleteRun = &queue->_partialList->elements[queue->_partialTop];
|
||||
LevelRunAttach(incompleteRun, element);
|
||||
FindPreviousPartialRun(queue);
|
||||
}
|
||||
|
||||
/* Save the location of the isolating run. */
|
||||
if (RunKindIsIsolate(element->kind)) {
|
||||
queue->_partialList = queue->_rearList;
|
||||
queue->_partialTop = queue->_rearTop;
|
||||
}
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
SB_INTERNAL void RunQueueDequeue(RunQueueRef queue)
|
||||
{
|
||||
/* The queue should not be empty. */
|
||||
SBAssert(queue->count != 0);
|
||||
|
||||
if (queue->_frontTop != RunQueueList_MaxIndex) {
|
||||
queue->_frontTop += 1;
|
||||
} else {
|
||||
RunQueueListRef frontList = queue->_frontList;
|
||||
|
||||
if (frontList == queue->_rearList) {
|
||||
queue->_rearTop = -1;
|
||||
} else {
|
||||
queue->_frontList = frontList->next;
|
||||
}
|
||||
|
||||
queue->_frontTop = 0;
|
||||
}
|
||||
|
||||
queue->count -= 1;
|
||||
queue->peek = &queue->_frontList->elements[queue->_frontTop];
|
||||
}
|
||||
|
||||
SB_INTERNAL void RunQueueFinalize(RunQueueRef queue)
|
||||
{
|
||||
RunQueueListRef list = queue->_firstList.next;
|
||||
|
||||
while (list) {
|
||||
RunQueueListRef next = list->next;
|
||||
free(list);
|
||||
list = next;
|
||||
};
|
||||
}
|
||||
55
modules/juce_graphics/unicode/sheenbidi/Source/RunQueue.h
Normal file
55
modules/juce_graphics/unicode/sheenbidi/Source/RunQueue.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_RUN_QUEUE_H
|
||||
#define _SB_INTERNAL_RUN_QUEUE_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
|
||||
#include "LevelRun.h"
|
||||
#include "SBBase.h"
|
||||
|
||||
#define RunQueueList_Length 8
|
||||
#define RunQueueList_MaxIndex (RunQueueList_Length - 1)
|
||||
|
||||
typedef struct _RunQueueList {
|
||||
LevelRun elements[RunQueueList_Length];
|
||||
|
||||
struct _RunQueueList *previous; /**< Reference to the previous list of queue elements */
|
||||
struct _RunQueueList *next; /**< Reference to the next list of queue elements */
|
||||
} RunQueueList, *RunQueueListRef;
|
||||
|
||||
typedef struct _RunQueue {
|
||||
RunQueueList _firstList; /**< First list of elements, which is part of the queue */
|
||||
RunQueueListRef _frontList; /**< The list containing front element of the queue */
|
||||
RunQueueListRef _rearList; /**< The list containing rear element of the queue */
|
||||
RunQueueListRef _partialList; /**< The list containing latest partial isolating run */
|
||||
SBInteger _frontTop; /**< Index of front element in front list */
|
||||
SBInteger _rearTop; /**< Index of rear element in rear list */
|
||||
SBInteger _partialTop; /**< Index of partial run in partial list */
|
||||
LevelRunRef peek; /**< Peek element of the queue */
|
||||
SBUInteger count; /**< Number of elements the queue contains */
|
||||
SBBoolean shouldDequeue;
|
||||
} RunQueue, *RunQueueRef;
|
||||
|
||||
SB_INTERNAL void RunQueueInitialize(RunQueueRef queue);
|
||||
|
||||
SB_INTERNAL SBBoolean RunQueueEnqueue(RunQueueRef queue, const LevelRunRef levelRun);
|
||||
SB_INTERNAL void RunQueueDequeue(RunQueueRef queue);
|
||||
|
||||
SB_INTERNAL void RunQueueFinalize(RunQueueRef queue);
|
||||
|
||||
#endif
|
||||
203
modules/juce_graphics/unicode/sheenbidi/Source/SBAlgorithm.c
Normal file
203
modules/juce_graphics/unicode/sheenbidi/Source/SBAlgorithm.c
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Copyright (C) 2016-2022 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 <SBConfig.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "BidiTypeLookup.h"
|
||||
#include "SBBase.h"
|
||||
#include "SBCodepointSequence.h"
|
||||
#include "SBLog.h"
|
||||
#include "SBParagraph.h"
|
||||
#include "SBAlgorithm.h"
|
||||
|
||||
static SBAlgorithmRef AllocateAlgorithm(SBUInteger stringLength)
|
||||
{
|
||||
const SBUInteger sizeAlgorithm = sizeof(SBAlgorithm);
|
||||
const SBUInteger sizeTypes = sizeof(SBBidiType) * stringLength;
|
||||
const SBUInteger sizeMemory = sizeAlgorithm + sizeTypes;
|
||||
|
||||
void *pointer = malloc(sizeMemory);
|
||||
|
||||
if (pointer) {
|
||||
const SBUInteger offsetAlgorithm = 0;
|
||||
const SBUInteger offsetTypes = offsetAlgorithm + sizeAlgorithm;
|
||||
|
||||
SBUInt8 *memory = (SBUInt8 *)pointer;
|
||||
SBAlgorithmRef algorithm = (SBAlgorithmRef)(memory + offsetAlgorithm);
|
||||
SBLevel *fixedTypes = (SBLevel *)(memory + offsetTypes);
|
||||
|
||||
algorithm->fixedTypes = fixedTypes;
|
||||
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void DisposeAlgorithm(SBAlgorithmRef algorithm)
|
||||
{
|
||||
free(algorithm);
|
||||
}
|
||||
|
||||
static void DetermineBidiTypes(const SBCodepointSequence *sequence, SBBidiType *types)
|
||||
{
|
||||
SBUInteger stringIndex = 0;
|
||||
SBUInteger firstIndex = 0;
|
||||
SBCodepoint codepoint;
|
||||
|
||||
while ((codepoint = SBCodepointSequenceGetCodepointAt(sequence, &stringIndex)) != SBCodepointInvalid) {
|
||||
types[firstIndex] = LookupBidiType(codepoint);
|
||||
|
||||
/* Subsequent code units get 'BN' type. */
|
||||
while (++firstIndex < stringIndex) {
|
||||
types[firstIndex] = SBBidiTypeBN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SBAlgorithmRef CreateAlgorithm(const SBCodepointSequence *codepointSequence)
|
||||
{
|
||||
SBUInteger stringLength = codepointSequence->stringLength;
|
||||
SBAlgorithmRef algorithm;
|
||||
|
||||
SB_LOG_BLOCK_OPENER("Algorithm Input");
|
||||
SB_LOG_STATEMENT("Codepoints", 1, SB_LOG_CODEPOINT_SEQUENCE(codepointSequence));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
algorithm = AllocateAlgorithm(stringLength);
|
||||
|
||||
if (algorithm) {
|
||||
algorithm->codepointSequence = *codepointSequence;
|
||||
algorithm->retainCount = 1;
|
||||
|
||||
DetermineBidiTypes(codepointSequence, algorithm->fixedTypes);
|
||||
|
||||
SB_LOG_BLOCK_OPENER("Determined Types");
|
||||
SB_LOG_STATEMENT("Types", 1, SB_LOG_BIDI_TYPES_ARRAY(algorithm->fixedTypes, stringLength));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
SB_LOG_BREAKER();
|
||||
}
|
||||
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
SBAlgorithmRef SBAlgorithmCreate(const SBCodepointSequence *codepointSequence)
|
||||
{
|
||||
if (SBCodepointSequenceIsValid(codepointSequence)) {
|
||||
return CreateAlgorithm(codepointSequence);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const SBBidiType *SBAlgorithmGetBidiTypesPtr(SBAlgorithmRef algorithm)
|
||||
{
|
||||
return algorithm->fixedTypes;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBUInteger SBAlgorithmGetSeparatorLength(SBAlgorithmRef algorithm, SBUInteger separatorIndex)
|
||||
{
|
||||
const SBCodepointSequence *codepointSequence = &algorithm->codepointSequence;
|
||||
SBUInteger stringIndex = separatorIndex;
|
||||
SBCodepoint codepoint;
|
||||
SBUInteger separatorLength;
|
||||
|
||||
codepoint = SBCodepointSequenceGetCodepointAt(codepointSequence, &stringIndex);
|
||||
separatorLength = stringIndex - separatorIndex;
|
||||
|
||||
if (codepoint == '\r') {
|
||||
/* Don't break in between 'CR' and 'LF'. */
|
||||
if (stringIndex < codepointSequence->stringLength) {
|
||||
codepoint = SBCodepointSequenceGetCodepointAt(codepointSequence, &stringIndex);
|
||||
|
||||
if (codepoint == '\n') {
|
||||
separatorLength = stringIndex - separatorIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return separatorLength;
|
||||
}
|
||||
|
||||
void SBAlgorithmGetParagraphBoundary(SBAlgorithmRef algorithm,
|
||||
SBUInteger paragraphOffset, SBUInteger suggestedLength,
|
||||
SBUInteger *acutalLength, SBUInteger *separatorLength)
|
||||
{
|
||||
const SBCodepointSequence *codepointSequence = &algorithm->codepointSequence;
|
||||
SBBidiType *bidiTypes = algorithm->fixedTypes;
|
||||
SBUInteger limitIndex;
|
||||
SBUInteger startIndex;
|
||||
|
||||
if (separatorLength) {
|
||||
*separatorLength = 0;
|
||||
}
|
||||
|
||||
SBUIntegerNormalizeRange(codepointSequence->stringLength, ¶graphOffset, &suggestedLength);
|
||||
limitIndex = paragraphOffset + suggestedLength;
|
||||
|
||||
for (startIndex = paragraphOffset; startIndex < limitIndex; startIndex++) {
|
||||
SBBidiType currentType = bidiTypes[startIndex];
|
||||
|
||||
if (currentType == SBBidiTypeB) {
|
||||
SBUInteger codeUnitCount = SBAlgorithmGetSeparatorLength(algorithm, startIndex);
|
||||
|
||||
startIndex += codeUnitCount;
|
||||
|
||||
if (separatorLength) {
|
||||
*separatorLength = codeUnitCount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (acutalLength) {
|
||||
*acutalLength = startIndex - paragraphOffset;
|
||||
}
|
||||
}
|
||||
|
||||
SBParagraphRef SBAlgorithmCreateParagraph(SBAlgorithmRef algorithm,
|
||||
SBUInteger paragraphOffset, SBUInteger suggestedLength, SBLevel baseLevel)
|
||||
{
|
||||
const SBCodepointSequence *codepointSequence = &algorithm->codepointSequence;
|
||||
SBUInteger stringLength = codepointSequence->stringLength;
|
||||
|
||||
SBUIntegerNormalizeRange(stringLength, ¶graphOffset, &suggestedLength);
|
||||
|
||||
if (suggestedLength > 0) {
|
||||
return SBParagraphCreate(algorithm, paragraphOffset, suggestedLength, baseLevel);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SBAlgorithmRef SBAlgorithmRetain(SBAlgorithmRef algorithm)
|
||||
{
|
||||
if (algorithm) {
|
||||
algorithm->retainCount += 1;
|
||||
}
|
||||
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
void SBAlgorithmRelease(SBAlgorithmRef algorithm)
|
||||
{
|
||||
if (algorithm && --algorithm->retainCount == 0) {
|
||||
DisposeAlgorithm(algorithm);
|
||||
}
|
||||
}
|
||||
34
modules/juce_graphics/unicode/sheenbidi/Source/SBAlgorithm.h
Normal file
34
modules/juce_graphics/unicode/sheenbidi/Source/SBAlgorithm.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_ALGORITHM_H
|
||||
#define _SB_INTERNAL_ALGORITHM_H
|
||||
|
||||
#include <SBAlgorithm.h>
|
||||
#include <SBBase.h>
|
||||
#include <SBBidiType.h>
|
||||
#include <SBCodepointSequence.h>
|
||||
#include <SBConfig.h>
|
||||
|
||||
typedef struct _SBAlgorithm {
|
||||
SBCodepointSequence codepointSequence;
|
||||
SBBidiType *fixedTypes;
|
||||
SBUInteger retainCount;
|
||||
} SBAlgorithm;
|
||||
|
||||
SB_INTERNAL SBUInteger SBAlgorithmGetSeparatorLength(SBAlgorithmRef algorithm, SBUInteger separatorIndex);
|
||||
|
||||
#endif
|
||||
24
modules/juce_graphics/unicode/sheenbidi/Source/SBAssert.h
Normal file
24
modules/juce_graphics/unicode/sheenbidi/Source/SBAssert.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_ASSERT_H
|
||||
#define _SB_INTERNAL_ASSERT_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define SBAssert(exp) assert(exp)
|
||||
|
||||
#endif
|
||||
420
modules/juce_graphics/unicode/sheenbidi/Source/SBBase.c
Normal file
420
modules/juce_graphics/unicode/sheenbidi/Source/SBBase.c
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* 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 <SBConfig.h>
|
||||
|
||||
#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');
|
||||
}
|
||||
}
|
||||
108
modules/juce_graphics/unicode/sheenbidi/Source/SBBase.h
Normal file
108
modules/juce_graphics/unicode/sheenbidi/Source/SBBase.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_BASE_H
|
||||
#define _SB_INTERNAL_BASE_H
|
||||
|
||||
#include <SBBase.h>
|
||||
#include <SBBidiType.h>
|
||||
#include <SBCodepoint.h>
|
||||
#include <SBConfig.h>
|
||||
#include <SBGeneralCategory.h>
|
||||
#include <SBScript.h>
|
||||
|
||||
/**
|
||||
* A value that indicates an invalid unsigned index.
|
||||
*/
|
||||
#define SBInvalidIndex (SBUInteger)(-1)
|
||||
|
||||
SB_INTERNAL void SBUIntegerNormalizeRange(SBUInteger actualLength,
|
||||
SBUInteger *rangeOffset, SBUInteger *rangeLength);
|
||||
|
||||
SB_INTERNAL SBBoolean SBUIntegerVerifyRange(SBUInteger actualLength,
|
||||
SBUInteger rangeOffset, SBUInteger rangeLength);
|
||||
|
||||
|
||||
#define SBNumberGetMax(first, second) \
|
||||
( \
|
||||
(first) > (second) \
|
||||
? (first) \
|
||||
: (second) \
|
||||
)
|
||||
|
||||
#define SBNumberLimitIncrement(number, limit) \
|
||||
( \
|
||||
(number) < (limit) \
|
||||
? (number) + (1) \
|
||||
: (limit) \
|
||||
)
|
||||
|
||||
#define SBNumberLimitDecrement(number, limit) \
|
||||
( \
|
||||
(number) > (limit) \
|
||||
? (number) - (1) \
|
||||
: (limit) \
|
||||
)
|
||||
|
||||
#define SBNumberRingAdd(number, count, capacity) \
|
||||
(((number) + (count)) % (capacity))
|
||||
|
||||
#define SBNumberRingIncrement(number, capacity) \
|
||||
SBNumberRingAdd(number, 1, capacity)
|
||||
|
||||
#define SBNumberRingSubtract(number, count, capacity) \
|
||||
(((number) + (capacity) - (count)) % (capacity))
|
||||
|
||||
#define SBNumberRingDecrement(number, capacity) \
|
||||
SBNumberRingSubtract(number, 1, capacity)
|
||||
|
||||
|
||||
#define SBLevelAsNormalBidiType(level) \
|
||||
( \
|
||||
((level) & 1) \
|
||||
? SBBidiTypeR \
|
||||
: SBBidiTypeL \
|
||||
)
|
||||
|
||||
#define SBLevelAsOppositeBidiType(level) \
|
||||
( \
|
||||
((level) & 1) \
|
||||
? SBBidiTypeL \
|
||||
: SBBidiTypeR \
|
||||
)
|
||||
|
||||
|
||||
#define SBBidiTypeIsEqual(t1, t2) ((t1) == (t2))
|
||||
|
||||
#define SBBidiTypeIsNumber(t) SBUInt8InRange(t, SBBidiTypeAN, SBBidiTypeEN)
|
||||
#define SBBidiTypeIsIsolate(t) SBUInt8InRange(t, SBBidiTypeLRI, SBBidiTypePDI)
|
||||
|
||||
#define SBBidiTypeIsStrongOrNumber(t) (SBBidiTypeIsStrong(t) || SBBidiTypeIsNumber(t))
|
||||
#define SBBidiTypeIsNumberSeparator(t) SBUInt8InRange(t, SBBidiTypeES, SBBidiTypeCS)
|
||||
#define SBBidiTypeIsIsolateInitiator(t) SBUInt8InRange(t, SBBidiTypeLRI, SBBidiTypeFSI)
|
||||
#define SBBidiTypeIsIsolateTerminator(t) SBBidiTypeIsEqual(t, SBBidiTypePDI)
|
||||
#define SBBidiTypeIsNeutralOrIsolate(t) SBUInt8InRange(t, SBBidiTypeWS, SBBidiTypePDI)
|
||||
|
||||
|
||||
#define SBCodepointMax 0x10FFFF
|
||||
#define SBCodepointInRange(v, s, e) SBUInt32InRange(v, s, e)
|
||||
#define SBCodepointIsSurrogate(c) SBCodepointInRange(c, 0xD800, 0xDFFF)
|
||||
#define SBCodepointIsValid(c) (!SBCodepointIsSurrogate(c) && (c) <= SBCodepointMax)
|
||||
|
||||
|
||||
#define SBScriptIsCommonOrInherited(s) ((s) <= SBScriptZYYY)
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
* 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 <SBConfig.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "SBAssert.h"
|
||||
#include "SBBase.h"
|
||||
#include "SBCodepointSequence.h"
|
||||
|
||||
typedef struct {
|
||||
SBUInt8 valid;
|
||||
SBUInt8 total;
|
||||
SBUInt8 start;
|
||||
SBUInt8 end;
|
||||
} UTF8State;
|
||||
|
||||
static const UTF8State UTF8StateTable[9] = {
|
||||
{1,0,0x00,0x00}, {0,0,0x00,0x00}, {1,2,0x80,0xBF}, {1,3,0xA0,0xBF}, {1,3,0x80,0xBF},
|
||||
{1,3,0x80,0x9F}, {1,4,0x90,0xBF}, {1,4,0x80,0xBF}, {1,4,0x80,0x8F}
|
||||
};
|
||||
|
||||
static const SBUInt8 UTF8LookupTable[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* LEAD: -- 80..BF -- */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1,
|
||||
/* LEAD: -- C0..C1 -- */
|
||||
1, 1,
|
||||
/* LEAD: -- C2..DF -- */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* LEAD: -- E0..E0 -- */
|
||||
3,
|
||||
/* LEAD: -- E1..EC -- */
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
/* LEAD: -- ED..ED -- */
|
||||
5,
|
||||
/* LEAD: -- EE..EF -- */
|
||||
4, 4,
|
||||
/* LEAD: -- F0..F0 -- */
|
||||
6,
|
||||
/* LEAD: -- F1..F3 -- */
|
||||
7, 7, 7,
|
||||
/* LEAD: -- F4..F4 -- */
|
||||
8,
|
||||
/* LEAD: -- F5..F7 -- */
|
||||
1, 1, 1,
|
||||
/* LEAD: -- F8..FB -- */
|
||||
1, 1, 1, 1,
|
||||
/* LEAD: -- FC..FD -- */
|
||||
1, 1,
|
||||
/* LEAD: -- FE..FF -- */
|
||||
1, 1
|
||||
};
|
||||
|
||||
static SBCodepoint GetUTF8CodepointAt(const SBCodepointSequence *codepointSequence, SBUInteger *stringIndex);
|
||||
static SBCodepoint GetUTF8CodepointBefore(const SBCodepointSequence *codepointSequence, SBUInteger *stringIndex);
|
||||
static SBCodepoint GetUTF16CodepointAt(const SBCodepointSequence *codepointSequence, SBUInteger *stringIndex);
|
||||
static SBCodepoint GetUTF16CodepointBefore(const SBCodepointSequence *codepointSequence, SBUInteger *stringIndex);
|
||||
static SBCodepoint GetUTF32CodepointAt(const SBCodepointSequence *codepointSequence, SBUInteger *stringIndex);
|
||||
static SBCodepoint GetUTF32CodepointBefore(const SBCodepointSequence *codepointSequence, SBUInteger *stringIndex);
|
||||
|
||||
SB_INTERNAL SBBoolean SBCodepointSequenceIsValid(const SBCodepointSequence *codepointSequence)
|
||||
{
|
||||
if (codepointSequence) {
|
||||
SBBoolean encodingValid = SBFalse;
|
||||
|
||||
switch (codepointSequence->stringEncoding) {
|
||||
case SBStringEncodingUTF8:
|
||||
case SBStringEncodingUTF16:
|
||||
case SBStringEncodingUTF32:
|
||||
encodingValid = SBTrue;
|
||||
break;
|
||||
}
|
||||
|
||||
return (encodingValid && codepointSequence->stringBuffer && codepointSequence->stringLength > 0);
|
||||
}
|
||||
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
SBCodepoint SBCodepointSequenceGetCodepointBefore(const SBCodepointSequence *codepointSequence, SBUInteger *stringIndex)
|
||||
{
|
||||
SBCodepoint codepoint = SBCodepointInvalid;
|
||||
|
||||
if ((*stringIndex - 1) < codepointSequence->stringLength) {
|
||||
switch (codepointSequence->stringEncoding) {
|
||||
case SBStringEncodingUTF8:
|
||||
codepoint = GetUTF8CodepointBefore(codepointSequence, stringIndex);
|
||||
break;
|
||||
|
||||
case SBStringEncodingUTF16:
|
||||
codepoint = GetUTF16CodepointBefore(codepointSequence, stringIndex);
|
||||
break;
|
||||
|
||||
case SBStringEncodingUTF32:
|
||||
codepoint = GetUTF32CodepointBefore(codepointSequence, stringIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
SBCodepoint SBCodepointSequenceGetCodepointAt(const SBCodepointSequence *codepointSequence, SBUInteger *stringIndex)
|
||||
{
|
||||
SBCodepoint codepoint = SBCodepointInvalid;
|
||||
|
||||
if (*stringIndex < codepointSequence->stringLength) {
|
||||
switch (codepointSequence->stringEncoding) {
|
||||
case SBStringEncodingUTF8:
|
||||
codepoint = GetUTF8CodepointAt(codepointSequence, stringIndex);
|
||||
break;
|
||||
|
||||
case SBStringEncodingUTF16:
|
||||
codepoint = GetUTF16CodepointAt(codepointSequence, stringIndex);
|
||||
break;
|
||||
|
||||
case SBStringEncodingUTF32:
|
||||
codepoint = GetUTF32CodepointAt(codepointSequence, stringIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
static SBCodepoint GetUTF8CodepointAt(const SBCodepointSequence *sequence, SBUInteger *index)
|
||||
{
|
||||
const SBUInt8 *buffer = sequence->stringBuffer;
|
||||
SBUInteger length = sequence->stringLength;
|
||||
SBUInt8 lead;
|
||||
UTF8State state;
|
||||
SBUInteger limit;
|
||||
SBCodepoint codepoint;
|
||||
|
||||
lead = buffer[*index];
|
||||
state = UTF8StateTable[UTF8LookupTable[lead]];
|
||||
limit = *index + state.total;
|
||||
|
||||
if (limit > length) {
|
||||
limit = length;
|
||||
state.valid = SBFalse;
|
||||
}
|
||||
|
||||
codepoint = lead & (0x7F >> state.total);
|
||||
|
||||
while (++(*index) < limit) {
|
||||
SBUInt8 byte = buffer[*index];
|
||||
|
||||
if (byte >= state.start && byte <= state.end) {
|
||||
codepoint = (codepoint << 6) | (byte & 0x3F);
|
||||
} else {
|
||||
state.valid = SBFalse;
|
||||
break;
|
||||
}
|
||||
|
||||
state.start = 0x80;
|
||||
state.end = 0xBF;
|
||||
}
|
||||
|
||||
if (state.valid) {
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
return SBCodepointFaulty;
|
||||
}
|
||||
|
||||
static SBCodepoint GetUTF8CodepointBefore(const SBCodepointSequence *sequence, SBUInteger *index)
|
||||
{
|
||||
const SBUInt8 *buffer = sequence->stringBuffer;
|
||||
SBUInteger startIndex = *index;
|
||||
SBUInteger limitIndex;
|
||||
SBUInteger continuation;
|
||||
SBCodepoint codepoint;
|
||||
|
||||
continuation = 7;
|
||||
|
||||
while (--continuation && --startIndex) {
|
||||
SBUInt8 codeunit = buffer[startIndex];
|
||||
|
||||
if ((codeunit & 0xC0) != 0x80) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
limitIndex = startIndex;
|
||||
codepoint = GetUTF8CodepointAt(sequence, &limitIndex);
|
||||
|
||||
if (limitIndex == *index) {
|
||||
*index = startIndex;
|
||||
} else {
|
||||
codepoint = SBCodepointFaulty;
|
||||
*index -= 1;
|
||||
}
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
static SBCodepoint GetUTF16CodepointAt(const SBCodepointSequence *sequence, SBUInteger *index)
|
||||
{
|
||||
const SBUInt16 *buffer = sequence->stringBuffer;
|
||||
SBUInteger length = sequence->stringLength;
|
||||
SBCodepoint codepoint;
|
||||
SBUInt16 lead;
|
||||
|
||||
codepoint = SBCodepointFaulty;
|
||||
|
||||
lead = buffer[*index];
|
||||
*index += 1;
|
||||
|
||||
if (!SBCodepointIsSurrogate(lead)) {
|
||||
codepoint = lead;
|
||||
} else if (lead <= 0xDBFF) {
|
||||
if (*index < length) {
|
||||
SBUInt16 trail = buffer[*index];
|
||||
|
||||
if (SBUInt16InRange(trail, 0xDC00, 0xDFFF)) {
|
||||
codepoint = (lead << 10) + trail - ((0xD800 << 10) + 0xDC00 - 0x10000);
|
||||
*index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
static SBCodepoint GetUTF16CodepointBefore(const SBCodepointSequence *sequence, SBUInteger *index)
|
||||
{
|
||||
const SBUInt16 *buffer = sequence->stringBuffer;
|
||||
SBCodepoint codepoint;
|
||||
SBUInt16 trail;
|
||||
|
||||
codepoint = SBCodepointFaulty;
|
||||
|
||||
*index -= 1;
|
||||
trail = buffer[*index];
|
||||
|
||||
if (!SBCodepointIsSurrogate(trail)) {
|
||||
codepoint = trail;
|
||||
} else if (trail >= 0xDC00) {
|
||||
if (*index > 0) {
|
||||
SBUInt16 lead = buffer[*index - 1];
|
||||
|
||||
if (SBUInt16InRange(lead, 0xD800, 0xDBFF)) {
|
||||
codepoint = (lead << 10) + trail - ((0xD800 << 10) + 0xDC00 - 0x10000);
|
||||
*index -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
static SBCodepoint GetUTF32CodepointAt(const SBCodepointSequence *sequence, SBUInteger *index)
|
||||
{
|
||||
const SBUInt32 *buffer = sequence->stringBuffer;
|
||||
SBCodepoint codepoint;
|
||||
|
||||
codepoint = buffer[*index];
|
||||
*index += 1;
|
||||
|
||||
if (SBCodepointIsValid(codepoint)) {
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
return SBCodepointFaulty;
|
||||
}
|
||||
|
||||
static SBCodepoint GetUTF32CodepointBefore(const SBCodepointSequence *sequence, SBUInteger *index)
|
||||
{
|
||||
const SBUInt32 *buffer = sequence->stringBuffer;
|
||||
SBCodepoint codepoint;
|
||||
|
||||
*index -= 1;
|
||||
codepoint = buffer[*index];
|
||||
|
||||
if (SBCodepointIsValid(codepoint)) {
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
return SBCodepointFaulty;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_CODEPOINT_SEQUENCE_H
|
||||
#define _SB_INTERNAL_CODEPOINT_SEQUENCE_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
#include <SBCodepointSequence.h>
|
||||
|
||||
SB_INTERNAL SBBoolean SBCodepointSequenceIsValid(const SBCodepointSequence *codepointSequence);
|
||||
|
||||
#endif
|
||||
320
modules/juce_graphics/unicode/sheenbidi/Source/SBLine.c
Normal file
320
modules/juce_graphics/unicode/sheenbidi/Source/SBLine.c
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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 <SBConfig.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "PairingLookup.h"
|
||||
#include "SBAlgorithm.h"
|
||||
#include "SBAssert.h"
|
||||
#include "SBBase.h"
|
||||
#include "SBCodepointSequence.h"
|
||||
#include "SBParagraph.h"
|
||||
#include "SBRun.h"
|
||||
#include "SBLine.h"
|
||||
|
||||
typedef struct _LineContext {
|
||||
const SBBidiType *refTypes;
|
||||
SBLevel *fixedLevels;
|
||||
SBUInteger runCount;
|
||||
SBLevel maxLevel;
|
||||
} LineContext, *LineContextRef;
|
||||
|
||||
static SBLevel CopyLevels(SBLevel *destination,
|
||||
const SBLevel *source, SBUInteger length, SBUInteger *runCount)
|
||||
{
|
||||
SBLevel lastLevel = SBLevelInvalid;
|
||||
SBLevel maxLevel = 0;
|
||||
SBUInteger totalRuns = 0;
|
||||
|
||||
while (length--) {
|
||||
SBLevel level = *(source++);
|
||||
*(destination++) = level;
|
||||
|
||||
if (level != lastLevel) {
|
||||
totalRuns += 1;
|
||||
|
||||
if (level > maxLevel) {
|
||||
maxLevel = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*runCount = totalRuns;
|
||||
|
||||
return maxLevel;
|
||||
}
|
||||
|
||||
static LineContextRef CreateLineContext(const SBBidiType *types, const SBLevel *levels, SBUInteger length)
|
||||
{
|
||||
const SBUInteger sizeContext = sizeof(LineContext);
|
||||
const SBUInteger sizeLevels = sizeof(SBLevel) * length;
|
||||
const SBUInteger sizeMemory = sizeContext + sizeLevels;
|
||||
|
||||
void *pointer = malloc(sizeMemory);
|
||||
|
||||
if (pointer) {
|
||||
const SBUInteger offsetContext = 0;
|
||||
const SBUInteger offsetLevels = offsetContext + sizeContext;
|
||||
|
||||
SBUInt8 *memory = (SBUInt8 *)pointer;
|
||||
LineContextRef context = (LineContextRef)(memory + offsetContext);
|
||||
SBLevel *fixedLevels = (SBLevel *)(memory + offsetLevels);
|
||||
|
||||
context->refTypes = types;
|
||||
context->fixedLevels = fixedLevels;
|
||||
context->maxLevel = CopyLevels(fixedLevels, levels, length, &context->runCount);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void DisposeLineContext(LineContextRef context)
|
||||
{
|
||||
free(context);
|
||||
}
|
||||
|
||||
static SBLineRef AllocateLine(SBUInteger runCount)
|
||||
{
|
||||
const SBUInteger sizeLine = sizeof(SBLine);
|
||||
const SBUInteger sizeRuns = sizeof(SBRun) * runCount;
|
||||
const SBUInteger sizeMemory = sizeLine + sizeRuns;
|
||||
|
||||
void *pointer = malloc(sizeMemory);
|
||||
|
||||
if (pointer) {
|
||||
const SBUInteger offsetLine = 0;
|
||||
const SBUInteger offsetRuns = offsetLine + sizeLine;
|
||||
|
||||
SBUInt8 *memory = (SBUInt8 *)pointer;
|
||||
SBLineRef line = (SBLineRef)(memory + offsetLine);
|
||||
SBRun *runs = (SBRun *)(memory + offsetRuns);
|
||||
|
||||
line->fixedRuns = runs;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void SetNewLevel(SBLevel *levels, SBUInteger length, SBLevel newLevel)
|
||||
{
|
||||
SBUInteger index = length;
|
||||
|
||||
while (index--) {
|
||||
levels[index] = newLevel;
|
||||
}
|
||||
}
|
||||
|
||||
static void ResetLevels(LineContextRef context, SBLevel baseLevel, SBUInteger charCount)
|
||||
{
|
||||
const SBBidiType *types = context->refTypes;
|
||||
SBLevel *levels = context->fixedLevels;
|
||||
SBUInteger index;
|
||||
SBUInteger length;
|
||||
SBBoolean reset;
|
||||
|
||||
index = charCount;
|
||||
length = 0;
|
||||
reset = SBTrue;
|
||||
|
||||
while (index--) {
|
||||
SBBidiType type = types[index];
|
||||
|
||||
switch (type) {
|
||||
case SBBidiTypeB:
|
||||
case SBBidiTypeS:
|
||||
SetNewLevel(levels + index, length + 1, baseLevel);
|
||||
length = 0;
|
||||
reset = SBTrue;
|
||||
context->runCount += 1;
|
||||
break;
|
||||
|
||||
case SBBidiTypeLRE:
|
||||
case SBBidiTypeRLE:
|
||||
case SBBidiTypeLRO:
|
||||
case SBBidiTypeRLO:
|
||||
case SBBidiTypePDF:
|
||||
case SBBidiTypeBN:
|
||||
length += 1;
|
||||
break;
|
||||
|
||||
case SBBidiTypeWS:
|
||||
case SBBidiTypeLRI:
|
||||
case SBBidiTypeRLI:
|
||||
case SBBidiTypeFSI:
|
||||
case SBBidiTypePDI:
|
||||
if (reset) {
|
||||
SetNewLevel(levels + index, length + 1, baseLevel);
|
||||
length = 0;
|
||||
|
||||
context->runCount += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
length = 0;
|
||||
reset = SBFalse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SBUInteger InitializeRuns(SBRun *runs,
|
||||
const SBLevel *levels, SBUInteger length, SBUInteger lineOffset)
|
||||
{
|
||||
SBUInteger index;
|
||||
SBUInteger runCount = 1;
|
||||
|
||||
(*runs).offset = lineOffset;
|
||||
(*runs).level = levels[0];
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
SBLevel level = levels[index];
|
||||
|
||||
if (level != (*runs).level) {
|
||||
(*runs).length = index + lineOffset - (*runs).offset;
|
||||
|
||||
++runs;
|
||||
(*runs).offset = lineOffset + index;
|
||||
(*runs).level = level;
|
||||
|
||||
runCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
(*runs).length = index + lineOffset - (*runs).offset;
|
||||
|
||||
return runCount;
|
||||
}
|
||||
|
||||
static void ReverseRunSequence(SBRun *runs, SBUInteger runCount)
|
||||
{
|
||||
SBUInteger halfCount = runCount / 2;
|
||||
SBUInteger finalIndex = runCount - 1;
|
||||
SBUInteger index;
|
||||
|
||||
for (index = 0; index < halfCount; index++) {
|
||||
SBUInteger tieIndex;
|
||||
SBRun tempRun;
|
||||
|
||||
tieIndex = finalIndex - index;
|
||||
|
||||
tempRun = runs[index];
|
||||
runs[index] = runs[tieIndex];
|
||||
runs[tieIndex] = tempRun;
|
||||
}
|
||||
}
|
||||
|
||||
static void ReorderRuns(SBRun *runs, SBUInteger runCount, SBLevel maxLevel)
|
||||
{
|
||||
SBLevel newLevel;
|
||||
|
||||
for (newLevel = maxLevel; newLevel; newLevel--) {
|
||||
SBUInteger start = runCount;
|
||||
|
||||
while (start--) {
|
||||
if (runs[start].level >= newLevel) {
|
||||
SBUInteger count = 1;
|
||||
|
||||
for (; start && runs[start - 1].level >= newLevel; start--) {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
ReverseRunSequence(runs + start, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL SBLineRef SBLineCreate(SBParagraphRef paragraph,
|
||||
SBUInteger lineOffset, SBUInteger lineLength)
|
||||
{
|
||||
SBUInteger innerOffset = lineOffset - paragraph->offset;
|
||||
const SBBidiType *refTypes = paragraph->refTypes + innerOffset;
|
||||
const SBLevel *refLevels = paragraph->fixedLevels + innerOffset;
|
||||
LineContextRef context;
|
||||
SBLineRef line;
|
||||
|
||||
/* Line range MUST be valid. */
|
||||
SBAssert(lineOffset < (lineOffset + lineLength)
|
||||
&& lineOffset >= paragraph->offset
|
||||
&& (lineOffset + lineLength) <= (paragraph->offset + paragraph->length));
|
||||
|
||||
context = CreateLineContext(refTypes, refLevels, lineLength);
|
||||
|
||||
if (context) {
|
||||
ResetLevels(context, paragraph->baseLevel, lineLength);
|
||||
|
||||
line = AllocateLine(context->runCount);
|
||||
|
||||
if (line) {
|
||||
line->runCount = InitializeRuns(line->fixedRuns, context->fixedLevels, lineLength, lineOffset);
|
||||
ReorderRuns(line->fixedRuns, line->runCount, context->maxLevel);
|
||||
|
||||
line->codepointSequence = paragraph->algorithm->codepointSequence;
|
||||
line->offset = lineOffset;
|
||||
line->length = lineLength;
|
||||
line->retainCount = 1;
|
||||
}
|
||||
|
||||
DisposeLineContext(context);
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SBUInteger SBLineGetOffset(SBLineRef line)
|
||||
{
|
||||
return line->offset;
|
||||
}
|
||||
|
||||
SBUInteger SBLineGetLength(SBLineRef line)
|
||||
{
|
||||
return line->length;
|
||||
}
|
||||
|
||||
SBUInteger SBLineGetRunCount(SBLineRef line)
|
||||
{
|
||||
return line->runCount;
|
||||
}
|
||||
|
||||
const SBRun *SBLineGetRunsPtr(SBLineRef line)
|
||||
{
|
||||
return line->fixedRuns;
|
||||
}
|
||||
|
||||
SBLineRef SBLineRetain(SBLineRef line)
|
||||
{
|
||||
if (line) {
|
||||
line->retainCount += 1;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
void SBLineRelease(SBLineRef line)
|
||||
{
|
||||
if (line && --line->retainCount == 0) {
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
39
modules/juce_graphics/unicode/sheenbidi/Source/SBLine.h
Normal file
39
modules/juce_graphics/unicode/sheenbidi/Source/SBLine.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_LINE_H
|
||||
#define _SB_INTERNAL_LINE_H
|
||||
|
||||
#include <SBBase.h>
|
||||
#include <SBCodepointSequence.h>
|
||||
#include <SBConfig.h>
|
||||
#include <SBLine.h>
|
||||
#include <SBParagraph.h>
|
||||
#include <SBRun.h>
|
||||
|
||||
typedef struct _SBLine {
|
||||
SBCodepointSequence codepointSequence;
|
||||
SBRun *fixedRuns;
|
||||
SBUInteger runCount;
|
||||
SBUInteger offset;
|
||||
SBUInteger length;
|
||||
SBUInteger retainCount;
|
||||
} SBLine;
|
||||
|
||||
SB_INTERNAL SBLineRef SBLineCreate(SBParagraphRef paragraph,
|
||||
SBUInteger lineOffset, SBUInteger lineLength);
|
||||
|
||||
#endif
|
||||
303
modules/juce_graphics/unicode/sheenbidi/Source/SBLog.c
Normal file
303
modules/juce_graphics/unicode/sheenbidi/Source/SBLog.c
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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 <SBConfig.h>
|
||||
|
||||
#ifdef SB_CONFIG_LOG
|
||||
|
||||
#include "SBBase.h"
|
||||
#include "SBBidiChain.h"
|
||||
#include "SBBidiType.h"
|
||||
#include "SBIsolatingRun.h"
|
||||
#include "SBLog.h"
|
||||
|
||||
int _SBLogPosition = 0;
|
||||
|
||||
SB_INTERNAL void PrintBaseLevel(SBLevel baseLevel)
|
||||
{
|
||||
switch (baseLevel) {
|
||||
case SBLevelDefaultLTR:
|
||||
SB_LOG_STRING("Auto-LTR");
|
||||
break;
|
||||
|
||||
case SBLevelDefaultRTL:
|
||||
SB_LOG_STRING("Auto-RTL");
|
||||
break;
|
||||
|
||||
case 0:
|
||||
SB_LOG_STRING("LTR");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
SB_LOG_STRING("RTL");
|
||||
break;
|
||||
|
||||
default:
|
||||
SB_LOG(("Level - %d", baseLevel));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void PrintBidiType(SBBidiType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SBBidiTypeNil:
|
||||
SB_LOG_STRING("Nil");
|
||||
break;
|
||||
|
||||
case SBBidiTypeL:
|
||||
SB_LOG_STRING("L");
|
||||
break;
|
||||
|
||||
case SBBidiTypeR:
|
||||
SB_LOG_STRING("R");
|
||||
break;
|
||||
|
||||
case SBBidiTypeAL:
|
||||
SB_LOG_STRING("AL");
|
||||
break;
|
||||
|
||||
case SBBidiTypeEN:
|
||||
SB_LOG_STRING("EN");
|
||||
break;
|
||||
|
||||
case SBBidiTypeES:
|
||||
SB_LOG_STRING("ES");
|
||||
break;
|
||||
|
||||
case SBBidiTypeET:
|
||||
SB_LOG_STRING("EN");
|
||||
break;
|
||||
|
||||
case SBBidiTypeAN:
|
||||
SB_LOG_STRING("AN");
|
||||
break;
|
||||
|
||||
case SBBidiTypeCS:
|
||||
SB_LOG_STRING("CS");
|
||||
break;
|
||||
|
||||
case SBBidiTypeNSM:
|
||||
SB_LOG_STRING("NSM");
|
||||
break;
|
||||
|
||||
case SBBidiTypeBN:
|
||||
SB_LOG_STRING("BN");
|
||||
break;
|
||||
|
||||
case SBBidiTypeB:
|
||||
SB_LOG_STRING("B");
|
||||
break;
|
||||
|
||||
case SBBidiTypeS:
|
||||
SB_LOG_STRING("S");
|
||||
break;
|
||||
|
||||
case SBBidiTypeWS:
|
||||
SB_LOG_STRING("WS");
|
||||
break;
|
||||
|
||||
case SBBidiTypeON:
|
||||
SB_LOG_STRING("ON");
|
||||
break;
|
||||
|
||||
case SBBidiTypeLRE:
|
||||
SB_LOG_STRING("LRE");
|
||||
break;
|
||||
|
||||
case SBBidiTypeRLE:
|
||||
SB_LOG_STRING("RLE");
|
||||
break;
|
||||
|
||||
case SBBidiTypeLRO:
|
||||
SB_LOG_STRING("LRO");
|
||||
break;
|
||||
|
||||
case SBBidiTypeRLO:
|
||||
SB_LOG_STRING("RLO");
|
||||
break;
|
||||
|
||||
case SBBidiTypePDF:
|
||||
SB_LOG_STRING("PDF");
|
||||
break;
|
||||
|
||||
case SBBidiTypeLRI:
|
||||
SB_LOG_STRING("LRI");
|
||||
break;
|
||||
|
||||
case SBBidiTypeRLI:
|
||||
SB_LOG_STRING("RLI");
|
||||
break;
|
||||
|
||||
case SBBidiTypeFSI:
|
||||
SB_LOG_STRING("FSI");
|
||||
break;
|
||||
|
||||
case SBBidiTypePDI:
|
||||
SB_LOG_STRING("PDI");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void PrintCodepointSequence(const SBCodepointSequence *codepointSequence)
|
||||
{
|
||||
SBUInteger stringIndex = 0;
|
||||
SBCodepoint codepoint;
|
||||
|
||||
while ((codepoint = SBCodepointSequenceGetCodepointAt(codepointSequence, &stringIndex)) != SBCodepointInvalid) {
|
||||
SB_LOG(("%04X ", codepoint));
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void PrintBidiTypesArray(SBBidiType *types, SBUInteger length)
|
||||
{
|
||||
SBUInteger index;
|
||||
|
||||
for (index = 0; index < length; ++index) {
|
||||
SB_LOG_BIDI_TYPE(types[index]);
|
||||
SB_LOG_DIVIDER(1);
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void PrintLevelsArray(SBLevel *levels, SBUInteger length)
|
||||
{
|
||||
SBUInteger index;
|
||||
|
||||
for (index = 0; index < length; ++index) {
|
||||
SB_LOG_LEVEL(levels[index]);
|
||||
SB_LOG_DIVIDER(1);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
void *object;
|
||||
BidiLink link;
|
||||
SBUInteger length;
|
||||
} IsolatingContext;
|
||||
|
||||
typedef void (*IsolatingConsumer)(IsolatingRunRef isolatingRun, IsolatingContext *context);
|
||||
|
||||
SB_INTERNAL void IsolatingRunForEach(IsolatingRunRef isolatingRun,
|
||||
IsolatingContext *context, IsolatingConsumer consumer)
|
||||
{
|
||||
BidiChainRef bidiChain = isolatingRun->bidiChain;
|
||||
LevelRunRef levelRun;
|
||||
|
||||
/* Iterate over individual level runs of the isolating run. */
|
||||
for (levelRun = isolatingRun->baseLevelRun; levelRun; levelRun = levelRun->next) {
|
||||
BidiLink breakLink = BidiChainGetNext(bidiChain, levelRun->lastLink);
|
||||
BidiLink currentLink = levelRun->firstLink;
|
||||
BidiLink subsequentLink = levelRun->subsequentLink;
|
||||
|
||||
/* Iterate over each link of the level run. */
|
||||
while (currentLink != breakLink) {
|
||||
BidiLink nextLink = BidiChainGetNext(bidiChain, currentLink);
|
||||
SBUInteger linkOffset = BidiChainGetOffset(bidiChain, currentLink);
|
||||
SBUInteger linkLength;
|
||||
SBUInteger index;
|
||||
|
||||
if (nextLink != breakLink) {
|
||||
linkLength = BidiChainGetOffset(bidiChain, nextLink) - linkOffset;
|
||||
} else {
|
||||
linkLength = BidiChainGetOffset(bidiChain, subsequentLink) - linkOffset;
|
||||
}
|
||||
|
||||
/* Skip any sequence of BN character types. */
|
||||
for (index = 1; index < linkLength; index++) {
|
||||
SBBidiType bidiType = BidiChainGetType(bidiChain, currentLink + index);
|
||||
if (bidiType == SBBidiTypeBN) {
|
||||
linkLength = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
context->link = currentLink;
|
||||
context->length = linkLength;
|
||||
consumer(isolatingRun, context);
|
||||
|
||||
currentLink = nextLink;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintTypesOperation(IsolatingRunRef isolatingRun, IsolatingContext *context)
|
||||
{
|
||||
SBBidiType bidiType = BidiChainGetType(isolatingRun->bidiChain, context->link);
|
||||
|
||||
while (context->length--) {
|
||||
SB_LOG_BIDI_TYPE(bidiType);
|
||||
SB_LOG_DIVIDER(1);
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void PrintRunTypes(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
IsolatingContext context;
|
||||
IsolatingRunForEach(isolatingRun, &context, _SBPrintTypesOperation);
|
||||
}
|
||||
|
||||
static void PrintLevelsOperation(IsolatingRunRef isolatingRun, IsolatingContext *context)
|
||||
{
|
||||
SBLevel charLevel = BidiChainGetLevel(isolatingRun->bidiChain, context->link);
|
||||
|
||||
while (context->length--) {
|
||||
SB_LOG_LEVEL(charLevel);
|
||||
SB_LOG_DIVIDER(1);
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void PrintRunLevels(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
IsolatingContext context;
|
||||
IsolatingRunForEach(isolatingRun, &context, _SBPrintLevelsOperation);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
SBUInteger offset;
|
||||
SBUInteger length;
|
||||
} IsolatingRange;
|
||||
|
||||
static void PrintRangeOperation(IsolatingRunRef isolatingRun, IsolatingContext *context)
|
||||
{
|
||||
IsolatingRange *range = context->object;
|
||||
SBUInteger offset = BidiChainGetOffset(isolatingRun->bidiChain, context->link);
|
||||
|
||||
if (range->length == 0) {
|
||||
range->offset = offset;
|
||||
range->length = context->length;
|
||||
} else if (offset == (range->offset + range->length)) {
|
||||
range->length += context->length;
|
||||
} else {
|
||||
SB_LOG_RANGE(range->offset, range->length);
|
||||
SB_LOG_DIVIDER(1);
|
||||
|
||||
range->offset = offset;
|
||||
range->length = context->length;
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void PrintRunRange(IsolatingRunRef isolatingRun)
|
||||
{
|
||||
IsolatingRange range = { 0, 0 };
|
||||
IsolatingContext context;
|
||||
context.object = ⦥
|
||||
|
||||
IsolatingRunForEach(isolatingRun, &context, _SBPrintRangeOperation);
|
||||
SB_LOG_RANGE(range.offset, range.length);
|
||||
SB_LOG_DIVIDER(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
153
modules/juce_graphics/unicode/sheenbidi/Source/SBLog.h
Normal file
153
modules/juce_graphics/unicode/sheenbidi/Source/SBLog.h
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_LOG_H
|
||||
#define _SB_INTERNAL_LOG_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
|
||||
#ifdef SB_CONFIG_LOG
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "SBBase.h"
|
||||
#include "SBBidiType.h"
|
||||
#include "SBCodepointSequence.h"
|
||||
#include "SBIsolatingRun.h"
|
||||
|
||||
SB_INTERNAL void PrintBaseLevel(SBLevel baseLevel);
|
||||
SB_INTERNAL void PrintBidiType(SBBidiType type);
|
||||
|
||||
SB_INTERNAL void PrintCodepointSequence(const SBCodepointSequence *codepointSequence);
|
||||
SB_INTERNAL void PrintBidiTypesArray(SBBidiType *types, SBUInteger length);
|
||||
SB_INTERNAL void PrintLevelsArray(SBLevel *levels, SBUInteger length);
|
||||
|
||||
SB_INTERNAL void PrintRunTypes(IsolatingRunRef isolatingRun);
|
||||
SB_INTERNAL void PrintRunLevels(IsolatingRunRef isolatingRun);
|
||||
SB_INTERNAL void PrintRunRange(IsolatingRunRef isolatingRun);
|
||||
|
||||
extern int _SBLogPosition;
|
||||
|
||||
#define SB_LOG_BEGIN() (++_SBLogPosition)
|
||||
#define SB_LOG_END() (--_SBLogPosition)
|
||||
|
||||
#define SB_LOG(s) printf s
|
||||
|
||||
#define SB_LOG_NUMBER(n) \
|
||||
SB_LOG(("%ld", (long)n))
|
||||
|
||||
#define SB_LOG_RANGE(o, l) \
|
||||
SB_LOG(("[%ld, %ld]", (long)o, (long)(o + l - 1)))
|
||||
|
||||
#define SB_LOG_CHAR(c) \
|
||||
SBLOG(("%c", c))
|
||||
|
||||
#define SB_LOG_STRING(s) \
|
||||
SB_LOG(("%s", s))
|
||||
|
||||
#define SB_LOG_LEVEL(l) \
|
||||
SB_LOG_NUMBER(l)
|
||||
|
||||
#define SB_LOG_BREAKER() \
|
||||
SB_LOG(("\n"))
|
||||
|
||||
#define SB_LOG_DIVIDER(n) \
|
||||
SB_LOG(("%.*s", n, "\t\t\t\t\t\t\t\t\t\t"))
|
||||
|
||||
#define SB_LOG_INITIATOR() \
|
||||
SB_LOG_DIVIDER(_SBLogPosition)
|
||||
|
||||
#define SB_LOG_CAPTION(c) \
|
||||
SB_LOG((c":"))
|
||||
|
||||
#define SB_LOG_STATEMENT_TEXT(t) \
|
||||
(t)
|
||||
|
||||
#define SB_LOG_LINE(s) \
|
||||
do { \
|
||||
SB_LOG(s); \
|
||||
SB_LOG_BREAKER(); \
|
||||
} while (0)
|
||||
|
||||
#define SB_LOG_STATEMENT(c, d, t) \
|
||||
do { \
|
||||
SB_LOG_INITIATOR(); \
|
||||
SB_LOG_CAPTION(c); \
|
||||
SB_LOG_DIVIDER(d); \
|
||||
SB_LOG_STATEMENT_TEXT(t); \
|
||||
SB_LOG_BREAKER(); \
|
||||
} while (0)
|
||||
|
||||
#define SB_LOG_BLOCK_OPENER(c) \
|
||||
do { \
|
||||
SB_LOG_INITIATOR(); \
|
||||
SB_LOG_CAPTION(c); \
|
||||
SB_LOG_BREAKER(); \
|
||||
SB_LOG_BEGIN(); \
|
||||
} while (0)
|
||||
|
||||
#define SB_LOG_BLOCK_CLOSER() SB_LOG_END()
|
||||
|
||||
#define SB_LOG_BASE_LEVEL(l) PrintBaseLevel(l)
|
||||
#define SB_LOG_BIDI_TYPE(t) PrintBidiType(t)
|
||||
|
||||
#define SB_LOG_CODEPOINT_SEQUENCE(s) PrintCodepointSequence(s)
|
||||
#define SB_LOG_BIDI_TYPES_ARRAY(a, l) PrintBidiTypesArray(a, l)
|
||||
#define SB_LOG_LEVELS_ARRAY(a, l) PrintLevelsArray(a, l)
|
||||
|
||||
#define SB_LOG_RUN_TYPES(r) PrintRunTypes(r)
|
||||
#define SB_LOG_RUN_LEVELS(r) PrintRunLevels(r)
|
||||
#define SB_LOG_RUN_RANGE(r) PrintRunRange(r)
|
||||
|
||||
#else
|
||||
|
||||
#define SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG(s) SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG_NUMBER(n) SB_LOG_NONE()
|
||||
#define SB_LOG_RANGE(o, l) SB_LOG_NONE()
|
||||
#define SB_LOG_CHAR(c) SB_LOG_NONE()
|
||||
#define SB_LOG_STRING(s) SB_LOG_NONE()
|
||||
#define SB_LOG_LEVEL(l) SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG_BREAKER() SB_LOG_NONE()
|
||||
#define SB_LOG_DIVIDER(n) SB_LOG_NONE()
|
||||
#define SB_LOG_INITIATOR() SB_LOG_NONE()
|
||||
#define SB_LOG_CAPTION(c) SB_LOG_NONE()
|
||||
#define SB_LOG_STATEMENT_TEXT(t) SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG_LINE(s) SB_LOG_NONE()
|
||||
#define SB_LOG_STATEMENT(c, d, t) SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG_BLOCK_OPENER(c) SB_LOG_NONE()
|
||||
#define SB_LOG_BLOCK_CLOSER() SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG_BASE_LEVEL(l) SB_LOG_NONE()
|
||||
#define SB_LOG_BIDI_TYPE(t) SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG_CODEPOINT_SEQUENCE(s) SB_LOG_NONE()
|
||||
#define SB_LOG_BIDI_TYPES_ARRAY(a, l) SB_LOG_NONE()
|
||||
#define SB_LOG_LEVELS_ARRAY(a, l) SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG_RUN_TYPES(r) SB_LOG_NONE()
|
||||
#define SB_LOG_RUN_LEVELS(r) SB_LOG_NONE()
|
||||
|
||||
#define SB_LOG_RUN_RANGE(r) SB_LOG_NONE()
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
123
modules/juce_graphics/unicode/sheenbidi/Source/SBMirrorLocator.c
Normal file
123
modules/juce_graphics/unicode/sheenbidi/Source/SBMirrorLocator.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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 <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "PairingLookup.h"
|
||||
#include "SBBase.h"
|
||||
#include "SBLine.h"
|
||||
#include "SBMirrorLocator.h"
|
||||
|
||||
SBMirrorLocatorRef SBMirrorLocatorCreate(void)
|
||||
{
|
||||
SBMirrorLocatorRef locator = malloc(sizeof(SBMirrorLocator));
|
||||
|
||||
if (locator) {
|
||||
locator->_line = NULL;
|
||||
locator->retainCount = 1;
|
||||
|
||||
SBMirrorLocatorReset(locator);
|
||||
}
|
||||
|
||||
return locator;
|
||||
}
|
||||
|
||||
void SBMirrorLocatorLoadLine(SBMirrorLocatorRef locator, SBLineRef line, void *stringBuffer)
|
||||
{
|
||||
SBLineRelease(locator->_line);
|
||||
|
||||
if (line && stringBuffer == line->codepointSequence.stringBuffer) {
|
||||
locator->_line = SBLineRetain(line);
|
||||
}
|
||||
|
||||
SBMirrorLocatorReset(locator);
|
||||
}
|
||||
|
||||
const SBMirrorAgent *SBMirrorLocatorGetAgent(SBMirrorLocatorRef locator)
|
||||
{
|
||||
return &locator->agent;
|
||||
}
|
||||
|
||||
SBBoolean SBMirrorLocatorMoveNext(SBMirrorLocatorRef locator)
|
||||
{
|
||||
SBLineRef line = locator->_line;
|
||||
|
||||
if (line) {
|
||||
const SBCodepointSequence *sequence = &line->codepointSequence;
|
||||
|
||||
do {
|
||||
const SBRun *run = &line->fixedRuns[locator->_runIndex];
|
||||
|
||||
if (run->level & 1) {
|
||||
SBUInteger stringIndex;
|
||||
SBUInteger stringLimit;
|
||||
|
||||
stringIndex = locator->_stringIndex;
|
||||
if (stringIndex == SBInvalidIndex) {
|
||||
stringIndex = run->offset;
|
||||
}
|
||||
stringLimit = run->offset + run->length;
|
||||
|
||||
while (stringIndex < stringLimit) {
|
||||
SBUInteger initialIndex = stringIndex;
|
||||
SBCodepoint codepoint = SBCodepointSequenceGetCodepointAt(sequence, &stringIndex);
|
||||
SBCodepoint mirror = LookupMirror(codepoint);
|
||||
|
||||
if (mirror) {
|
||||
locator->_stringIndex = stringIndex;
|
||||
locator->agent.index = initialIndex;
|
||||
locator->agent.mirror = mirror;
|
||||
locator->agent.codepoint = codepoint;
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
locator->_stringIndex = SBInvalidIndex;
|
||||
} while (++locator->_runIndex < line->runCount);
|
||||
|
||||
SBMirrorLocatorReset(locator);
|
||||
}
|
||||
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
void SBMirrorLocatorReset(SBMirrorLocatorRef locator)
|
||||
{
|
||||
locator->_runIndex = 0;
|
||||
locator->_stringIndex = SBInvalidIndex;
|
||||
locator->agent.index = SBInvalidIndex;
|
||||
locator->agent.mirror = 0;
|
||||
}
|
||||
|
||||
SBMirrorLocatorRef SBMirrorLocatorRetain(SBMirrorLocatorRef locator)
|
||||
{
|
||||
if (locator) {
|
||||
locator->retainCount += 1;
|
||||
}
|
||||
|
||||
return locator;
|
||||
}
|
||||
|
||||
void SBMirrorLocatorRelease(SBMirrorLocatorRef locator)
|
||||
{
|
||||
if (locator && --locator->retainCount == 0) {
|
||||
SBLineRelease(locator->_line);
|
||||
free(locator);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_MIRROR_LOCATOR_H
|
||||
#define _SB_INTERNAL_MIRROR_LOCATOR_H
|
||||
|
||||
#include <SBBase.h>
|
||||
#include <SBMirrorLocator.h>
|
||||
#include <SBLine.h>
|
||||
|
||||
typedef struct _SBMirrorLocator {
|
||||
SBLineRef _line;
|
||||
SBUInteger _runIndex;
|
||||
SBUInteger _stringIndex;
|
||||
SBMirrorAgent agent;
|
||||
SBUInteger retainCount;
|
||||
} SBMirrorLocator;
|
||||
|
||||
#endif
|
||||
702
modules/juce_graphics/unicode/sheenbidi/Source/SBParagraph.c
Normal file
702
modules/juce_graphics/unicode/sheenbidi/Source/SBParagraph.c
Normal file
|
|
@ -0,0 +1,702 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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 <SBConfig.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "BidiChain.h"
|
||||
#include "BidiTypeLookup.h"
|
||||
#include "IsolatingRun.h"
|
||||
#include "LevelRun.h"
|
||||
#include "RunQueue.h"
|
||||
#include "SBAlgorithm.h"
|
||||
#include "SBAssert.h"
|
||||
#include "SBBase.h"
|
||||
#include "SBCodepointSequence.h"
|
||||
#include "SBLine.h"
|
||||
#include "SBLog.h"
|
||||
#include "StatusStack.h"
|
||||
#include "SBParagraph.h"
|
||||
|
||||
typedef struct _ParagraphContext {
|
||||
BidiChain bidiChain;
|
||||
StatusStack statusStack;
|
||||
RunQueue runQueue;
|
||||
IsolatingRun isolatingRun;
|
||||
} ParagraphContext, *ParagraphContextRef;
|
||||
|
||||
static void PopulateBidiChain(BidiChainRef chain, const SBBidiType *types, SBUInteger length);
|
||||
static SBBoolean ProcessRun(ParagraphContextRef context, const LevelRunRef levelRun, SBBoolean forceFinish);
|
||||
|
||||
static ParagraphContextRef CreateParagraphContext(const SBBidiType *types, SBLevel *levels, SBUInteger length)
|
||||
{
|
||||
const SBUInteger sizeContext = sizeof(ParagraphContext);
|
||||
const SBUInteger sizeLinks = sizeof(BidiLink) * (length + 2);
|
||||
const SBUInteger sizeTypes = sizeof(SBBidiType) * (length + 2);
|
||||
const SBUInteger sizeMemory = sizeContext + sizeLinks + sizeTypes;
|
||||
|
||||
void *pointer = malloc(sizeMemory);
|
||||
|
||||
if (pointer) {
|
||||
const SBUInteger offsetContext = 0;
|
||||
const SBUInteger offsetLinks = offsetContext + sizeContext;
|
||||
const SBUInteger offsetTypes = offsetLinks + sizeLinks;
|
||||
|
||||
SBUInt8 *memory = (SBUInt8 *)pointer;
|
||||
ParagraphContextRef context = (ParagraphContextRef)(memory + offsetContext);
|
||||
BidiLink *fixedLinks = (BidiLink *)(memory + offsetLinks);
|
||||
SBBidiType *fixedTypes = (SBBidiType *)(memory + offsetTypes);
|
||||
|
||||
BidiChainInitialize(&context->bidiChain, fixedTypes, levels, fixedLinks);
|
||||
StatusStackInitialize(&context->statusStack);
|
||||
RunQueueInitialize(&context->runQueue);
|
||||
IsolatingRunInitialize(&context->isolatingRun);
|
||||
|
||||
PopulateBidiChain(&context->bidiChain, types, length);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void DisposeParagraphContext(ParagraphContextRef context)
|
||||
{
|
||||
StatusStackFinalize(&context->statusStack);
|
||||
RunQueueFinalize(&context->runQueue);
|
||||
IsolatingRunFinalize(&context->isolatingRun);
|
||||
free(context);
|
||||
}
|
||||
|
||||
static SBParagraphRef AllocateParagraph(SBUInteger length)
|
||||
{
|
||||
const SBUInteger sizeParagraph = sizeof(SBParagraph);
|
||||
const SBUInteger sizeLevels = sizeof(SBLevel) * (length + 2);
|
||||
const SBUInteger sizeMemory = sizeParagraph + sizeLevels;
|
||||
|
||||
void *pointer = malloc(sizeMemory);
|
||||
|
||||
if (pointer) {
|
||||
const SBUInteger offsetParagraph = 0;
|
||||
const SBUInteger offsetLevels = offsetParagraph + sizeParagraph;
|
||||
|
||||
SBUInt8 *memory = (SBUInt8 *)pointer;
|
||||
SBParagraphRef paragraph = (SBParagraphRef)(memory + offsetParagraph);
|
||||
SBLevel *levels = (SBLevel *)(memory + offsetLevels);
|
||||
|
||||
paragraph->fixedLevels = levels;
|
||||
|
||||
return paragraph;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void DisposeParagraph(SBParagraphRef paragraph)
|
||||
{
|
||||
free(paragraph);
|
||||
}
|
||||
|
||||
static SBUInteger DetermineBoundary(SBAlgorithmRef algorithm, SBUInteger paragraphOffset, SBUInteger suggestedLength)
|
||||
{
|
||||
SBBidiType *bidiTypes = algorithm->fixedTypes;
|
||||
SBUInteger suggestedLimit = paragraphOffset + suggestedLength;
|
||||
SBUInteger stringIndex;
|
||||
|
||||
for (stringIndex = paragraphOffset; stringIndex < suggestedLimit; stringIndex++) {
|
||||
if (bidiTypes[stringIndex] == SBBidiTypeB) {
|
||||
stringIndex += SBAlgorithmGetSeparatorLength(algorithm, stringIndex);
|
||||
goto Return;
|
||||
}
|
||||
}
|
||||
|
||||
Return:
|
||||
return (stringIndex - paragraphOffset);
|
||||
}
|
||||
|
||||
static void PopulateBidiChain(BidiChainRef chain, const SBBidiType *types, SBUInteger length)
|
||||
{
|
||||
SBBidiType type = SBBidiTypeNil;
|
||||
SBUInteger priorIndex = SBInvalidIndex;
|
||||
SBUInteger index;
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
SBBidiType priorType = type;
|
||||
type = types[index];
|
||||
|
||||
switch (type) {
|
||||
case SBBidiTypeB:
|
||||
case SBBidiTypeON:
|
||||
case SBBidiTypeLRE:
|
||||
case SBBidiTypeRLE:
|
||||
case SBBidiTypeLRO:
|
||||
case SBBidiTypeRLO:
|
||||
case SBBidiTypePDF:
|
||||
case SBBidiTypeLRI:
|
||||
case SBBidiTypeRLI:
|
||||
case SBBidiTypeFSI:
|
||||
case SBBidiTypePDI:
|
||||
BidiChainAdd(chain, type, index - priorIndex);
|
||||
priorIndex = index;
|
||||
|
||||
if (type == SBBidiTypeB) {
|
||||
index = length;
|
||||
goto AddLast;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (type != priorType) {
|
||||
BidiChainAdd(chain, type, index - priorIndex);
|
||||
priorIndex = index;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AddLast:
|
||||
BidiChainAdd(chain, SBBidiTypeNil, index - priorIndex);
|
||||
}
|
||||
|
||||
static BidiLink SkipIsolatingRun(BidiChainRef chain, BidiLink skipLink, BidiLink breakLink)
|
||||
{
|
||||
BidiLink link = skipLink;
|
||||
SBUInteger depth = 1;
|
||||
|
||||
while ((link = BidiChainGetNext(chain, link)) != breakLink) {
|
||||
SBBidiType type = BidiChainGetType(chain, link);
|
||||
|
||||
switch (type) {
|
||||
case SBBidiTypeLRI:
|
||||
case SBBidiTypeRLI:
|
||||
case SBBidiTypeFSI:
|
||||
depth += 1;
|
||||
break;
|
||||
|
||||
case SBBidiTypePDI:
|
||||
if (--depth == 0) {
|
||||
return link;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return BidiLinkNone;
|
||||
}
|
||||
|
||||
static SBLevel DetermineBaseLevel(BidiChainRef chain, BidiLink skipLink, BidiLink breakLink, SBLevel defaultLevel, SBBoolean isIsolate)
|
||||
{
|
||||
BidiLink link = skipLink;
|
||||
|
||||
/* Rules P2, P3 */
|
||||
while ((link = BidiChainGetNext(chain, link)) != breakLink) {
|
||||
SBBidiType type = BidiChainGetType(chain, link);
|
||||
|
||||
switch (type) {
|
||||
case SBBidiTypeL:
|
||||
return 0;
|
||||
|
||||
case SBBidiTypeAL:
|
||||
case SBBidiTypeR:
|
||||
return 1;
|
||||
|
||||
case SBBidiTypeLRI:
|
||||
case SBBidiTypeRLI:
|
||||
case SBBidiTypeFSI:
|
||||
link = SkipIsolatingRun(chain, link, breakLink);
|
||||
if (link == BidiLinkNone) {
|
||||
goto Default;
|
||||
}
|
||||
break;
|
||||
|
||||
case SBBidiTypePDI:
|
||||
if (isIsolate) {
|
||||
/*
|
||||
* In case of isolating run, the PDI will be the last code point.
|
||||
* NOTE:
|
||||
* The inner isolating runs will be skipped by the case above this one.
|
||||
*/
|
||||
goto Default;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Default:
|
||||
return defaultLevel;
|
||||
}
|
||||
|
||||
static SBLevel DetermineParagraphLevel(BidiChainRef chain, SBLevel baseLevel)
|
||||
{
|
||||
if (baseLevel >= SBLevelMax) {
|
||||
return DetermineBaseLevel(chain, chain->roller, chain->roller,
|
||||
(baseLevel != SBLevelDefaultRTL ? 0 : 1),
|
||||
SBFalse);
|
||||
}
|
||||
|
||||
return baseLevel;
|
||||
}
|
||||
|
||||
static SBBoolean DetermineLevels(ParagraphContextRef context, SBLevel baseLevel)
|
||||
{
|
||||
BidiChainRef chain = &context->bidiChain;
|
||||
StatusStackRef stack = &context->statusStack;
|
||||
BidiLink roller = chain->roller;
|
||||
BidiLink link;
|
||||
|
||||
BidiLink priorLink;
|
||||
BidiLink firstLink;
|
||||
BidiLink lastLink;
|
||||
|
||||
SBLevel priorLevel;
|
||||
SBBidiType sor;
|
||||
SBBidiType eor;
|
||||
|
||||
SBUInteger overIsolate;
|
||||
SBUInteger overEmbedding;
|
||||
SBUInteger validIsolate;
|
||||
|
||||
priorLink = chain->roller;
|
||||
firstLink = BidiLinkNone;
|
||||
lastLink = BidiLinkNone;
|
||||
|
||||
priorLevel = baseLevel;
|
||||
sor = SBBidiTypeNil;
|
||||
|
||||
/* Rule X1 */
|
||||
overIsolate = 0;
|
||||
overEmbedding = 0;
|
||||
validIsolate = 0;
|
||||
|
||||
StatusStackPush(stack, baseLevel, SBBidiTypeON, SBFalse);
|
||||
|
||||
BidiChainForEach(chain, roller, link) {
|
||||
SBBoolean forceFinish = SBFalse;
|
||||
SBBoolean bnEquivalent = SBFalse;
|
||||
SBBidiType type;
|
||||
|
||||
type = BidiChainGetType(chain, link);
|
||||
|
||||
#define LeastGreaterOddLevel() \
|
||||
( \
|
||||
(StatusStackGetEmbeddingLevel(stack) + 1) | 1 \
|
||||
)
|
||||
|
||||
#define LeastGreaterEvenLevel() \
|
||||
( \
|
||||
(StatusStackGetEmbeddingLevel(stack) + 2) & ~1 \
|
||||
)
|
||||
|
||||
#define MergeLinkIfNeeded() \
|
||||
{ \
|
||||
if (BidiChainMergeIfEqual(chain, priorLink, link)) { \
|
||||
continue; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PushEmbedding(l, o) \
|
||||
{ \
|
||||
SBLevel newLevel = l; \
|
||||
\
|
||||
bnEquivalent = SBTrue; \
|
||||
\
|
||||
if (newLevel <= SBLevelMax && !overIsolate && !overEmbedding) { \
|
||||
if (!StatusStackPush(stack, newLevel, o, SBFalse)) { \
|
||||
return SBFalse; \
|
||||
} \
|
||||
} else { \
|
||||
if (!overIsolate) { \
|
||||
overEmbedding += 1; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PushIsolate(l, o) \
|
||||
{ \
|
||||
SBBidiType priorStatus = StatusStackGetOverrideStatus(stack); \
|
||||
SBLevel newLevel = l; \
|
||||
\
|
||||
BidiChainSetLevel(chain, link, \
|
||||
StatusStackGetEmbeddingLevel(stack)); \
|
||||
\
|
||||
if (newLevel <= SBLevelMax && !overIsolate && !overEmbedding) { \
|
||||
validIsolate += 1; \
|
||||
\
|
||||
if (!StatusStackPush(stack, newLevel, o, SBTrue)) { \
|
||||
return SBFalse; \
|
||||
} \
|
||||
} else { \
|
||||
overIsolate += 1; \
|
||||
} \
|
||||
\
|
||||
if (priorStatus != SBBidiTypeON) { \
|
||||
BidiChainSetType(chain, link, priorStatus); \
|
||||
MergeLinkIfNeeded(); \
|
||||
} \
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
/* Rule X2 */
|
||||
case SBBidiTypeRLE:
|
||||
PushEmbedding(LeastGreaterOddLevel(), SBBidiTypeON);
|
||||
break;
|
||||
|
||||
/* Rule X3 */
|
||||
case SBBidiTypeLRE:
|
||||
PushEmbedding(LeastGreaterEvenLevel(), SBBidiTypeON);
|
||||
break;
|
||||
|
||||
/* Rule X4 */
|
||||
case SBBidiTypeRLO:
|
||||
PushEmbedding(LeastGreaterOddLevel(), SBBidiTypeR);
|
||||
break;
|
||||
|
||||
/* Rule X5 */
|
||||
case SBBidiTypeLRO:
|
||||
PushEmbedding(LeastGreaterEvenLevel(), SBBidiTypeL);
|
||||
break;
|
||||
|
||||
/* Rule X5a */
|
||||
case SBBidiTypeRLI:
|
||||
PushIsolate(LeastGreaterOddLevel(), SBBidiTypeON);
|
||||
break;
|
||||
|
||||
/* Rule X5b */
|
||||
case SBBidiTypeLRI:
|
||||
PushIsolate(LeastGreaterEvenLevel(), SBBidiTypeON);
|
||||
break;
|
||||
|
||||
/* Rule X5c */
|
||||
case SBBidiTypeFSI:
|
||||
{
|
||||
SBBoolean isRTL = (DetermineBaseLevel(chain, link, roller, 0, SBTrue) == 1);
|
||||
PushIsolate(isRTL ? LeastGreaterOddLevel() : LeastGreaterEvenLevel(), SBBidiTypeON);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Rule X6 */
|
||||
default:
|
||||
BidiChainSetLevel(chain, link, StatusStackGetEmbeddingLevel(stack));
|
||||
|
||||
if (StatusStackGetOverrideStatus(stack) != SBBidiTypeON) {
|
||||
BidiChainSetType(chain, link, StatusStackGetOverrideStatus(stack));
|
||||
MergeLinkIfNeeded();
|
||||
}
|
||||
break;
|
||||
|
||||
/* Rule X6a */
|
||||
case SBBidiTypePDI:
|
||||
{
|
||||
SBBidiType overrideStatus;
|
||||
|
||||
if (overIsolate != 0) {
|
||||
overIsolate -= 1;
|
||||
} else if (validIsolate == 0) {
|
||||
/* Do nothing */
|
||||
} else {
|
||||
overEmbedding = 0;
|
||||
|
||||
while (!StatusStackGetIsolateStatus(stack)) {
|
||||
StatusStackPop(stack);
|
||||
}
|
||||
StatusStackPop(stack);
|
||||
|
||||
validIsolate -= 1;
|
||||
}
|
||||
|
||||
BidiChainSetLevel(chain, link, StatusStackGetEmbeddingLevel(stack));
|
||||
overrideStatus = StatusStackGetOverrideStatus(stack);
|
||||
|
||||
if (overrideStatus != SBBidiTypeON) {
|
||||
BidiChainSetType(chain, link, overrideStatus);
|
||||
MergeLinkIfNeeded();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Rule X7 */
|
||||
case SBBidiTypePDF:
|
||||
bnEquivalent = SBTrue;
|
||||
|
||||
if (overIsolate != 0) {
|
||||
/* Do nothing */
|
||||
} else if (overEmbedding != 0) {
|
||||
overEmbedding -= 1;
|
||||
} else if (!StatusStackGetIsolateStatus(stack) && stack->count >= 2) {
|
||||
StatusStackPop(stack);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Rule X8 */
|
||||
case SBBidiTypeB:
|
||||
/*
|
||||
* These values are reset for clarity, in this implementation B can only occur as the
|
||||
* last code in the array.
|
||||
*/
|
||||
StatusStackSetEmpty(stack);
|
||||
StatusStackPush(stack, baseLevel, SBBidiTypeON, SBFalse);
|
||||
|
||||
overIsolate = 0;
|
||||
overEmbedding = 0;
|
||||
validIsolate = 0;
|
||||
|
||||
BidiChainSetLevel(chain, link, baseLevel);
|
||||
break;
|
||||
|
||||
case SBBidiTypeBN:
|
||||
bnEquivalent = SBTrue;
|
||||
break;
|
||||
|
||||
case SBBidiTypeNil:
|
||||
forceFinish = SBTrue;
|
||||
BidiChainSetLevel(chain, link, baseLevel);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Rule X9 */
|
||||
if (bnEquivalent) {
|
||||
/* The type of this link is BN equivalent, so abandon it and continue the loop. */
|
||||
BidiChainSetType(chain, link, SBBidiTypeBN);
|
||||
BidiChainAbandonNext(chain, priorLink);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sor == SBBidiTypeNil) {
|
||||
sor = SBLevelAsNormalBidiType(SBNumberGetMax(baseLevel, BidiChainGetLevel(chain, link)));
|
||||
firstLink = link;
|
||||
priorLevel = BidiChainGetLevel(chain, link);
|
||||
} else if (priorLevel != BidiChainGetLevel(chain, link) || forceFinish) {
|
||||
LevelRun levelRun;
|
||||
SBLevel currentLevel;
|
||||
|
||||
/* Since the level has changed at this link, therefore the run must end at prior link. */
|
||||
lastLink = priorLink;
|
||||
|
||||
/* Save the current level i.e. level of the next run. */
|
||||
currentLevel = BidiChainGetLevel(chain, link);
|
||||
/*
|
||||
* Now we have both the prior level and the current level i.e. unchanged levels of both
|
||||
* the current run and the next run. So, identify eor of the current run.
|
||||
* NOTE:
|
||||
* sor of the run has been already determined at this stage.
|
||||
*/
|
||||
eor = SBLevelAsNormalBidiType(SBNumberGetMax(priorLevel, currentLevel));
|
||||
|
||||
LevelRunInitialize(&levelRun, chain, firstLink, lastLink, sor, eor);
|
||||
|
||||
if (!ProcessRun(context, &levelRun, forceFinish)) {
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
/* The sor of next run (if any) should be technically equal to eor of this run. */
|
||||
sor = eor;
|
||||
/* The next run (if any) will start from this index. */
|
||||
firstLink = link;
|
||||
|
||||
priorLevel = currentLevel;
|
||||
}
|
||||
|
||||
priorLink = link;
|
||||
}
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
static SBBoolean ProcessRun(ParagraphContextRef context, const LevelRunRef levelRun, SBBoolean forceFinish)
|
||||
{
|
||||
RunQueueRef queue = &context->runQueue;
|
||||
|
||||
if (!RunQueueEnqueue(queue, levelRun)) {
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
if (queue->shouldDequeue || forceFinish) {
|
||||
IsolatingRunRef isolatingRun = &context->isolatingRun;
|
||||
LevelRunRef peek;
|
||||
|
||||
/* Rule X10 */
|
||||
for (; queue->count != 0; RunQueueDequeue(queue)) {
|
||||
peek = queue->peek;
|
||||
if (RunKindIsAttachedTerminating(peek->kind)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
isolatingRun->baseLevelRun = peek;
|
||||
|
||||
if (!IsolatingRunResolve(isolatingRun)) {
|
||||
return SBFalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
static void SaveLevels(BidiChainRef chain, SBLevel *levels, SBLevel baseLevel)
|
||||
{
|
||||
BidiLink roller = chain->roller;
|
||||
BidiLink link;
|
||||
|
||||
SBUInteger index = 0;
|
||||
SBLevel level = baseLevel;
|
||||
|
||||
BidiChainForEach(chain, roller, link) {
|
||||
SBUInteger offset = BidiChainGetOffset(chain, link);
|
||||
|
||||
for (; index < offset; index++) {
|
||||
levels[index] = level;
|
||||
}
|
||||
|
||||
level = BidiChainGetLevel(chain, link);
|
||||
}
|
||||
}
|
||||
|
||||
static SBBoolean ResolveParagraph(SBParagraphRef paragraph,
|
||||
SBAlgorithmRef algorithm, SBUInteger offset, SBUInteger length, SBLevel baseLevel)
|
||||
{
|
||||
const SBBidiType *bidiTypes = algorithm->fixedTypes + offset;
|
||||
SBBoolean isSucceeded = SBFalse;
|
||||
ParagraphContextRef context;
|
||||
SBLevel resolvedLevel;
|
||||
|
||||
context = CreateParagraphContext(bidiTypes, paragraph->fixedLevels, length);
|
||||
|
||||
if (context) {
|
||||
resolvedLevel = DetermineParagraphLevel(&context->bidiChain, baseLevel);
|
||||
|
||||
SB_LOG_BLOCK_OPENER("Determined Paragraph Level");
|
||||
SB_LOG_STATEMENT("Base Level", 1, SB_LOG_LEVEL(resolvedLevel));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
context->isolatingRun.codepointSequence = &algorithm->codepointSequence;
|
||||
context->isolatingRun.bidiTypes = bidiTypes;
|
||||
context->isolatingRun.bidiChain = &context->bidiChain;
|
||||
context->isolatingRun.paragraphOffset = offset;
|
||||
context->isolatingRun.paragraphLevel = resolvedLevel;
|
||||
|
||||
if (DetermineLevels(context, resolvedLevel)) {
|
||||
SaveLevels(&context->bidiChain, ++paragraph->fixedLevels, resolvedLevel);
|
||||
|
||||
SB_LOG_BLOCK_OPENER("Determined Embedding Levels");
|
||||
SB_LOG_STATEMENT("Levels", 1, SB_LOG_LEVELS_ARRAY(paragraph->fixedLevels, length));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
paragraph->algorithm = SBAlgorithmRetain(algorithm);
|
||||
paragraph->refTypes = bidiTypes;
|
||||
paragraph->offset = offset;
|
||||
paragraph->length = length;
|
||||
paragraph->baseLevel = resolvedLevel;
|
||||
paragraph->retainCount = 1;
|
||||
|
||||
isSucceeded = SBTrue;
|
||||
}
|
||||
|
||||
DisposeParagraphContext(context);
|
||||
}
|
||||
|
||||
return isSucceeded;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBParagraphRef SBParagraphCreate(SBAlgorithmRef algorithm,
|
||||
SBUInteger paragraphOffset, SBUInteger suggestedLength, SBLevel baseLevel)
|
||||
{
|
||||
const SBCodepointSequence *codepointSequence = &algorithm->codepointSequence;
|
||||
SBUInteger stringLength = codepointSequence->stringLength;
|
||||
SBUInteger actualLength;
|
||||
|
||||
SBParagraphRef paragraph;
|
||||
|
||||
/* The given range MUST be valid. */
|
||||
SBAssert(SBUIntegerVerifyRange(stringLength, paragraphOffset, suggestedLength) && suggestedLength > 0);
|
||||
|
||||
SB_LOG_BLOCK_OPENER("Paragraph Input");
|
||||
SB_LOG_STATEMENT("Paragraph Offset", 1, SB_LOG_NUMBER(paragraphOffset));
|
||||
SB_LOG_STATEMENT("Suggested Length", 1, SB_LOG_NUMBER(suggestedLength));
|
||||
SB_LOG_STATEMENT("Base Direction", 1, SB_LOG_BASE_LEVEL(baseLevel));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
actualLength = DetermineBoundary(algorithm, paragraphOffset, suggestedLength);
|
||||
|
||||
SB_LOG_BLOCK_OPENER("Determined Paragraph Boundary");
|
||||
SB_LOG_STATEMENT("Actual Length", 1, SB_LOG_NUMBER(actualLength));
|
||||
SB_LOG_BLOCK_CLOSER();
|
||||
|
||||
paragraph = AllocateParagraph(actualLength);
|
||||
|
||||
if (paragraph) {
|
||||
if (ResolveParagraph(paragraph, algorithm, paragraphOffset, actualLength, baseLevel)) {
|
||||
return paragraph;
|
||||
}
|
||||
|
||||
DisposeParagraph(paragraph);
|
||||
}
|
||||
|
||||
SB_LOG_BREAKER();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SBUInteger SBParagraphGetOffset(SBParagraphRef paragraph)
|
||||
{
|
||||
return paragraph->offset;
|
||||
}
|
||||
|
||||
SBUInteger SBParagraphGetLength(SBParagraphRef paragraph)
|
||||
{
|
||||
return paragraph->length;
|
||||
}
|
||||
|
||||
SBLevel SBParagraphGetBaseLevel(SBParagraphRef paragraph)
|
||||
{
|
||||
return paragraph->baseLevel;
|
||||
}
|
||||
|
||||
const SBLevel *SBParagraphGetLevelsPtr(SBParagraphRef paragraph)
|
||||
{
|
||||
return paragraph->fixedLevels;
|
||||
}
|
||||
|
||||
SBLineRef SBParagraphCreateLine(SBParagraphRef paragraph, SBUInteger lineOffset, SBUInteger lineLength)
|
||||
{
|
||||
SBUInteger paragraphOffset = paragraph->offset;
|
||||
SBUInteger paragraphLength = paragraph->length;
|
||||
SBUInteger paragraphLimit = paragraphOffset + paragraphLength;
|
||||
SBUInteger lineLimit = lineOffset + lineLength;
|
||||
|
||||
if (lineOffset < lineLimit && lineOffset >= paragraphOffset && lineLimit <= paragraphLimit) {
|
||||
return SBLineCreate(paragraph, lineOffset, lineLength);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SBParagraphRef SBParagraphRetain(SBParagraphRef paragraph)
|
||||
{
|
||||
if (paragraph) {
|
||||
paragraph->retainCount += 1;
|
||||
}
|
||||
|
||||
return paragraph;
|
||||
}
|
||||
|
||||
void SBParagraphRelease(SBParagraphRef paragraph)
|
||||
{
|
||||
if (paragraph && --paragraph->retainCount == 0) {
|
||||
SBAlgorithmRelease(paragraph->algorithm);
|
||||
DisposeParagraph(paragraph);
|
||||
}
|
||||
}
|
||||
38
modules/juce_graphics/unicode/sheenbidi/Source/SBParagraph.h
Normal file
38
modules/juce_graphics/unicode/sheenbidi/Source/SBParagraph.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_PARAGRAPH_H
|
||||
#define _SB_INTERNAL_PARAGRAPH_H
|
||||
|
||||
#include <SBAlgorithm.h>
|
||||
#include <SBBase.h>
|
||||
#include <SBConfig.h>
|
||||
#include <SBParagraph.h>
|
||||
|
||||
typedef struct _SBParagraph {
|
||||
SBAlgorithmRef algorithm;
|
||||
const SBBidiType *refTypes;
|
||||
SBLevel *fixedLevels;
|
||||
SBUInteger offset;
|
||||
SBUInteger length;
|
||||
SBLevel baseLevel;
|
||||
SBUInteger retainCount;
|
||||
} SBParagraph;
|
||||
|
||||
SB_INTERNAL SBParagraphRef SBParagraphCreate(SBAlgorithmRef algorithm,
|
||||
SBUInteger paragraphOffset, SBUInteger suggestedLength, SBLevel baseLevel);
|
||||
|
||||
#endif
|
||||
176
modules/juce_graphics/unicode/sheenbidi/Source/SBScriptLocator.c
Normal file
176
modules/juce_graphics/unicode/sheenbidi/Source/SBScriptLocator.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Copyright (C) 2018-2022 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 <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "GeneralCategoryLookup.h"
|
||||
#include "PairingLookup.h"
|
||||
#include "SBBase.h"
|
||||
#include "SBCodepointSequence.h"
|
||||
#include "ScriptLookup.h"
|
||||
#include "ScriptStack.h"
|
||||
#include "SBScriptLocator.h"
|
||||
|
||||
static SBBoolean IsSimilarScript(SBScript lhs, SBScript rhs)
|
||||
{
|
||||
return SBScriptIsCommonOrInherited(lhs)
|
||||
|| SBScriptIsCommonOrInherited(rhs)
|
||||
|| lhs == rhs;
|
||||
}
|
||||
|
||||
SBScriptLocatorRef SBScriptLocatorCreate(void)
|
||||
{
|
||||
SBScriptLocatorRef locator = malloc(sizeof(SBScriptLocator));
|
||||
|
||||
if (locator) {
|
||||
locator->_codepointSequence.stringEncoding = SBStringEncodingUTF8;
|
||||
locator->_codepointSequence.stringBuffer = NULL;
|
||||
locator->_codepointSequence.stringLength = 0;
|
||||
locator->retainCount = 1;
|
||||
|
||||
SBScriptLocatorReset(locator);
|
||||
}
|
||||
|
||||
return locator;
|
||||
}
|
||||
|
||||
void SBScriptLocatorLoadCodepoints(SBScriptLocatorRef locator, const SBCodepointSequence *codepointSequence)
|
||||
{
|
||||
locator->_codepointSequence = *codepointSequence;
|
||||
SBScriptLocatorReset(locator);
|
||||
}
|
||||
|
||||
const SBScriptAgent *SBScriptLocatorGetAgent(SBScriptLocatorRef locator)
|
||||
{
|
||||
return &locator->agent;
|
||||
}
|
||||
|
||||
static void ResolveScriptRun(SBScriptLocatorRef locator, SBUInteger offset)
|
||||
{
|
||||
const SBCodepointSequence *sequence = &locator->_codepointSequence;
|
||||
ScriptStackRef stack = &locator->_scriptStack;
|
||||
SBScript result = SBScriptZYYY;
|
||||
SBUInteger current = offset;
|
||||
SBUInteger next = offset;
|
||||
SBCodepoint codepoint;
|
||||
|
||||
/* Iterate over the code points of specified string buffer. */
|
||||
while ((codepoint = SBCodepointSequenceGetCodepointAt(sequence, &next)) != SBCodepointInvalid) {
|
||||
SBBoolean isStacked = SBFalse;
|
||||
SBScript script;
|
||||
|
||||
script = LookupScript(codepoint);
|
||||
|
||||
/* Handle paired punctuations in case of a common script. */
|
||||
if (script == SBScriptZYYY) {
|
||||
SBGeneralCategory generalCategory = LookupGeneralCategory(codepoint);
|
||||
|
||||
/* Check if current code point is an open punctuation. */
|
||||
if (generalCategory == SBGeneralCategoryPS) {
|
||||
SBCodepoint mirror = LookupMirror(codepoint);
|
||||
if (mirror) {
|
||||
/* A closing pair exists for this punctuation, so push it onto the stack. */
|
||||
ScriptStackPush(stack, result, mirror);
|
||||
}
|
||||
}
|
||||
/* Check if current code point is a close punctuation. */
|
||||
else if (generalCategory == SBGeneralCategoryPE) {
|
||||
SBBoolean isMirrored = (LookupMirror(codepoint) != 0);
|
||||
if (isMirrored) {
|
||||
/* Find the matching entry in the stack, while popping the unmatched ones. */
|
||||
while (!ScriptStackIsEmpty(stack)) {
|
||||
SBCodepoint mirror = ScriptStackGetMirror(stack);
|
||||
if (mirror != codepoint) {
|
||||
ScriptStackPop(stack);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ScriptStackIsEmpty(stack)) {
|
||||
isStacked = SBTrue;
|
||||
/* Paired punctuation match the script of enclosing text. */
|
||||
script = ScriptStackGetScript(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsSimilarScript(result, script)) {
|
||||
if (SBScriptIsCommonOrInherited(result) && !SBScriptIsCommonOrInherited(script)) {
|
||||
/* Set the concrete script of this code point as the result. */
|
||||
result = script;
|
||||
/* Seal the pending punctuations with the result. */
|
||||
ScriptStackSealPairs(stack, result);
|
||||
}
|
||||
|
||||
if (isStacked) {
|
||||
/* Pop the paired punctuation from the stack. */
|
||||
ScriptStackPop(stack);
|
||||
}
|
||||
} else {
|
||||
/* The current code point has a different script, so finish the run. */
|
||||
break;
|
||||
}
|
||||
|
||||
current = next;
|
||||
}
|
||||
|
||||
ScriptStackLeavePairs(stack);
|
||||
|
||||
/* Set the run info in agent. */
|
||||
locator->agent.offset = offset;
|
||||
locator->agent.length = current - offset;
|
||||
locator->agent.script = result;
|
||||
}
|
||||
|
||||
SBBoolean SBScriptLocatorMoveNext(SBScriptLocatorRef locator)
|
||||
{
|
||||
SBUInteger offset = locator->agent.offset + locator->agent.length;
|
||||
|
||||
if (offset < locator->_codepointSequence.stringLength) {
|
||||
ResolveScriptRun(locator, offset);
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
SBScriptLocatorReset(locator);
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
void SBScriptLocatorReset(SBScriptLocatorRef locator)
|
||||
{
|
||||
ScriptStackReset(&locator->_scriptStack);
|
||||
locator->agent.offset = 0;
|
||||
locator->agent.length = 0;
|
||||
locator->agent.script = SBScriptNil;
|
||||
}
|
||||
|
||||
SBScriptLocatorRef SBScriptLocatorRetain(SBScriptLocatorRef locator)
|
||||
{
|
||||
if (locator) {
|
||||
locator->retainCount += 1;
|
||||
}
|
||||
|
||||
return locator;
|
||||
}
|
||||
|
||||
void SBScriptLocatorRelease(SBScriptLocatorRef locator)
|
||||
{
|
||||
if (locator && --locator->retainCount == 0) {
|
||||
free(locator);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2018-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_SCRIPT_LOCATOR_H
|
||||
#define _SB_INTERNAL_SCRIPT_LOCATOR_H
|
||||
|
||||
#include <SBBase.h>
|
||||
#include <SBCodepointSequence.h>
|
||||
#include <SBScriptLocator.h>
|
||||
|
||||
#include "ScriptStack.h"
|
||||
|
||||
typedef struct _SBScriptLocator {
|
||||
SBCodepointSequence _codepointSequence;
|
||||
ScriptStack _scriptStack;
|
||||
SBScriptAgent agent;
|
||||
SBUInteger retainCount;
|
||||
} SBScriptLocator;
|
||||
|
||||
#endif
|
||||
2282
modules/juce_graphics/unicode/sheenbidi/Source/ScriptLookup.c
Normal file
2282
modules/juce_graphics/unicode/sheenbidi/Source/ScriptLookup.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Automatically generated by SheenBidiGenerator tool.
|
||||
* DO NOT EDIT!!
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_SCRIPT_LOOKUP_H
|
||||
#define _SB_INTERNAL_SCRIPT_LOOKUP_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
#include <SBScript.h>
|
||||
|
||||
#include "SBBase.h"
|
||||
|
||||
SB_INTERNAL SBScript LookupScript(SBCodepoint codepoint);
|
||||
|
||||
#endif
|
||||
83
modules/juce_graphics/unicode/sheenbidi/Source/ScriptStack.c
Normal file
83
modules/juce_graphics/unicode/sheenbidi/Source/ScriptStack.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2018-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 <SBConfig.h>
|
||||
|
||||
#include "SBAssert.h"
|
||||
#include "SBBase.h"
|
||||
#include "ScriptStack.h"
|
||||
|
||||
SB_INTERNAL void ScriptStackReset(ScriptStackRef stack)
|
||||
{
|
||||
stack->top = -1;
|
||||
stack->count = 0;
|
||||
stack->open = 0;
|
||||
}
|
||||
|
||||
SB_INTERNAL void ScriptStackPush(ScriptStackRef stack, SBScript script, SBCodepoint mirror)
|
||||
{
|
||||
stack->count = SBNumberLimitIncrement(stack->count, _SBScriptStackCapacity);
|
||||
stack->open = SBNumberLimitIncrement(stack->open, _SBScriptStackCapacity);
|
||||
|
||||
stack->top = SBNumberRingIncrement(stack->top, _SBScriptStackCapacity);
|
||||
stack->_elements[stack->top].script = script;
|
||||
stack->_elements[stack->top].mirror = mirror;
|
||||
}
|
||||
|
||||
SB_INTERNAL void ScriptStackPop(ScriptStackRef stack)
|
||||
{
|
||||
/* There must be at least one entry in the stack. */
|
||||
SBAssert(stack->count > 0);
|
||||
|
||||
stack->count -= 1;
|
||||
stack->open = SBNumberLimitDecrement(stack->open, 0);
|
||||
stack->top = SBNumberRingDecrement(stack->top, _SBScriptStackCapacity);
|
||||
|
||||
if (ScriptStackIsEmpty(stack)) {
|
||||
stack->top = -1;
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL void ScriptStackLeavePairs(ScriptStackRef stack)
|
||||
{
|
||||
stack->open = 0;
|
||||
}
|
||||
|
||||
SB_INTERNAL void ScriptStackSealPairs(ScriptStackRef stack, SBScript script)
|
||||
{
|
||||
SBInteger index = SBNumberRingSubtract(stack->top, (SBInteger)stack->open, _SBScriptStackCapacity);
|
||||
|
||||
while (stack->open) {
|
||||
index = SBNumberRingIncrement(index, _SBScriptStackCapacity);
|
||||
stack->_elements[index].script = script;
|
||||
stack->open -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean ScriptStackIsEmpty(ScriptStackRef stack)
|
||||
{
|
||||
return (stack->count == 0);
|
||||
}
|
||||
|
||||
SB_INTERNAL SBScript ScriptStackGetScript(ScriptStackRef stack)
|
||||
{
|
||||
return stack->_elements[stack->top].script;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBCodepoint ScriptStackGetMirror(ScriptStackRef stack)
|
||||
{
|
||||
return stack->_elements[stack->top].mirror;
|
||||
}
|
||||
49
modules/juce_graphics/unicode/sheenbidi/Source/ScriptStack.h
Normal file
49
modules/juce_graphics/unicode/sheenbidi/Source/ScriptStack.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2018-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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_SCRIPT_STACK_H
|
||||
#define _SB_INTERNAL_SCRIPT_STACK_H
|
||||
|
||||
#include <SBBase.h>
|
||||
#include <SBConfig.h>
|
||||
|
||||
#define _SBScriptStackCapacity 63
|
||||
|
||||
typedef struct _SBScriptStackElement {
|
||||
SBScript script;
|
||||
SBCodepoint mirror;
|
||||
} _SBScriptStackElement;
|
||||
|
||||
typedef struct _SBScriptStack {
|
||||
_SBScriptStackElement _elements[_SBScriptStackCapacity];
|
||||
SBInteger top;
|
||||
SBUInteger count;
|
||||
SBUInteger open;
|
||||
} ScriptStack, *ScriptStackRef;
|
||||
|
||||
SB_INTERNAL void ScriptStackReset(ScriptStackRef stack);
|
||||
|
||||
SB_INTERNAL void ScriptStackPush(ScriptStackRef stack, SBScript script, SBCodepoint mirror);
|
||||
SB_INTERNAL void ScriptStackPop(ScriptStackRef stack);
|
||||
|
||||
SB_INTERNAL void ScriptStackLeavePairs(ScriptStackRef stack);
|
||||
SB_INTERNAL void ScriptStackSealPairs(ScriptStackRef stack, SBScript script);
|
||||
|
||||
SB_INTERNAL SBBoolean ScriptStackIsEmpty(ScriptStackRef stack);
|
||||
SB_INTERNAL SBScript ScriptStackGetScript(ScriptStackRef stack);
|
||||
SB_INTERNAL SBCodepoint ScriptStackGetMirror(ScriptStackRef stack);
|
||||
|
||||
#endif
|
||||
42
modules/juce_graphics/unicode/sheenbidi/Source/SheenBidi.c
Normal file
42
modules/juce_graphics/unicode/sheenbidi/Source/SheenBidi.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2014-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 <SBConfig.h>
|
||||
#include <SheenBidi.h>
|
||||
|
||||
#ifdef SB_CONFIG_UNITY
|
||||
|
||||
#include "BidiChain.c"
|
||||
#include "BidiTypeLookup.c"
|
||||
#include "BracketQueue.c"
|
||||
#include "GeneralCategoryLookup.c"
|
||||
#include "IsolatingRun.c"
|
||||
#include "LevelRun.c"
|
||||
#include "PairingLookup.c"
|
||||
#include "RunQueue.c"
|
||||
#include "SBAlgorithm.c"
|
||||
#include "SBBase.c"
|
||||
#include "SBCodepointSequence.c"
|
||||
#include "SBLine.c"
|
||||
#include "SBLog.c"
|
||||
#include "SBMirrorLocator.c"
|
||||
#include "SBParagraph.c"
|
||||
#include "SBScriptLocator.c"
|
||||
#include "ScriptLookup.c"
|
||||
#include "ScriptStack.c"
|
||||
#include "StatusStack.c"
|
||||
|
||||
#endif
|
||||
124
modules/juce_graphics/unicode/sheenbidi/Source/StatusStack.c
Normal file
124
modules/juce_graphics/unicode/sheenbidi/Source/StatusStack.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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 <SBConfig.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "SBAssert.h"
|
||||
#include "SBBase.h"
|
||||
#include "StatusStack.h"
|
||||
|
||||
static SBBoolean StatusStackInsertElement(StatusStackRef stack)
|
||||
{
|
||||
if (stack->_peekTop != _StatusStackList_MaxIndex) {
|
||||
stack->_peekTop += 1;
|
||||
} else {
|
||||
_StatusStackListRef previousList = stack->_peekList;
|
||||
_StatusStackListRef peekList = previousList->next;
|
||||
|
||||
if (!peekList) {
|
||||
peekList = malloc(sizeof(_StatusStackList));
|
||||
if (!peekList) {
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
peekList->previous = previousList;
|
||||
peekList->next = NULL;
|
||||
|
||||
previousList->next = peekList;
|
||||
}
|
||||
|
||||
stack->_peekList = peekList;
|
||||
stack->_peekTop = 0;
|
||||
}
|
||||
stack->count += 1;
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
SB_INTERNAL void StatusStackInitialize(StatusStackRef stack)
|
||||
{
|
||||
stack->_firstList.previous = NULL;
|
||||
stack->_firstList.next = NULL;
|
||||
|
||||
StatusStackSetEmpty(stack);
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean StatusStackPush(StatusStackRef stack,
|
||||
SBLevel embeddingLevel, SBBidiType overrideStatus, SBBoolean isolateStatus)
|
||||
{
|
||||
/* The stack can hold upto 127 elements. */
|
||||
SBAssert(stack->count <= 127);
|
||||
|
||||
if (StatusStackInsertElement(stack)) {
|
||||
_StatusStackElementRef element = &stack->_peekList->elements[stack->_peekTop];
|
||||
element->embeddingLevel = embeddingLevel;
|
||||
element->overrideStatus = overrideStatus;
|
||||
element->isolateStatus = isolateStatus;
|
||||
|
||||
return SBTrue;
|
||||
}
|
||||
|
||||
return SBFalse;
|
||||
}
|
||||
|
||||
SB_INTERNAL void StatusStackPop(StatusStackRef stack)
|
||||
{
|
||||
/* The stack should not be empty. */
|
||||
SBAssert(stack->count != 0);
|
||||
|
||||
if (stack->_peekTop != 0) {
|
||||
stack->_peekTop -= 1;
|
||||
} else {
|
||||
stack->_peekList = stack->_peekList->previous;
|
||||
stack->_peekTop = _StatusStackList_MaxIndex;
|
||||
}
|
||||
stack->count -= 1;
|
||||
}
|
||||
|
||||
SB_INTERNAL void StatusStackSetEmpty(StatusStackRef stack)
|
||||
{
|
||||
stack->_peekList = &stack->_firstList;
|
||||
stack->_peekTop = 0;
|
||||
stack->count = 0;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBLevel StatusStackGetEmbeddingLevel(StatusStackRef stack)
|
||||
{
|
||||
return stack->_peekList->elements[stack->_peekTop].embeddingLevel;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBidiType StatusStackGetOverrideStatus(StatusStackRef stack)
|
||||
{
|
||||
return stack->_peekList->elements[stack->_peekTop].overrideStatus;
|
||||
}
|
||||
|
||||
SB_INTERNAL SBBoolean StatusStackGetIsolateStatus(StatusStackRef stack)
|
||||
{
|
||||
return stack->_peekList->elements[stack->_peekTop].isolateStatus;
|
||||
}
|
||||
|
||||
SB_INTERNAL void StatusStackFinalize(StatusStackRef stack)
|
||||
{
|
||||
_StatusStackListRef list = stack->_firstList.next;
|
||||
|
||||
while (list) {
|
||||
_StatusStackListRef next = list->next;
|
||||
free(list);
|
||||
list = next;
|
||||
};
|
||||
}
|
||||
58
modules/juce_graphics/unicode/sheenbidi/Source/StatusStack.h
Normal file
58
modules/juce_graphics/unicode/sheenbidi/Source/StatusStack.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2022 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.
|
||||
*/
|
||||
|
||||
#ifndef _SB_INTERNAL_STATUS_STACK_H
|
||||
#define _SB_INTERNAL_STATUS_STACK_H
|
||||
|
||||
#include <SBConfig.h>
|
||||
#include "SBBase.h"
|
||||
|
||||
#define _StatusStackList_Length 16
|
||||
#define _StatusStackList_MaxIndex (_StatusStackList_Length - 1)
|
||||
|
||||
typedef struct _StatusStackElement {
|
||||
SBBoolean isolateStatus;
|
||||
SBBidiType overrideStatus;
|
||||
SBLevel embeddingLevel;
|
||||
} _StatusStackElement, *_StatusStackElementRef;
|
||||
|
||||
typedef struct _StatusStackList {
|
||||
_StatusStackElement elements[_StatusStackList_Length];
|
||||
|
||||
struct _StatusStackList *previous;
|
||||
struct _StatusStackList *next;
|
||||
} _StatusStackList, *_StatusStackListRef;
|
||||
|
||||
typedef struct _StatusStack {
|
||||
_StatusStackList _firstList;
|
||||
_StatusStackListRef _peekList;
|
||||
SBUInteger _peekTop;
|
||||
SBUInteger count;
|
||||
} StatusStack, *StatusStackRef;
|
||||
|
||||
SB_INTERNAL void StatusStackInitialize(StatusStackRef stack);
|
||||
SB_INTERNAL void StatusStackFinalize(StatusStackRef stack);
|
||||
|
||||
SB_INTERNAL SBBoolean StatusStackPush(StatusStackRef stack,
|
||||
SBLevel embeddingLevel, SBBidiType overrideStatus, SBBoolean isolateStatus);
|
||||
SB_INTERNAL void StatusStackPop(StatusStackRef stack);
|
||||
SB_INTERNAL void StatusStackSetEmpty(StatusStackRef stack);
|
||||
|
||||
SB_INTERNAL SBLevel StatusStackGetEmbeddingLevel(StatusStackRef stack);
|
||||
SB_INTERNAL SBBidiType StatusStackGetOverrideStatus(StatusStackRef stack);
|
||||
SB_INTERNAL SBBoolean StatusStackGetIsolateStatus(StatusStackRef stack);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue