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

304 lines
7.3 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>
#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 = &range;
IsolatingRunForEach(isolatingRun, &context, _SBPrintRangeOperation);
SB_LOG_RANGE(range.offset, range.length);
SB_LOG_DIVIDER(1);
}
#endif