/** * 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. */ #include "stoolkit/SEmbedState.h" #include "stoolkit/SCharClass.h" static SS_UCS4 stateMap[4] = { SD_CD_LRO, SD_CD_LRE, SD_CD_RLO, SD_CD_RLE, }; /** * This is a state class that stores the embedding history. * Currently it supports 32+32/4 = 16 embedding levels. * To support more you need to add exstatexx. */ /** * Check if state is equal */ bool SEmbedState::operator==(const SEmbedState& es) const { return (explevel == es.explevel && memcmp (states, es.states, sizeof (states)) == 0); } /** * Check if state is not equal */ bool SEmbedState::operator!=(const SEmbedState& es) const { return (explevel != es.explevel || memcmp (states, es.states, sizeof (states)) != 0); } /** * exstate0 and exstate1 are operated with this. @ @param level is the current (real) level * @return an index into stateMap */ unsigned int SEmbedState::getMark(unsigned int level) const { unsigned int line = level/8; unsigned int index = (level%8)*4; return ((states[line] >> index) & 0x3); } /** * exstate0 and exstate1 are operated with this. @ @param level is the current (real) level * @mark is an index into stateMap */ void SEmbedState::setMark (unsigned int level, unsigned int _mark) { unsigned int line = level/8; unsigned int index = (level%8)*4; unsigned int mask = ((0x3 << index) ^ 0xffffffff); states[line] = states[line] & mask; states[line] = states[line] | (_mark << index); } /* Return embedding marks */ SV_UCS4 SEmbedState::getEmbeddingMarks (const SEmbedState* from) const { SV_UCS4 ret; unsigned int depfrom = (from==0) ? 0 : from->getDepth(); unsigned int depto = getDepth(); unsigned int min = (depfrom < depto) ? depfrom : depto; /* skip the common ones */ unsigned int i = 0; for (i=0; igetMark(i)!=getMark(i)) break; } /* fill in the space with PDF */ for (unsigned int j=i; j=2 && (emb&1) == 1) emb++; if (mark<2 && (emb&1) == 0) emb++; emb++; } return ret; } /** * Set the overriding state from stack * Stack can contain only glyphs that are in stateMap. */ void SEmbedState::setEmbeddingMarks (const SV_UCS4& stack) { memset (states, 0, sizeof (states)); explevel = 0; /* our max embeding is 16 */ unsigned int level = 0; for (unsigned int i=0; i SD_BIDI_MAX_EMBED) break; level++; level++; } else if ((mark==0 || mark == 1) && (level&1) == 0) { if (level+2 > SD_BIDI_MAX_EMBED) break; level++; level++; } else { if (level+1 > SD_BIDI_MAX_EMBED) break; level++; } /* RL is 2 and 3 */ setExplicitLevel (level, override); setMark (i, mark); } return; } /** * Used for debug. */ SString SEmbedState::toString() const { SString ret; ret.append ("["); char s[12]; SV_UCS4 v = getEmbeddingMarks(0); const char* c = ""; for (unsigned int i=0; i