1// Copyright 2016 PDFium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7#include "core/fpdfapi/render/cpdf_charposlist.h" 8 9#include "core/fpdfapi/font/cpdf_cidfont.h" 10#include "core/fpdfapi/font/cpdf_font.h" 11 12CPDF_CharPosList::CPDF_CharPosList() { 13 m_pCharPos = nullptr; 14 m_nChars = 0; 15} 16 17CPDF_CharPosList::~CPDF_CharPosList() { 18 FX_Free(m_pCharPos); 19} 20 21void CPDF_CharPosList::Load(const std::vector<uint32_t>& charCodes, 22 const std::vector<float>& charPos, 23 CPDF_Font* pFont, 24 float FontSize) { 25 m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, charCodes.size()); 26 m_nChars = 0; 27 CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); 28 bool bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); 29 for (size_t iChar = 0; iChar < charCodes.size(); ++iChar) { 30 uint32_t CharCode = charCodes[iChar]; 31 if (CharCode == static_cast<uint32_t>(-1)) 32 continue; 33 34 bool bVert = false; 35 FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; 36 if (pCIDFont) 37 charpos.m_bFontStyle = true; 38 WideString unicode = pFont->UnicodeFromCharCode(CharCode); 39 charpos.m_Unicode = !unicode.IsEmpty() ? unicode[0] : CharCode; 40 charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); 41 uint32_t GlyphID = charpos.m_GlyphIndex; 42#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ 43 charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); 44 GlyphID = charpos.m_ExtGID; 45#endif 46 CFX_Font* pCurrentFont; 47 if (GlyphID != static_cast<uint32_t>(-1)) { 48 charpos.m_FallbackFontPosition = -1; 49 pCurrentFont = pFont->GetFont(); 50 } else { 51 charpos.m_FallbackFontPosition = 52 pFont->FallbackFontFromCharcode(CharCode); 53 charpos.m_GlyphIndex = pFont->FallbackGlyphFromCharcode( 54 charpos.m_FallbackFontPosition, CharCode); 55 pCurrentFont = pFont->GetFontFallback(charpos.m_FallbackFontPosition); 56#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ 57 charpos.m_ExtGID = charpos.m_GlyphIndex; 58#endif 59 } 60 61 if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) 62 charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); 63 else 64 charpos.m_FontCharWidth = 0; 65 66 charpos.m_Origin = CFX_PointF(iChar > 0 ? charPos[iChar - 1] : 0, 0); 67 charpos.m_bGlyphAdjust = false; 68 69 float scalingFactor = 1.0f; 70 if (!pFont->IsEmbedded() && pFont->HasFontWidths() && !bVertWriting && 71 !pCurrentFont->GetSubstFont()->m_bFlagMM) { 72 int pdfGlyphWidth = pFont->GetCharWidthF(CharCode); 73 int ftGlyphWidth = 74 pCurrentFont ? pCurrentFont->GetGlyphWidth(charpos.m_GlyphIndex) : 0; 75 if (ftGlyphWidth && pdfGlyphWidth > ftGlyphWidth + 1) { 76 // Move the initial x position by half of the excess (transformed to 77 // text space coordinates). 78 charpos.m_Origin.x += 79 (pdfGlyphWidth - ftGlyphWidth) * FontSize / 2000.0f; 80 } else if (pdfGlyphWidth && ftGlyphWidth && 81 pdfGlyphWidth < ftGlyphWidth) { 82 scalingFactor = static_cast<float>(pdfGlyphWidth) / ftGlyphWidth; 83 ASSERT(scalingFactor >= 0.0f); 84 charpos.m_AdjustMatrix[0] = scalingFactor; 85 charpos.m_AdjustMatrix[1] = 0.0f; 86 charpos.m_AdjustMatrix[2] = 0.0f; 87 charpos.m_AdjustMatrix[3] = 1.0f; 88 charpos.m_bGlyphAdjust = true; 89 } 90 } 91 if (!pCIDFont) 92 continue; 93 94 uint16_t CID = pCIDFont->CIDFromCharCode(CharCode); 95 if (bVertWriting) { 96 charpos.m_Origin = CFX_PointF(0, charpos.m_Origin.x); 97 98 short vx; 99 short vy; 100 pCIDFont->GetVertOrigin(CID, vx, vy); 101 charpos.m_Origin.x -= FontSize * vx / 1000; 102 charpos.m_Origin.y -= FontSize * vy / 1000; 103 } 104 105 const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID); 106 if (pTransform && !bVert) { 107 charpos.m_AdjustMatrix[0] = 108 pCIDFont->CIDTransformToFloat(pTransform[0]) * scalingFactor; 109 charpos.m_AdjustMatrix[1] = 110 pCIDFont->CIDTransformToFloat(pTransform[1]) * scalingFactor; 111 charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]); 112 charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]); 113 charpos.m_Origin.x += 114 pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize; 115 charpos.m_Origin.y += 116 pCIDFont->CIDTransformToFloat(pTransform[5]) * FontSize; 117 charpos.m_bGlyphAdjust = true; 118 } 119 } 120} 121