int CBFontTT::GetTextWidth(byte *Text, int MaxLength) { WideString text; if (Game->m_TextEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text); else text = StringUtil::AnsiToWide((char *)Text); if (MaxLength >= 0 && text.length() > MaxLength) text = text.substr(0, MaxLength); int textWidth, textHeight; MeasureText(text, -1, -1, textWidth, textHeight); return textWidth; }
void Font::AddCurrentLine(const WideString & text, const int32 pos, SeparatorPositions & separatorPosition, Vector<WideString> & resultVector) const { WideString currentLine = text.substr(separatorPosition.currentLineStart, pos - separatorPosition.currentLineStart); //Trim whitespace at begin/end line while(currentLine.size() > 1 && IsSpace(currentLine[0])) { currentLine.erase(currentLine.begin()); } while(currentLine.size() > 1 && IsSpace(currentLine[currentLine.size() - 1])) { currentLine.erase(currentLine.end() - 1); } resultVector.push_back(currentLine); separatorPosition.Reset(); }
//-------------------------------- bool Utils::createDirectoryRecursive( const WideString &pathString ) { if (pathString.length() == 0) return false; WideString path = pathString; if (path[path.length()-1] != '/' && path[path.length()-1] != '\\') path.push_back('\\'); std::list<WideString> paths; size_t offset = WideString::npos; while ((offset != 0) && (offset = pathString.find_last_of(L"/\\", offset)) != WideString::npos) { paths.push_front(pathString.substr(0, offset + 1)); if (offset != 0) --offset; } bool pathExists = true; const wchar_t* currentPath = _wgetcwd(0, 0); for (std::list<WideString>::const_iterator iPath = paths.begin(); iPath != paths.end(); ++iPath) { // if path exists if (_wchdir((*iPath).c_str()) == 0) continue; // path does not exist, try to create it _wmkdir((*iPath).c_str()); if (_wchdir((*iPath).c_str()) != 0) { pathExists = false; break; } } // Restore current path _wchdir(currentPath); return pathExists; }
void CBFontTT::DrawText(byte *Text, int X, int Y, int Width, TTextAlign Align, int MaxHeight, int MaxLength) { if (Text == NULL || strcmp((char *)Text, "") == 0) return; WideString text; if (Game->m_TextEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text); else text = StringUtil::AnsiToWide((char *)Text); if (MaxLength >= 0 && text.length() > MaxLength) text = text.substr(0, MaxLength); CBRenderSDL *m_Renderer = (CBRenderSDL *)Game->m_Renderer; // find cached surface, if exists int MinPriority = INT_MAX; int MinIndex = -1; CBSurface *Surface = NULL; int textOffset = 0; for (int i = 0; i < NUM_CACHED_TEXTS; i++) { if (m_CachedTexts[i] == NULL) { MinPriority = 0; MinIndex = i; } else { if (m_CachedTexts[i]->m_Text == text && m_CachedTexts[i]->m_Align == Align && m_CachedTexts[i]->m_Width == Width && m_CachedTexts[i]->m_MaxHeight == MaxHeight && m_CachedTexts[i]->m_MaxLength == MaxLength) { Surface = m_CachedTexts[i]->m_Surface; textOffset = m_CachedTexts[i]->m_TextOffset; m_CachedTexts[i]->m_Priority++; m_CachedTexts[i]->m_Marked = true; break; } else { if (m_CachedTexts[i]->m_Priority < MinPriority) { MinPriority = m_CachedTexts[i]->m_Priority; MinIndex = i; } } } } // not found, create one if (!Surface) { Surface = RenderTextToTexture(text, Width, Align, MaxHeight, textOffset); if (Surface) { // write surface to cache if (m_CachedTexts[MinIndex] != NULL) delete m_CachedTexts[MinIndex]; m_CachedTexts[MinIndex] = new CBCachedTTFontText; m_CachedTexts[MinIndex]->m_Surface = Surface; m_CachedTexts[MinIndex]->m_Align = Align; m_CachedTexts[MinIndex]->m_Width = Width; m_CachedTexts[MinIndex]->m_MaxHeight = MaxHeight; m_CachedTexts[MinIndex]->m_MaxLength = MaxLength; m_CachedTexts[MinIndex]->m_Priority = 1; m_CachedTexts[MinIndex]->m_Text = text; m_CachedTexts[MinIndex]->m_TextOffset = textOffset; m_CachedTexts[MinIndex]->m_Marked = true; } } // and paint it if (Surface) { RECT rc; CBPlatform::SetRect(&rc, 0, 0, Surface->GetWidth(), Surface->GetHeight()); for (int i = 0; i < m_Layers.GetSize(); i++) { uint32 Color = m_Layers[i]->m_Color; uint32 OrigForceAlpha = m_Renderer->m_ForceAlphaColor; if (m_Renderer->m_ForceAlphaColor != 0) { Color = DRGBA(D3DCOLGetR(Color), D3DCOLGetG(Color), D3DCOLGetB(Color), D3DCOLGetA(m_Renderer->m_ForceAlphaColor)); m_Renderer->m_ForceAlphaColor = 0; } Surface->DisplayTransOffset(X, Y - textOffset, rc, Color, BLEND_NORMAL, false, false, m_Layers[i]->m_OffsetX, m_Layers[i]->m_OffsetY); m_Renderer->m_ForceAlphaColor = OrigForceAlpha; } } }
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); }