// Draw text using SpriteFont // NOTE: chars spacing is NOT proportional to fontSize void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float fontSize, int spacing, Color tint) { int length = strlen(text); int textOffsetX = 0; // Offset between characters int textOffsetY = 0; // Required for line break! float scaleFactor; unsigned char letter; // Current character int index; // Index position in sprite font scaleFactor = fontSize/spriteFont.size; // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly // written in C code files (codified by default as UTF-8) for (int i = 0; i < length; i++) { if ((unsigned char)text[i] == '\n') { // NOTE: Fixed line spacing of 1.5 lines textOffsetY += ((spriteFont.size + spriteFont.size/2)*scaleFactor); textOffsetX = 0; } else { if ((unsigned char)text[i] == 0xc2) // UTF-8 encoding identification HACK! { // Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿) letter = (unsigned char)text[i + 1]; index = GetCharIndex(spriteFont, (int)letter); i++; } else if ((unsigned char)text[i] == 0xc3) // UTF-8 encoding identification HACK! { // Support UTF-8 encoded values from [0xc3 0x80](À) -> [0xc3 0xbf](ÿ) letter = (unsigned char)text[i + 1]; index = GetCharIndex(spriteFont, (int)letter + 64); i++; } else index = GetCharIndex(spriteFont, (int)text[i]); DrawTexturePro(spriteFont.texture, spriteFont.charRecs[index], (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[index].x*scaleFactor, position.y + textOffsetY + spriteFont.charOffsets[index].y*scaleFactor, spriteFont.charRecs[index].width*scaleFactor, spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (spriteFont.charRecs[index].width*scaleFactor + spacing); else textOffsetX += (spriteFont.charAdvanceX[index]*scaleFactor + spacing); } } }
int GetStringXSize(CFont* font, const CString* string) { int str_length = CString_GetSize(string); int total_x = 0; for (int i = 0; i < str_length; i++) { total_x += font->char_data[GetCharIndex(font, string->data[i])].x_next; } return total_x; }
int32_t CFDE_TxtEdtPage::SelectWord(const CFX_PointF& fPoint, int32_t& nCount) { if (m_nRefCount < 0) { return -1; } CFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf(); FX_BOOL bBefore; int32_t nIndex = GetCharIndex(fPoint, bBefore); if (nIndex == m_pEditEngine->GetTextBufLength()) { nIndex = m_pEditEngine->GetTextBufLength() - 1; } if (nIndex < 0) { return -1; } std::unique_ptr<CFX_WordBreak> pIter(new CFX_WordBreak); pIter->Attach(new CFDE_TxtEdtBufIter(pBuf)); pIter->SetAt(nIndex); nCount = pIter->GetWordLength(); return pIter->GetWordPos(); }
// Measure string size for SpriteFont Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing) { int len = strlen(text); int tempLen = 0; // Used to count longer text line num chars int lenCounter = 0; int textWidth = 0; int tempTextWidth = 0; // Used to count longer text line width int textHeight = spriteFont.size; float scaleFactor = fontSize/spriteFont.size; for (int i = 0; i < len; i++) { lenCounter++; if (text[i] != '\n') { int index = GetCharIndex(spriteFont, (int)text[i]); if (spriteFont.charAdvanceX[index] != 0) textWidth += spriteFont.charAdvanceX[index]; else textWidth += (spriteFont.charRecs[index].width + spriteFont.charOffsets[index].x); } else { if (tempTextWidth < textWidth) tempTextWidth = textWidth; lenCounter = 0; textWidth = 0; textHeight += (spriteFont.size + spriteFont.size/2); // NOTE: Fixed line spacing of 1.5 lines } if (tempLen < lenCounter) tempLen = lenCounter; } if (tempTextWidth < textWidth) tempTextWidth = textWidth; Vector2 vec; vec.x = (float)tempTextWidth*scaleFactor + (tempLen - 1)*spacing; // Adds chars spacing to measure vec.y = (float)textHeight*scaleFactor; return vec; }
int CPDF_TextPageFind::GetMatchedCount() const { int resStart = GetCharIndex(m_resStart); int resEnd = GetCharIndex(m_resEnd); return resEnd - resStart + 1; }
int CPDF_TextPageFind::GetCurOrder() const { return GetCharIndex(m_resStart); }
FX_BOOL CPDF_TextPageFind::FindNext() { if (!m_pTextPage) return FALSE; m_resArray.clear(); if (m_findNextStart == -1) return FALSE; if (m_strText.IsEmpty()) { m_IsFind = FALSE; return m_IsFind; } int strLen = m_strText.GetLength(); if (m_findNextStart > strLen - 1) { m_IsFind = FALSE; return m_IsFind; } int nCount = pdfium::CollectionSize<int>(m_csFindWhatArray); int nResultPos = 0; int nStartPos = 0; nStartPos = m_findNextStart; bool bSpaceStart = false; for (int iWord = 0; iWord < nCount; iWord++) { CFX_WideString csWord = m_csFindWhatArray[iWord]; if (csWord.IsEmpty()) { if (iWord == nCount - 1) { FX_WCHAR strInsert = m_strText.GetAt(nStartPos); if (strInsert == TEXT_LINEFEED_CHAR || strInsert == TEXT_SPACE_CHAR || strInsert == TEXT_RETURN_CHAR || strInsert == 160) { nResultPos = nStartPos + 1; break; } iWord = -1; } else if (iWord == 0) { bSpaceStart = true; } continue; } int endIndex; nResultPos = m_strText.Find(csWord.c_str(), nStartPos); if (nResultPos == -1) { m_IsFind = FALSE; return m_IsFind; } endIndex = nResultPos + csWord.GetLength() - 1; if (iWord == 0) m_resStart = nResultPos; FX_BOOL bMatch = TRUE; if (iWord != 0 && !bSpaceStart) { int PreResEndPos = nStartPos; int curChar = csWord.GetAt(0); CFX_WideString lastWord = m_csFindWhatArray[iWord - 1]; int lastChar = lastWord.GetAt(lastWord.GetLength() - 1); if (nStartPos == nResultPos && !(IsIgnoreSpaceCharacter(lastChar) || IsIgnoreSpaceCharacter(curChar))) { bMatch = FALSE; } for (int d = PreResEndPos; d < nResultPos; d++) { FX_WCHAR strInsert = m_strText.GetAt(d); if (strInsert != TEXT_LINEFEED_CHAR && strInsert != TEXT_SPACE_CHAR && strInsert != TEXT_RETURN_CHAR && strInsert != 160) { bMatch = FALSE; break; } } } else if (bSpaceStart) { if (nResultPos > 0) { FX_WCHAR strInsert = m_strText.GetAt(nResultPos - 1); if (strInsert != TEXT_LINEFEED_CHAR && strInsert != TEXT_SPACE_CHAR && strInsert != TEXT_RETURN_CHAR && strInsert != 160) { bMatch = FALSE; m_resStart = nResultPos; } else { m_resStart = nResultPos - 1; } } } if (m_bMatchWholeWord && bMatch) { bMatch = IsMatchWholeWord(m_strText, nResultPos, endIndex); } nStartPos = endIndex + 1; if (!bMatch) { iWord = -1; if (bSpaceStart) nStartPos = m_resStart + m_csFindWhatArray[1].GetLength(); else nStartPos = m_resStart + m_csFindWhatArray[0].GetLength(); } } m_resEnd = nResultPos + m_csFindWhatArray.back().GetLength() - 1; m_IsFind = TRUE; int resStart = GetCharIndex(m_resStart); int resEnd = GetCharIndex(m_resEnd); m_resArray = m_pTextPage->GetRectArray(resStart, resEnd - resStart + 1); if (m_flags & FPDFTEXT_CONSECUTIVE) { m_findNextStart = m_resStart + 1; m_findPreStart = m_resEnd - 1; } else { m_findNextStart = m_resEnd + 1; m_findPreStart = m_resStart - 1; } return m_IsFind; }