PSI_NAMESPACE PSI_PROC( void, SimpleMessageBox )( PCOMMON parent, CTEXTSTR title, CTEXTSTR content ) { PCOMMON msg; CTEXTSTR start, end; TEXTCHAR msgtext[256]; int okay = 0; int y = 5; uint32_t width, height; uint32_t title_width, greatest_width; #ifdef USE_INTERFACES GetMyInterface(); #endif GetStringSize( content, &width, &height ); title_width = GetStringSize( title, NULL, NULL ); if( title_width > width ) greatest_width = title_width; else greatest_width = width; msg = CreateFrame( title, 0, 0 , greatest_width + 10, height + (COMMON_BUTTON_PAD * 3) + COMMON_BUTTON_HEIGHT , 0, parent ); end = start = content; do { while( end[0] && end[0] != '\n' ) end++; if( end[0] ) { MemCpy( msgtext, (POINTER)start, end-start ); msgtext[end-start] = 0; //end[0] = 0; MakeTextControl( msg, COMMON_BUTTON_PAD, y , greatest_width, height , -1, msgtext, 0 ); //end[0] = '\n'; end = start = end+1; y += height; } else MakeTextControl( msg, COMMON_BUTTON_PAD, y , greatest_width, height , -1, start, 0 ); } while( end[0] ); //AddExitButton( msg, &done ); AddCommonButtons( msg, NULL, &okay ); lprintf( WIDE("show message box") ); DisplayFrame( msg ); CommonWait( msg ); DestroyFrame( &msg ); }
static void AdjustItemsIntoBox( PSI_CONTROL pc ) { // current item must be shown in the list... uint32_t w, h; int x, y, maxchars; PLISTITEM pli; ValidatedControlData( PLISTBOX, LISTBOX_CONTROL, plb, pc ); GetStringSize( WIDE(" "), &w, &h ); maxchars = ( pc->surface_rect.width - 8 ) / w; y = 2; x = 4; // if no current, then the cursor line need not be shown // in fact first shown is first item... if( plb->current ) { plb->firstshown = plb->current; pli = plb->current; while( pli ) { y += h; pli = pli->next; } // while there's stuff above current to show, and // current will still fit integrally on the listbox // back up firstshown.... while( plb->firstshown->prior && ( SUS_LT( y, int, (pc->surface_rect.height - (h-1)),uint32_t) ) ) { y += h; plb->firstshown = plb->firstshown->prior; } }
// Image definition bool CLwoWriter::WriteImageDefinitions() { CLwoFile::CLayer::ImageVector& images = m_curLayer.GetImageVector(); CLwoFile::CLayer::ImageVector::iterator imageBegin, imageIt, imageEnd; imageBegin = images.begin(); imageEnd = images.end(); for(imageIt = imageBegin; imageIt != imageEnd; ++imageIt) // For each LWO face { std::string imagePath(*imageIt); ushort still_size = (ushort)GetStringSize(imagePath); MSG_DEBUG("CLIP | STIL: '" << imagePath << "'"); // "CLIP" + size WriteTag(CLwoFile::CHUNK_CLIP); WriteLong(4 + 4 + 2 + still_size); // imageIndex + "STIL" + stilSize + pathString ulong imageIndex = (imageIt - imageBegin); WriteLong(imageIndex); // image index : 0-based index WriteTag(CLwoFile::CHUNK_STIL); // STIL WriteShort(still_size); // Write the image path WriteString(imagePath); } return true; }
void CFontMaterial::DrawString( CDrawContext * pDrawContext, std::string text, float x, float y, float r, float g, float b, float a, int type ) { float xtrans = 0.0f, ytrans = 0.0f; float xoffset = 0.0f, yoffset = 0.0f; pDrawContext->SetTexture( m_FontSheet.GetTexture() ); pDrawContext->SetDrawColor( r, g, b, a ); if( type & ( DRAW_TEXT_HORIZ_CENTER | DRAW_TEXT_VERT_CENTER ) ) { Vector2< int > size = GetStringSize( text ); if( type & DRAW_TEXT_HORIZ_CENTER ) { xoffset = ( float )-size.GetX() * .5f; } if( type & DRAW_TEXT_VERT_CENTER ) { yoffset = ( float )-size.GetY() * .5f; } } for( int i = 0; i < text.length(); i++ ) { bool newline = false; if( text[i] == '\n' ) newline = true; if( !newline ) { int c = text[i]; CFontCharacter fchar = m_Characters[c]; Vector2< float > size = fchar.m_Size; Vector2< float > v1 = fchar.m_UpperLeftST; Vector2< float > v2 = fchar.m_LowerRightST; pDrawContext->StartDraw(); pDrawContext->SetPos( x + xoffset + xtrans + fchar.m_Left, y + yoffset + ytrans - fchar.m_Down + m_LargestBearingY ); pDrawContext->SetScale( size.GetX() , size.GetY() ); pDrawContext->SetTexCoord( v1.GetX(), v1.GetY(), v2.GetX(), v1.GetY(), v2.GetX(), v2.GetY(), v1.GetX(), v2.GetY() ); pDrawContext->EndDraw(); xtrans += fchar.m_Trans; } else { xtrans = 0; ytrans += m_FontSize; } } }
int CFontMaterial::GetStringHeight( std::string text ) { Vector2< int > v = GetStringSize( text ); return v.GetY(); }
int CFontMaterial::GetStringWidth( std::string text ) { Vector2< int > v = GetStringSize( text ); return v.GetX(); }
//============================================================================ //! 使用している文字のフィールドサイズの取得 dlBOOL C_DL2DFrameWorkText::GetStringSize(NODE_HANDLE handle , S_Vector2& out_Size_S) const { S_IntVec2 size_S; if(!GetStringSize(handle , size_S)){return dlFALSE;} out_Size_S.x = static_cast<dlF32>(size_S.x); out_Size_S.y = static_cast<dlF32>(size_S.y); return dlTRUE; }
void TextField::RemoveLastCharacterFromString() { if (GetStringSize() == 0) return; text.pop_back(); //text.erase(text.length() - 1); RenderText(); }
// Trims the right margins of a control to fit a given text string size. void CDialogTemplate::RTrimToString(WORD id, char *str, int margins) { DialogItemTemplate* item = GetItem(id); if (!item) return; SIZE size = GetStringSize(id, str); size.cx += margins; size.cy += 2; item->sWidth = short(size.cx); item->sHeight = short(size.cy); }
int MyMeshText::CreateString(bool concat, float fontheight, float x, float y, float z, float rotz, unsigned char justificationflags, ColorByte color, Vector2 size, const char* text, ...) { assert( m_pFont && m_pFont->m_pFont ); if( strlen( text ) == 0 ) return 0; const char* stringtodraw = text; if( g_pLanguageTable != 0 && text[0] == '.' ) stringtodraw = g_pLanguageTable->LookUp( text ); int numlines = 0; if( concat == false ) { ClearText(); } bool moretexttocome = true; const char* stringpos = stringtodraw; while( moretexttocome ) { numlines++; char singlelinebuffer[300]; singlelinebuffer[0] = 0; char* singlelinebufferpos = singlelinebuffer; // word wrap if width of text is not 0. if( size.x != 0 ) { float linewidth = -1;// = GetStringSize( fontheight, Vector2(0,0), singlelinebuffer ).x; while( linewidth < size.x && *stringpos != 0 ) { *singlelinebufferpos = *stringpos; singlelinebufferpos++; *singlelinebufferpos = 0; stringpos++; linewidth = GetStringSize( fontheight, Vector2(0,0), singlelinebuffer ).x; assert( singlelinebufferpos < singlelinebuffer + 300 ); } int numcharswewentback = 0; while( ( *(singlelinebufferpos-1) != ' ' && *stringpos != 0 ) && singlelinebufferpos > singlelinebuffer ) { singlelinebufferpos--; numcharswewentback++; } if( singlelinebufferpos != singlelinebuffer ) { *singlelinebufferpos = 0; stringpos -= numcharswewentback; } if( *stringpos == 0 ) moretexttocome = false; stringtodraw = singlelinebuffer; } else { moretexttocome = false; } //// don't bother drawing if fontheight is zero... still doing logic above so the currect number of lines will be returned. //if( g_pRTQGlobals->m_WordWrapCountLinesOnly ) // continue; Vertex_XYZUV_RGBA* pVertsToDraw = (Vertex_XYZUV_RGBA*)GetVerts( true ); int newverts = (int)strlen( stringtodraw ) * 4; #if _DEBUG m_MostLettersAttemptedToDrawThisFrame += newverts/4; if( m_MostLettersAttemptedToDrawThisFrame > m_MostLettersAttemptedToDrawEver ) m_MostLettersAttemptedToDrawEver = m_MostLettersAttemptedToDrawThisFrame; #endif if( m_NumVertsToDraw + newverts > GetNumVerts() ) { #if _DEBUG LOGInfo( LOGTag, "TextMesh buffer isn't big enough for string (%s) - %d of %d letters used - most letters needed (%d)\n", stringtodraw, m_NumVertsToDraw/4, GetNumVerts()/4, m_MostLettersAttemptedToDrawEver ); #endif //assert( false ); // drawing more than we have room for. return 0; } pVertsToDraw += m_NumVertsToDraw; unsigned int textstrlen = m_pFont->m_pFont->GenerateVerts( stringtodraw, true, pVertsToDraw, fontheight, GL_TRIANGLES, justificationflags, color ); m_NumVertsToDraw += (unsigned short)(textstrlen * 4); m_NumIndicesToDraw += textstrlen * 6; MyMatrix position; position.SetIdentity(); position.Rotate( rotz, 0, 0, 1 ); position.SetPosition( x, y - (numlines-1)*fontheight, z ); //position.SetPosition( x, y - (numlines-1)*g_pRTQGlobals->m_WordWrapLineIncSize, z ); //position.SetPosition( x, y, z ); for( unsigned int i=0; i<textstrlen*4; i++ ) { Vector3 out = position.TransformVector3( *(Vector3*)&pVertsToDraw[i].x ); pVertsToDraw[i].x = out.x; pVertsToDraw[i].y = out.y; pVertsToDraw[i].z = out.z; } } return numlines; }
/* * Get the metadata size information for a program item, * both on-disk and in-memory. */ static void GetMetadataSize(ILSizeInfo *info, ILProgramItem *item) { ILImage *image = ILProgramItem_Image(item); if(!item) { return; } info->meta += image->tokenSize[ILProgramItem_Token(item) >> 24]; switch(ILProgramItem_Token(item) & IL_META_TOKEN_MASK) { case IL_META_TOKEN_MODULE: GetStringSize(info, ILModule_Name((ILModule *)item)); info->meta += 16; /* GUID size */ info->loadedMeta += sizeof(ILModule); break; case IL_META_TOKEN_MODULE_REF: GetStringSize(info, ILModule_Name((ILModule *)item)); info->loadedMeta += sizeof(ILModule); break; case IL_META_TOKEN_TYPE_REF: info->loadedMeta += sizeof(ILClass); info->loadedMeta += sizeof(ILProgramItemLink); GetClassNameSize(info, (ILClass *)item); break; case IL_META_TOKEN_TYPE_DEF: info->loadedMeta += sizeof(ILClass); GetClassNameSize(info, (ILClass *)item); break; case IL_META_TOKEN_FIELD_DEF: info->loadedMeta += sizeof(ILField); GetStringSize(info, ILMember_Name(item)); GetBlobSize(info, item, ((ILMember *)item)->signatureBlob); GetTypeSize(info, ILMember_Signature(item)); break; case IL_META_TOKEN_METHOD_DEF: info->loadedMeta += sizeof(ILMethod); GetStringSize(info, ILMember_Name(item)); GetBlobSize(info, item, ((ILMember *)item)->signatureBlob); GetTypeSize(info, ILMember_Signature(item)); break; case IL_META_TOKEN_PARAM_DEF: info->loadedMeta += sizeof(ILParameter); GetStringSize(info, ILParameter_Name((ILParameter *)item)); break; case IL_META_TOKEN_INTERFACE_IMPL: info->loadedMeta += sizeof(ILImplements); break; case IL_META_TOKEN_MEMBER_REF: if(ILMemberGetKind((ILMember *)item) == IL_META_MEMBERKIND_METHOD) { info->loadedMeta += sizeof(ILMethod); } else { info->loadedMeta += sizeof(ILField); } info->loadedMeta += sizeof(ILProgramItemLink); GetStringSize(info, ILMember_Name(item)); GetBlobSize(info, item, ((ILMember *)item)->signatureBlob); GetTypeSize(info, ILMember_Signature(item)); break; case IL_META_TOKEN_CONSTANT: info->loadedMeta += sizeof(ILConstant); GetBlobSize(info, item, ((ILConstant *)item)->value); break; case IL_META_TOKEN_CUSTOM_ATTRIBUTE: info->loadedMeta += sizeof(ILAttribute); GetBlobSize(info, item, ((ILAttribute *)item)->value); break; case IL_META_TOKEN_FIELD_MARSHAL: info->loadedMeta += sizeof(ILFieldMarshal); GetBlobSize(info, item, ((ILFieldMarshal *)item)->type); break; case IL_META_TOKEN_DECL_SECURITY: info->loadedMeta += sizeof(ILDeclSecurity); GetBlobSize(info, item, ((ILDeclSecurity *)item)->blob); break; case IL_META_TOKEN_CLASS_LAYOUT: info->loadedMeta += sizeof(ILClassLayout); break; case IL_META_TOKEN_FIELD_LAYOUT: info->loadedMeta += sizeof(ILFieldLayout); break; case IL_META_TOKEN_STAND_ALONE_SIG: info->loadedMeta += sizeof(ILStandAloneSig); GetBlobSize(info, item, ((ILStandAloneSig *)item)->typeBlob); GetTypeSize(info, ((ILStandAloneSig *)item)->type); break; case IL_META_TOKEN_EVENT_MAP: info->loadedMeta += sizeof(ILEventMap); break; case IL_META_TOKEN_EVENT: info->loadedMeta += sizeof(ILEvent); break; case IL_META_TOKEN_PROPERTY_MAP: info->loadedMeta += sizeof(ILPropertyMap); break; case IL_META_TOKEN_PROPERTY: info->loadedMeta += sizeof(ILProperty); break; case IL_META_TOKEN_METHOD_SEMANTICS: info->loadedMeta += sizeof(ILMethodSem); break; case IL_META_TOKEN_METHOD_IMPL: info->loadedMeta += sizeof(ILOverride); break; case IL_META_TOKEN_TYPE_SPEC: info->loadedMeta += sizeof(ILTypeSpec); GetBlobSize(info, item, ((ILTypeSpec *)item)->typeBlob); GetTypeSize(info, ((ILTypeSpec *)item)->type); break; case IL_META_TOKEN_IMPL_MAP: info->loadedMeta += sizeof(ILPInvoke); GetStringSize(info, ILPInvoke_Alias((ILPInvoke *)item)); break; case IL_META_TOKEN_FIELD_RVA: info->loadedMeta += sizeof(ILFieldRVA); break; case IL_META_TOKEN_ASSEMBLY: info->loadedMeta += sizeof(ILAssembly); GetStringSize(info, ILAssembly_Name((ILAssembly *)item)); GetStringSize(info, ILAssembly_Locale((ILAssembly *)item)); break; case IL_META_TOKEN_ASSEMBLY_REF: info->loadedMeta += sizeof(ILAssembly); info->loadedMeta += sizeof(ILProgramItemLink); GetStringSize(info, ILAssembly_Name((ILAssembly *)item)); GetStringSize(info, ILAssembly_Locale((ILAssembly *)item)); break; case IL_META_TOKEN_PROCESSOR_DEF: case IL_META_TOKEN_PROCESSOR_REF: info->loadedMeta += sizeof(ILProcessorInfo); break; case IL_META_TOKEN_OS_DEF: case IL_META_TOKEN_OS_REF: info->loadedMeta += sizeof(ILOSInfo); break; case IL_META_TOKEN_FILE: info->loadedMeta += sizeof(ILFileDecl); GetStringSize(info, ILFileDecl_Name((ILFileDecl *)item)); GetBlobSize(info, item, ((ILFileDecl *)item)->hash); break; case IL_META_TOKEN_EXPORTED_TYPE: info->loadedMeta += sizeof(ILExportedType); info->loadedMeta += sizeof(ILProgramItemLink); GetClassNameSize(info, (ILClass *)item); break; case IL_META_TOKEN_MANIFEST_RESOURCE: info->loadedMeta += sizeof(ILManifestRes); GetStringSize(info, ILManifestRes_Name((ILManifestRes *)item)); break; case IL_META_TOKEN_NESTED_CLASS: info->loadedMeta += sizeof(ILNestedInfo); break; case IL_META_TOKEN_GENERIC_PAR: info->loadedMeta += sizeof(ILGenericPar); GetStringSize(info, ILGenericPar_Name((ILGenericPar *)item)); break; case IL_META_TOKEN_METHOD_SPEC: info->loadedMeta += sizeof(ILMethodSpec); GetBlobSize(info, item, ((ILMethodSpec *)item)->typeBlob); GetTypeSize(info, ((ILMethodSpec *)item)->type); break; } }
// Chunk doesnt inlcude its tag and size size void CLwoWriter::BuildChunkLengths() { MSG_DEBUG("Building LWO chunks length..."); ulong tagsSize = 0; { // Surfaces CLwoFile::CLayer::SurfaceMap& surfaces = m_curLayer.GetSurfaceMap(); CLwoFile::CLayer::SurfaceMap::iterator surfaceIt, surfaceEnd; surfaceEnd = surfaces.end(); for(surfaceIt = surfaces.begin(); surfaceIt != surfaceEnd; ++surfaceIt) // For each part name tagsSize += GetStringSize(surfaceIt->first); // Parts CLwoFile::CLayer::PartVector& parts = m_curLayer.GetPartVector(); CLwoFile::CLayer::PartVector::iterator partIt, partEnd; partEnd = parts.end(); for(partIt = parts.begin(); partIt != partEnd; ++partIt) // For each part name tagsSize += GetStringSize(*partIt); // Smoothing groups CLwoFile::CLayer::SGVector& sgs = m_curLayer.GetSGVector(); tagsSize += sgs.size() * GetStringSize("sgXX"); } ulong vertexPosCount = m_curLayer.GetVertexPositionVector().size(); ulong vmapTexCount = 0; ulong vmadTexCount = 0; { CLwoFile::CLayer::TexCoordMap& texCoords = m_curLayer.GetTexCoordMap(); CLwoFile::CLayer::TexCoordMap::iterator texCoordIt, texCoordEnd; texCoordEnd = texCoords.end(); std::vector< CLwoFile::CLayer::CTexCoord > texCoordVector; for(texCoordIt = texCoords.begin(); texCoordIt != texCoordEnd; ++texCoordIt) // For each LWO texCoord { texCoordVector = texCoordIt->second; std::vector< CLwoFile::CLayer::CTexCoord >::iterator texCoordVectorIt, texCoordVectorEnd; texCoordVectorEnd = texCoordVector.end(); for(texCoordVectorIt = texCoordVector.begin(); texCoordVectorIt != texCoordVectorEnd; ++texCoordVectorIt) // For each LWO face { if(texCoordVectorIt == texCoordVector.begin()) // skip the first one since its in the VMAP { ++vmapTexCount; continue; } ++vmadTexCount; } } } // Indexed vertices count ulong faceCount = 0; ulong vertexPolyCount = 0; { CLwoFile::CLayer::FaceVector& faces = m_curLayer.GetFaceVector(); faceCount = faces.size(); CLwoFile::CLayer::FaceVector::iterator faceIt, faceBegin, faceEnd; faceBegin = faces.begin(); faceEnd = faces.end(); for(faceIt = faceBegin; faceIt != faceEnd; ++faceIt) // for each LWO point vertexPolyCount += faceIt->VertexCount(); } //Images ulong imageCount = 0; ulong imagesSize = 0; { CLwoFile::CLayer::ImageVector& images = m_curLayer.GetImageVector(); imageCount = images.size(); CLwoFile::CLayer::ImageVector::iterator imageIt, imageEnd; imageEnd = images.end(); imageIt = images.begin(); // first image only for(imageIt = images.begin(); imageIt != imageEnd; ++imageIt) // for each LWO image { imagesSize += 4; // index of the image imagesSize += 6; // "STIL" + size of still imagesSize += GetStringSize(*imageIt); // size of path } } // TAGS (every surface names + part names + sg names) m_chunkLengthMap[CLwoFile::CHUNK_TAGS] = tagsSize; // LAYR m_chunkLengthMap[CLwoFile::CHUNK_LAYR] = 18; // blank layer // PNTS m_chunkLengthMap[CLwoFile::CHUNK_PNTS] = vertexPosCount * 12; // number of vertex in this mesh * 12 // VMAP | TXUV m_chunkLengthMap[CLwoFile::CHUNK_VMAP] = 4 + 2 + 8 + vmapTexCount * (2+8); // "TXUV" + dimension(short) + "txuv00\0\0" + vertexPos*(vIndex+UV) // VMAD | TXUV m_chunkLengthMap[CLwoFile::CHUNK_VMAD] = 4 + 2 + 8 + vmadTexCount * (2+2+8); // "TXUV" + dimension(short) + "txuv00\0\0" + texCoordCount*(pointIndex+polyIndex+UV) // POLS m_chunkLengthMap[CLwoFile::CHUNK_POLS] = 4 + vertexPolyCount * 2 + faceCount * 2; // "FACE" + for each face : vertex Number(short) + index per vertex(short) // PTAG m_chunkLengthMap[CLwoFile::CHUNK_PTAG] = 4 + faceCount * 4; // "SURF" or "PART" or "SMGP" + face number * 4 // CLIP m_chunkLengthMap[CLwoFile::CHUNK_CLIP] = imagesSize; // "STIL" sub-chunk // SURF constant sub-chunks { m_chunkLengthMap[CLwoFile::CHUNK_BLOK] = (6+50) + (6+104) + (92); // IMAP + TMAP + rest = 244 m_chunkLengthMap[CLwoFile::CHUNK_COLR] = 14; m_chunkLengthMap[CLwoFile::CHUNK_DIFF] = 6; } // Surfaces ulong surfacesSize = 0; CLwoFile::CLayer::SurfaceMap& surfaces = m_curLayer.GetSurfaceMap(); ulong surfaceCount = surfaces.size(); CLwoFile::CLayer::SurfaceMap::iterator surfaceIt, surfaceEnd; surfaceEnd = surfaces.end(); for(surfaceIt = surfaces.begin(); surfaceIt != surfaceEnd; ++surfaceIt) // For each surface { std::string surfaceName(surfaceIt->first); CLwoFile::CLayer::CSurface& surface = surfaceIt->second; bool bHasTex = (surface.m_imageIndex != -1); m_chunkLengthMap[CLwoFile::CHUNK_SURF] = GetStringSize(surfaceName) + 2 + // surface name + parent name "\0\0" (bHasTex ? (6 + m_chunkLengthMap[CLwoFile::CHUNK_BLOK]):0) + (6 + m_chunkLengthMap[CLwoFile::CHUNK_COLR]) + (6 + m_chunkLengthMap[CLwoFile::CHUNK_DIFF]); surface.m_size = m_chunkLengthMap[CLwoFile::CHUNK_SURF]; surfacesSize += m_chunkLengthMap[CLwoFile::CHUNK_SURF]; } // FORM m_chunkLengthMap[CLwoFile::CHUNK_FORM] = (4) + // LWO2 (8 + m_chunkLengthMap[CLwoFile::CHUNK_TAGS]) + // "TAGS" + size + chunk... (8 + m_chunkLengthMap[CLwoFile::CHUNK_LAYR]) + // "LAYR" (8 + m_chunkLengthMap[CLwoFile::CHUNK_PNTS]) + // "PNTS" (vmapTexCount > 0 ? (8 + m_chunkLengthMap[CLwoFile::CHUNK_VMAP]):0) + // "VMAP" (vmapTexCount > 0 ? (8 + m_chunkLengthMap[CLwoFile::CHUNK_VMAD]):0) + // "VMAD" // If VMAP, sure to have VMAD! (8 + m_chunkLengthMap[CLwoFile::CHUNK_POLS]) + // "POLS" (8 + m_chunkLengthMap[CLwoFile::CHUNK_PTAG]) + // ("PTAG" + size) + "SURF" + data (8 + m_chunkLengthMap[CLwoFile::CHUNK_PTAG]) + // "PART" (8 + m_chunkLengthMap[CLwoFile::CHUNK_PTAG]) + // "SMGP" imageCount*8 + m_chunkLengthMap[CLwoFile::CHUNK_CLIP] + // "CLIP" surfaceCount*8 + surfacesSize; // "SURF" }
void UFont::GetStringHeightAndWidth( const FString& InString, int32& Height, int32& Width ) const { Height = GetStringHeightSize( *InString ); Width = GetStringSize( *InString ); }
void Font::SplitTextToStrings(const WideString & text, const Vector2 & targetRectSize, Vector<WideString> & resultVector) { int32 targetWidth = (int32)(targetRectSize.dx * Core::GetVirtualToPhysicalFactor()); enum { SKIP = 0, GOODCHAR, // all characters we like (symbols, special chars, except \n and space FINISH, // process last line EXIT, }; // Yuri Coder, 2013/12/10. Replace "\n" occurrences (two chars) to '\n' (one char) is done by Yaml parser, // so appropriate code (state NEXTLINE)is removed from here. See please MOBWOT-6499. SeparatorPositions separator; resultVector.clear(); int state = SKIP; int totalSize = (int)text.length(); Vector<float32> sizes; GetStringSize(text, &sizes); if(sizes.size() == 0) { return; } bool wasSeparator = false; for(int pos = 0; state != EXIT; pos++) { char16 t = 0; if(pos < totalSize) { t = text[pos]; } bool isSeparator = IsWordSeparator(t); switch (state) { case SKIP: if (t == 0){ state = FINISH; break; } // if end of string process FINISH state and exit else if (IsSpace(t))break; // if space continue with the same state else if(IsLineEnd(t)) { // this block is copied from case NEXTLINE: if(t == 'n') // unlike in NEXTLINE where we ignore 2 symbols, here we ignore only one // so last position is pos instead of (pos-1) if (separator.IsLineInitialized()) // if we already have something in current line we add to result { AddCurrentLine(text, pos, separator, resultVector); }else { resultVector.push_back(L""); // here we add empty line if there was no characters in current line } state = SKIP; //always switch to SKIP because we do not know here what will be next break; } else // everything else is good characters { state = GOODCHAR; separator.lastWordStart = pos; separator.lastWordEnd = pos; if (!separator.IsLineInitialized()) separator.currentLineStart = pos; } break; case GOODCHAR: { if(IsSpace(t) || IsLineEnd(t) || t == 0 || (wasSeparator && !isSeparator)) // if we've found any possible separator process current line { //calculate current line width float32 currentLineWidth = 0; int32 startPos = (separator.IsLineInitialized()) ? separator.currentLineStart : 0; for (int i = startPos; i < pos ; i++) { currentLineWidth += sizes[i]; } if((currentLineWidth < targetWidth) || ((IsSpace(t) || isSeparator) && 0 == targetWidth)) { // pos could be the end of line. We need to save it if(IsLineEnd(t) || t == 0) { AddCurrentLine(text, pos, separator, resultVector); } else { separator.currentLineEnd = pos; separator.lastWordEnd = pos; } } else if(currentLineWidth == targetWidth) { // line fit all available space DVASSERT(pos > separator.currentLineStart); AddCurrentLine(text, pos, separator, resultVector); } else { //currentLineWidth > targetWidth int32 currentLineLength = separator.currentLineEnd - separator.currentLineStart; if((currentLineLength > 0)) { // use previous position of separator to split text pos = separator.currentLineEnd; AddCurrentLine(text, pos, separator, resultVector); t = 0; if(pos + 1 < totalSize) { t = text[pos + 1]; } if(IsSpace(t) || IsLineEnd(t) || t == 0) { state = SKIP; } else { state = GOODCHAR; separator.lastWordStart = pos; separator.lastWordEnd = pos; if (!separator.IsLineInitialized()) separator.currentLineStart = pos; } break; } else if(pos) { // truncate text by symbol for very long word if(0 == targetWidth) { AddCurrentLine(text, pos, separator, resultVector); } else { int32 endPos = (separator.IsLineInitialized()) ? separator.currentLineStart : 0; for (int i = pos-1; i >= endPos; --i) { currentLineWidth -= sizes[i]; if(currentLineWidth <= targetWidth) { separator.currentLineEnd = i; int32 currentLineLength = separator.currentLineEnd - separator.currentLineStart; if((currentLineLength > 0)) // use previous position of separator to split text { pos = separator.currentLineEnd-1; AddCurrentLine(text, separator.currentLineEnd, separator, resultVector); } break; } DVASSERT(i); } } state = SKIP; break; } else { DVASSERT(0); } } } if (IsSpace(t) || IsLineEnd(t)) state = SKIP; // if cur char is space go to skip else if (t == 0) state = FINISH; else if(wasSeparator && !isSeparator) { // good char after separator separator.lastWordStart = pos; separator.lastWordEnd = pos; if (!separator.IsLineInitialized()) separator.currentLineStart = pos; } } break; case FINISH: if (separator.IsLineInitialized()) // we check if we have something left in currentline and add this line to results { DVASSERT(separator.currentLineEnd > separator.currentLineStart); AddCurrentLine(text, separator.currentLineEnd, separator, resultVector); } state = EXIT; // always exit from here break; }; wasSeparator = isSeparator; }; }
void Font::SplitTextBySymbolsToStrings(const WideString & text, const Vector2 & targetRectSize, Vector<WideString> & resultVector) { int32 targetWidth = (int32)(targetRectSize.dx * Core::GetVirtualToPhysicalFactor()); int32 totalSize = (int)text.length(); int32 currentLineStart = 0; int32 currentLineEnd = 0; int32 currentLineDx = 0; resultVector.clear(); Vector<float32> sizes; GetStringSize(text, &sizes); if(sizes.size() == 0) { return; } for(int pos = 0; pos < totalSize; pos++) { char16 t = text[pos]; char16 tNext = 0; if(pos+1 < totalSize) tNext = text[pos+1]; currentLineEnd = pos; if(t == '\n') { WideString currentLine = text.substr(currentLineStart, currentLineEnd - currentLineStart); resultVector.push_back(currentLine); currentLineStart = pos + 1; currentLineDx = 0; } if(t == '\\' && tNext == 'n') { WideString currentLine = text.substr(currentLineStart, currentLineEnd - currentLineStart); resultVector.push_back(currentLine); currentLineStart = pos + 2; currentLineDx = 0; } // Use additional condition to prevent endless loop, when target size is less than // size of one symbol (sizes[pos] > targetWidth) // To keep initial index logic we should always perform action currentLineDx += sizes[pos] // before entering this condition, so currentLineDx > 0. if((currentLineDx > 0) && (currentLineDx + sizes[pos] > targetWidth)) { WideString currentLine = text.substr(currentLineStart, currentLineEnd - currentLineStart); resultVector.push_back(currentLine); currentLineStart = pos; currentLineDx = 0; pos--; } else { currentLineDx += (int32)sizes[pos]; } } WideString currentLine = text.substr(currentLineStart, currentLineEnd - currentLineStart + 1); resultVector.push_back(currentLine); }