bool XmlWriter::AppendAttributeF( const char *psAttrName, const char *psValueFmt, ... ) { EA_ASSERT_MESSAGE( mnState != kStateChars, "Attempt to append an attribute to an element that has already been closed." ); if ((mnState != kStateElement) && (mnState != kStateProcessingInstruction)) return false; /// For now, we assume that 256 is the max length for a formatted attribute. char sBuffer[ 256 ]; va_list arg; va_start( arg, psValueFmt ); const int result = vsnprintf_local( sBuffer, sizeof(sBuffer), psValueFmt, arg ); va_end( arg ); if ((unsigned)result >= sizeof(sBuffer)) // If (result < 0 or result >= sizeof(sBuffer))... return false; return (WriteText( " ", 1 ) && WriteName( psAttrName ) && WriteText( "=\"", 2 ) && WriteEscapedString( sBuffer, (unsigned)result ) && WriteText( "\"", 1 ) ); }
//////////////////////////////////////////////////////////////////////////////// // AppendAttribute // bool XmlWriter::AppendAttribute( const char *psAttrName, const char16_t *psValue ) { EA_ASSERT_MESSAGE( mnState != kStateChars, "Attempt to append an attribute to an element that has already been closed." ); if ((mnState != kStateElement) && (mnState != kStateProcessingInstruction)) return false; return (WriteText( " ", 1 ) && WriteName( psAttrName ) && WriteText( "=\"", 2 ) && WriteEscapedString( psValue, kSizeTypeNull ) && WriteText( "\"", 1 ) ); }
/////////////////////////////////////////////////////////////////////////////// // 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; }