/** * Yudit Unicode Editor Source File * * GNU Copyright (C) 1997-2006 Gaspar Sinai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, * dated June 1991. See file COPYYING for details. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /** * I collected most of the Unicode Implicit bidi * algortihm in this class, so it will be easier * to throw it away. */ #include "stoolkit/SBiDi.h" /** * This is the segment, that can independently resolve types. */ SBiDiSegment::SBiDiSegment (SD_BiDiClass* _classes) { classes = _classes; from = 0; till = 0; sor = true; eor = true; } SBiDiSegment::~SBiDiSegment() { } static bool debugFlag = false; /** * This will resolve the weak and the neutral types. * FIXME: This is the only thing that is not yet finished. */ void SBiDiSegment::resolveWeakNeutral() { unsigned int i; unsigned int j; SD_BiDiClass first = sor ? SD_BC_L : SD_BC_R; SD_BiDiClass last = eor ? SD_BC_L : SD_BC_R; if (debugFlag) { fprintf (stderr, "RES from=%u till=%u sor=%d eor=%d level=%u\n", from, till, (int)sor, (int)eor, level); } /* W1 */ SD_BiDiClass curr = first; for (i=from; i0; j--) { SD_BiDiClass c = classes[j-1]; if (c==SD_BC_L || c==SD_BC_R || c==SD_BC_AL) { if (c==SD_BC_AL) classes[i] = SD_BC_AN; break; } } // first is never AL, it is either L or R //if (j==0) classes[i] = first; } } /* W3 */ for (i=from; i0; j--) { SD_BiDiClass c = classes[j-1]; if (c==SD_BC_L || c==SD_BC_R) { if (c==SD_BC_L) classes[i] = SD_BC_L; break; } } if (j==0 && first==SD_BC_L) classes[i] = first; } } /* Resolving Neutral Types */ /* Neutral is non: R L AN EN */ /* N1 */ curr = first; for (i=from; isor = (initLevel%2) == 0; lastSegment->level = lastLevel; lastSize = 0; } SBiDi::~SBiDi () { delete classes; for (unsigned int i=0; itill = lastSize; lastLevel = embedLevel; return; } /* change of level at the beginning */ if (lastSegment->till==0) { lastSegment->sor = (lastLevel>embedLevel) ? ((lastLevel %2)==0) : ((embedLevel%2)==0); lastSegment->till = lastSize; lastSegment->level = lastLevel; lastLevel = embedLevel; return; } /* finish old segment */ lastSegment->eor = (lastLevel>embedLevel) ? ((lastLevel %2)==0) : ((embedLevel%2)==0); lastSegment->till = lastSize-1; /* sorry last one does not belong to us */ segments.append (lastSegment); /* new segment needed */ bool sor = (lastLevel>embedLevel) ? ((lastLevel %2)==0) : ((embedLevel%2)==0); lastLevel = embedLevel; lastSegment = new SBiDiSegment(classes); CHECK_NEW (lastSegment); lastSegment->sor = sor; /* we incremented lastSize at the beginning */ lastSegment->from = lastSize-1; lastSegment->till = lastSize; lastSegment->level = embedLevel; } void SBiDi::resolveWeakNeutral() { if (lastSize == 0) return; if (lastSegment) { lastSegment->eor = (lastLevel>initLevel) ? ((lastLevel %2)==0) : ((initLevel%2)==0); segments.append (lastSegment); /* This is how I debug */ if (segments.size()>1) { // debugFlag = true; } lastSegment = 0; } for (unsigned int i=0; iresolveWeakNeutral(); } if (segments.size()>1) debugFlag = false; } void SBiDi::insertBN (unsigned int at) { /* move up */ for (unsigned int i=lastSize; i>at; i--) { classes[i] = classes[i-1]; } lastSize++; //classes[at] = SD_BC_BN; /* make this stupid BN the type of the previous char */ /* The standard does not require any particular placement */ if (at == 0) { classes[at] = ((initLevel%2) == 0) ? SD_BC_L : SD_BC_R; return; } /* be the previous. */ classes[at] = classes[at-1]; }