void CPDF_TextObject::CalcCharPos(FX_FLOAT* pPosArray) const { CPDF_Font* pFont = m_TextState.GetFont(); FX_BOOL bVertWriting = FALSE; CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); if (pCIDFont) { bVertWriting = pCIDFont->IsVertWriting(); } FX_FLOAT fontsize = m_TextState.GetFontSize(); for (int i = 0, index = 0; i < m_nChars; ++i) { FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; if (charcode == (FX_DWORD) - 1) { continue; } pPosArray[index++] = i ? m_pCharPos[i - 1] : 0; FX_FLOAT charwidth; if (bVertWriting) { FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; } else { charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000; } pPosArray[index] = pPosArray[index - 1] + charwidth; index++; } }
FX_FLOAT CPDF_TextObject::GetCharWidth(FX_DWORD charcode) const { FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; CPDF_Font* pFont = m_TextState.GetFont(); FX_BOOL bVertWriting = FALSE; CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); if (pCIDFont) { bVertWriting = pCIDFont->IsVertWriting(); } if (!bVertWriting) return pFont->GetCharWidthF(charcode, 0) * fontsize; FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); return pCIDFont->GetVertWidth(CID) * fontsize; }
FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const { CPDF_Font* pFont = m_TextState.GetFont(); FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32); if (charCode != (FX_DWORD)-1) { return GetCharWidth(charCode); } FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f; FX_BOOL bVertWriting = FALSE; CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); if (pCIDFont) { bVertWriting = pCIDFont->IsVertWriting(); } FX_RECT fontRect; pFont->GetFontBBox(fontRect); fontSize *= bVertWriting ? (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width(); return fontSize; }
void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const { CPDF_Font* pFont = m_TextState.GetFont(); FX_BOOL bVertWriting = FALSE; CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); if (pCIDFont) { bVertWriting = pCIDFont->IsVertWriting(); } FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; int count = 0; for (int i = 0; i < m_nChars; ++i) { FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; if (charcode == (FX_DWORD) - 1) { continue; } if (count != index) { ++count; continue; } FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0; FX_RECT char_rect; pFont->GetCharBBox(charcode, char_rect, 0); if (!bVertWriting) { rect.left = curpos + char_rect.left * fontsize; rect.right = curpos + char_rect.right * fontsize; rect.top = char_rect.top * fontsize; rect.bottom = char_rect.bottom * fontsize; } else { FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); short vx, vy; pCIDFont->GetVertOrigin(CID, vx, vy); char_rect.left -= vx; char_rect.right -= vx; char_rect.top -= vy; char_rect.bottom -= vy; rect.left = char_rect.left * fontsize; rect.right = char_rect.right * fontsize; rect.top = curpos + char_rect.top * fontsize; rect.bottom = curpos + char_rect.bottom * fontsize; } return; } }
void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, FX_FLOAT* pTextAdvanceY, FX_FLOAT horz_scale, int level) { FX_FLOAT curpos = 0; FX_FLOAT min_x = 10000 * 1.0f; FX_FLOAT max_x = -10000 * 1.0f; FX_FLOAT min_y = 10000 * 1.0f; FX_FLOAT max_y = -10000 * 1.0f; CPDF_Font* pFont = m_TextState.GetFont(); FX_BOOL bVertWriting = FALSE; CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); if (pCIDFont) { bVertWriting = pCIDFont->IsVertWriting(); } FX_FLOAT fontsize = m_TextState.GetFontSize(); for (int i = 0; i < m_nChars; ++i) { FX_DWORD charcode = m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; if (charcode == (FX_DWORD) - 1) { curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000; continue; } if (i) { m_pCharPos[i - 1] = curpos; } FX_RECT char_rect; pFont->GetCharBBox(charcode, char_rect, level); FX_FLOAT charwidth; if (!bVertWriting) { if (min_y > char_rect.top) { min_y = (FX_FLOAT)char_rect.top; } if (max_y < char_rect.top) { max_y = (FX_FLOAT)char_rect.top; } if (min_y > char_rect.bottom) { min_y = (FX_FLOAT)char_rect.bottom; } if (max_y < char_rect.bottom) { max_y = (FX_FLOAT)char_rect.bottom; } FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000; FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000; if (min_x > char_left) { min_x = char_left; } if (max_x < char_left) { max_x = char_left; } if (min_x > char_right) { min_x = char_right; } if (max_x < char_right) { max_x = char_right; } charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000; } else { FX_WORD CID = pCIDFont->CIDFromCharCode(charcode); short vx; short vy; pCIDFont->GetVertOrigin(CID, vx, vy); char_rect.left -= vx; char_rect.right -= vx; char_rect.top -= vy; char_rect.bottom -= vy; if (min_x > char_rect.left) { min_x = (FX_FLOAT)char_rect.left; } if (max_x < char_rect.left) { max_x = (FX_FLOAT)char_rect.left; } if (min_x > char_rect.right) { min_x = (FX_FLOAT)char_rect.right; } if (max_x < char_rect.right) { max_x = (FX_FLOAT)char_rect.right; } FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000; FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000; if (min_y > char_top) { min_y = char_top; } if (max_y < char_top) { max_y = char_top; } if (min_y > char_bottom) { min_y = char_bottom; } if (max_y < char_bottom) { max_y = char_bottom; } charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; } curpos += charwidth; if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) { curpos += m_TextState.GetObject()->m_WordSpace; } curpos += m_TextState.GetObject()->m_CharSpace; } if (bVertWriting) { if (pTextAdvanceX) { *pTextAdvanceX = 0; } if (pTextAdvanceY) { *pTextAdvanceY = curpos; } min_x = min_x * fontsize / 1000; max_x = max_x * fontsize / 1000; } else { if (pTextAdvanceX) { *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale); } if (pTextAdvanceY) { *pTextAdvanceY = 0; } min_y = min_y * fontsize / 1000; max_y = max_y * fontsize / 1000; } CFX_AffineMatrix matrix; GetTextMatrix(&matrix); m_Left = min_x; m_Right = max_x; m_Bottom = min_y; m_Top = max_y; matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); int textmode = m_TextState.GetObject()->m_TextMode; if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) { FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2; m_Left -= half_width; m_Right += half_width; m_Top += half_width; m_Bottom -= half_width; } }