int Bcj2_Decode( const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, const Byte *buf2, SizeT size2, const Byte *buf3, SizeT size3, Byte *outBuf, SizeT outSize) { CProb p[256 + 2]; SizeT inPos = 0, outPos = 0; const Byte *buffer, *bufferLim; UInt32 range, code; Byte prevByte = 0; unsigned int i; for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) p[i] = kBitModelTotal >> 1; buffer = buf3; bufferLim = buffer + size3; RC_INIT2 if (outSize == 0) return SZ_OK; for (;;) { Byte b; CProb *prob; UInt32 bound; UInt32 ttt; SizeT limit = size0 - inPos; if (outSize - outPos < limit) limit = outSize - outPos; while (limit != 0) { Byte b = buf0[inPos]; outBuf[outPos++] = b; if (IsJ(prevByte, b)) break; inPos++; prevByte = b; limit--; } if (limit == 0 || outPos == outSize) break; b = buf0[inPos++]; if (b == 0xE8) prob = p + prevByte; else if (b == 0xE9) prob = p + 256; else prob = p + 257; IF_BIT_0(prob) { UPDATE_0(prob) prevByte = b; } else { UInt32 dest; const Byte *v; UPDATE_1(prob) if (b == 0xE8) { v = buf1; if (size1 < 4) return SZ_ERROR_DATA; buf1 += 4; size1 -= 4; } else { v = buf2; if (size2 < 4) return SZ_ERROR_DATA; buf2 += 4; size2 -= 4; } dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); outBuf[outPos++] = (Byte)dest; if (outPos == outSize) break; outBuf[outPos++] = (Byte)(dest >> 8); if (outPos == outSize) break; outBuf[outPos++] = (Byte)(dest >> 16); if (outPos == outSize) break; outBuf[outPos++] = prevByte = (Byte)(dest >> 24); } }
/////////////////////////////////////////////////////////////////////////////// // GetHangulCharCluster // // The return value is the number of chars eaten; clusterSize is the number of // chars generated. In the large majority of cases, they will be equal. // eastl_size_t Typesetter::GetHangulCharCluster(eastl_size_t i, eastl_size_t iCharEnd, Char* pCharCluster, eastl_size_t& clusterSize, int& clusterType) { EA_ASSERT((i < iCharEnd) && (iCharEnd <= mLineLayout.mCharArray.size())); bool bCompose = false; // To do: Make this configurable, perhaps part of LayoutSettings. eastl_size_t charCount = 0; if(!bCompose) // If we leave the characters as-is and don't convert Jamo to composed syllables... { clusterType = kHangulClusterTypeUnicode; pCharCluster[0] = mLineLayout.mCharArray[i]; clusterSize = 1; charCount = 1; } else { clusterSize = 0; clusterType = kHangulClusterTypeJamo; // This might change below. for(const Char* p = &mLineLayout.mCharArray[i], *pEnd = &mLineLayout.mCharArray[iCharEnd]; (p < pEnd) && (clusterSize < kMaxHangulCharClusterSize); ++p, ++charCount) { const Char c = *p; const bool bIsAnyHangul = (IsS(c) || IsJ(c) || IsTone(c)); if(clusterSize != 0) // If this is not the first char in the cluster... { const Char cPrev = p[-1]; // If the current character cannot combine with the previous character... // To consider: This should be a table lookup instead of a bunch of comparisons. if(!bIsAnyHangul || ( IsT(cPrev) && IsL(c)) || ( IsV(cPrev) && IsL(c)) || ( IsT(cPrev) && IsV(c)) || (!IsL(cPrev) && IsS(c)) || IsTone(cPrev)) { // We have a completed syllable. break; } } if(!bIsAnyHangul) // If not any kind of Hangul (syllable, jamo, tone)... { // We have non-Hangul Unicode (e.g. Latin or simply a space chars). pCharCluster[clusterSize++] = c; ++charCount; clusterType = kHangulClusterTypeUnicode; break; } else if(IsS(c)) // If the char is a Hangul syllable... { // We break the Hangul syllable down to its Jamo components. // We'll put them back together again in the next step of // the shaping pipeline. pCharCluster[clusterSize++] = GetL(c); pCharCluster[clusterSize++] = GetV(c); if(HasT(c)) pCharCluster[clusterSize++] = GetT(c); } else if((clusterSize == 0) && IsTone(c)) // If char is an initial Hangul tone... { // We have a standalone tone. pCharCluster[clusterSize++] = c; ++charCount; clusterType = kHangulClusterTypeTone; break; } else pCharCluster[clusterSize++] = c; // Else we are working with individual Jamo symbols... } } EA_ASSERT_MESSAGE(clusterType != kHangulClusterTypeNone, "Typesetter::GetHangulCharCluster: Unknown cluster type."); EA_ASSERT((charCount > 0) && (clusterSize > 0)); return charCount; }