| // Copyright 2016 PDFium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| #include "core/fpdfapi/render/cpdf_charposlist.h" | |
| #include "core/fpdfapi/font/cpdf_cidfont.h" | |
| #include "core/fpdfapi/font/cpdf_font.h" | |
| #include "core/fxge/cfx_renderdevice.h" | |
| #include "core/fxge/cfx_substfont.h" | |
| CPDF_CharPosList::CPDF_CharPosList(const std::vector<uint32_t>& charCodes, | |
| const std::vector<float>& charPos, | |
| CPDF_Font* pFont, | |
| float FontSize) { | |
| m_CharPos.reserve(charCodes.size()); | |
| CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); | |
| bool bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); | |
| for (size_t i = 0; i < charCodes.size(); ++i) { | |
| uint32_t CharCode = charCodes[i]; | |
| if (CharCode == static_cast<uint32_t>(-1)) | |
| continue; | |
| bool bVert = false; | |
| m_CharPos.emplace_back(); | |
| TextCharPos& charpos = m_CharPos.back(); | |
| if (pCIDFont) | |
| charpos.m_bFontStyle = true; | |
| WideString unicode = pFont->UnicodeFromCharCode(CharCode); | |
| charpos.m_Unicode = !unicode.IsEmpty() ? unicode[0] : CharCode; | |
| charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); | |
| uint32_t GlyphID = charpos.m_GlyphIndex; | |
| #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ | |
| charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); | |
| GlyphID = charpos.m_ExtGID != static_cast<uint32_t>(-1) | |
| ? charpos.m_ExtGID | |
| : charpos.m_GlyphIndex; | |
| #endif | |
| CFX_Font* pCurrentFont; | |
| if (GlyphID != static_cast<uint32_t>(-1)) { | |
| charpos.m_FallbackFontPosition = -1; | |
| pCurrentFont = pFont->GetFont(); | |
| } else { | |
| charpos.m_FallbackFontPosition = | |
| pFont->FallbackFontFromCharcode(CharCode); | |
| charpos.m_GlyphIndex = pFont->FallbackGlyphFromCharcode( | |
| charpos.m_FallbackFontPosition, CharCode); | |
| pCurrentFont = pFont->GetFontFallback(charpos.m_FallbackFontPosition); | |
| #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ | |
| charpos.m_ExtGID = charpos.m_GlyphIndex; | |
| #endif | |
| } | |
| if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) | |
| charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); | |
| else | |
| charpos.m_FontCharWidth = 0; | |
| charpos.m_Origin = CFX_PointF(i > 0 ? charPos[i - 1] : 0, 0); | |
| charpos.m_bGlyphAdjust = false; | |
| float scalingFactor = 1.0f; | |
| if (!pFont->IsEmbedded() && pFont->HasFontWidths() && !bVertWriting && | |
| !pCurrentFont->GetSubstFont()->m_bFlagMM) { | |
| uint32_t pdfGlyphWidth = pFont->GetCharWidthF(CharCode); | |
| uint32_t ftGlyphWidth = | |
| pCurrentFont ? pCurrentFont->GetGlyphWidth(charpos.m_GlyphIndex) : 0; | |
| if (ftGlyphWidth && pdfGlyphWidth > ftGlyphWidth + 1) { | |
| // Move the initial x position by half of the excess (transformed to | |
| // text space coordinates). | |
| charpos.m_Origin.x += | |
| (pdfGlyphWidth - ftGlyphWidth) * FontSize / 2000.0f; | |
| } else if (pdfGlyphWidth && ftGlyphWidth && | |
| pdfGlyphWidth < ftGlyphWidth) { | |
| scalingFactor = static_cast<float>(pdfGlyphWidth) / ftGlyphWidth; | |
| charpos.m_AdjustMatrix[0] = scalingFactor; | |
| charpos.m_AdjustMatrix[1] = 0.0f; | |
| charpos.m_AdjustMatrix[2] = 0.0f; | |
| charpos.m_AdjustMatrix[3] = 1.0f; | |
| charpos.m_bGlyphAdjust = true; | |
| } | |
| } | |
| 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]) * scalingFactor; | |
| charpos.m_AdjustMatrix[1] = | |
| pCIDFont->CIDTransformToFloat(pTransform[1]) * scalingFactor; | |
| charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]); | |
| 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; | |
| } | |
| } | |
| } | |
| CPDF_CharPosList::~CPDF_CharPosList() = default; | |
| uint32_t CPDF_CharPosList::GetCount() const { | |
| return pdfium::CollectionSize<uint32_t>(m_CharPos); | |
| } | |
| const TextCharPos& CPDF_CharPosList::GetAt(size_t index) const { | |
| return m_CharPos[index]; | |
| } |