void CPDF_CharPosList::Load(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, FX_FLOAT FontSize) { m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars); m_nChars = 0; CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); FX_BOOL bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); for (int iChar = 0; iChar < nChars; iChar++) { FX_DWORD CharCode = nChars == 1 ? (FX_DWORD)(uintptr_t)pCharCodes : pCharCodes[iChar]; if (CharCode == (FX_DWORD)-1) { continue; } FX_BOOL bVert = FALSE; FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; if (pCIDFont) { charpos.m_bFontStyle = pCIDFont->IsFontStyleFromCharCode(CharCode); } charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); #endif if (!pFont->IsEmbedded() && pFont->GetFontType() != PDFFONT_CIDFONT) { charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); } else { charpos.m_FontCharWidth = 0; } charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; charpos.m_OriginY = 0; charpos.m_bGlyphAdjust = FALSE; if (pCIDFont == NULL) { continue; } FX_WORD CID = pCIDFont->CIDFromCharCode(CharCode); if (bVertWriting) { charpos.m_OriginY = charpos.m_OriginX; charpos.m_OriginX = 0; short vx, vy; pCIDFont->GetVertOrigin(CID, vx, vy); charpos.m_OriginX -= FontSize * vx / 1000; charpos.m_OriginY -= FontSize * vy / 1000; } const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID); if (pTransform && !bVert) { charpos.m_AdjustMatrix[0] = pCIDFont->CIDTransformToFloat(pTransform[0]); charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]); charpos.m_AdjustMatrix[1] = pCIDFont->CIDTransformToFloat(pTransform[1]); charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]); charpos.m_OriginX += pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize; charpos.m_OriginY += pCIDFont->CIDTransformToFloat(pTransform[5]) * FontSize; charpos.m_bGlyphAdjust = TRUE; } } }
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_CharPosList::Load(const std::vector<uint32_t>& charCodes, const std::vector<FX_FLOAT>& charPos, CPDF_Font* pFont, FX_FLOAT FontSize) { int nChars = pdfium::CollectionSize<int>(charCodes); m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars); m_nChars = 0; CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); bool bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); for (int iChar = 0; iChar < nChars; iChar++) { uint32_t CharCode = charCodes[iChar]; if (CharCode == static_cast<uint32_t>(-1)) continue; bool bVert = false; FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; if (pCIDFont) charpos.m_bFontStyle = true; charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); if (charpos.m_GlyphIndex != static_cast<uint32_t>(-1)) { charpos.m_FallbackFontPosition = -1; } else { charpos.m_FallbackFontPosition = pFont->FallbackFontFromCharcode(CharCode); charpos.m_GlyphIndex = pFont->FallbackGlyphFromCharcode( charpos.m_FallbackFontPosition, CharCode); } // TODO(npm): Figure out how this affects m_ExtGID #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); #endif if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); else charpos.m_FontCharWidth = 0; charpos.m_Origin = CFX_PointF(iChar ? charPos[iChar - 1] : 0, 0); charpos.m_bGlyphAdjust = false; if (!pCIDFont) continue; uint16_t CID = pCIDFont->CIDFromCharCode(CharCode); if (bVertWriting) { charpos.m_Origin = CFX_PointF(0, charpos.m_Origin.x); short vx; short vy; pCIDFont->GetVertOrigin(CID, vx, vy); charpos.m_Origin.x -= FontSize * vx / 1000; charpos.m_Origin.y -= FontSize * vy / 1000; } const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID); if (pTransform && !bVert) { charpos.m_AdjustMatrix[0] = pCIDFont->CIDTransformToFloat(pTransform[0]); charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]); charpos.m_AdjustMatrix[1] = pCIDFont->CIDTransformToFloat(pTransform[1]); charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]); charpos.m_Origin.x += pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize; charpos.m_Origin.y += pCIDFont->CIDTransformToFloat(pTransform[5]) * FontSize; charpos.m_bGlyphAdjust = true; } } }
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; } }