stk-code_catmod/lib/sheenbidi/Source/BidiChain.c

111 lines
2.8 KiB
C

/*
* 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;
}