14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Copyright 2016 PDFium Authors. All rights reserved. 24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be 34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// found in the LICENSE file. 44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/render/cpdf_type3cache.h" 84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <map> 104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <memory> 11d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <utility> 124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/font/cpdf_type3char.h" 144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/font/cpdf_type3font.h" 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/render/cpdf_type3glyphs.h" 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxge/fx_dib.h" 174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxge/fx_font.h" 18d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "third_party/base/ptr_util.h" 194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannnamespace { 214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstruct CPDF_UniqueKeyGen { 234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann void Generate(int count, ...); 24d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann char m_Key[128]; 254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int m_KeyLen; 264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CPDF_UniqueKeyGen::Generate(int count, ...) { 294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann va_list argList; 304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann va_start(argList, count); 314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = 0; i < count; i++) { 324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int p = va_arg(argList, int); 334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (reinterpret_cast<uint32_t*>(m_Key))[i] = p; 344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann va_end(argList); 364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_KeyLen = count * sizeof(uint32_t); 374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool IsScanLine1bpp(uint8_t* pBuf, int width) { 404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int size = width / 8; 414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = 0; i < size; i++) { 424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (pBuf[i]) 434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (width % 8) && (pBuf[width / 8] & (0xff << (8 - width % 8))); 464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool IsScanLine8bpp(uint8_t* pBuf, int width) { 494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = 0; i < width; i++) { 504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (pBuf[i] > 0x40) 514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return true; 524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return false; 544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 56d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannint DetectFirstLastScan(const RetainPtr<CFX_DIBitmap>& pBitmap, bool bFirst) { 574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int height = pBitmap->GetHeight(); 584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pitch = pBitmap->GetPitch(); 594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int width = pBitmap->GetWidth(); 604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bpp = pBitmap->GetBPP(); 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bpp > 8) 624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann width *= bpp / 8; 634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uint8_t* pBuf = pBitmap->GetBuffer(); 644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int line = bFirst ? 0 : height - 1; 654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int line_step = bFirst ? 1 : -1; 664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int line_end = bFirst ? height : -1; 674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (line != line_end) { 684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bpp == 1) { 694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (IsScanLine1bpp(pBuf + line * pitch, width)) 704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return line; 714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (IsScanLine8bpp(pBuf + line * pitch, width)) 734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return line; 744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann line += line_step; 764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return -1; 784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} // namespace 814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDF_Type3Cache::CPDF_Type3Cache(CPDF_Type3Font* pFont) : m_pFont(pFont) {} 834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 84d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCPDF_Type3Cache::~CPDF_Type3Cache() {} 854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(uint32_t charcode, 874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const CFX_Matrix* pMatrix, 88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float retinaScaleX, 89d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float retinaScaleY) { 904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDF_UniqueKeyGen keygen; 914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann keygen.Generate( 924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000), 934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000)); 94d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ByteString FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); 954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDF_Type3Glyphs* pSizeCache; 964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann auto it = m_SizeMap.find(FaceGlyphsKey); 974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (it == m_SizeMap.end()) { 98d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann auto pNew = pdfium::MakeUnique<CPDF_Type3Glyphs>(); 99d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pSizeCache = pNew.get(); 100d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann m_SizeMap[FaceGlyphsKey] = std::move(pNew); 1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 102d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pSizeCache = it->second.get(); 1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann auto it2 = pSizeCache->m_GlyphMap.find(charcode); 1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (it2 != pSizeCache->m_GlyphMap.end()) 106d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return it2->second.get(); 1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 108d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann std::unique_ptr<CFX_GlyphBitmap> pNewBitmap = 1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann RenderGlyph(pSizeCache, charcode, pMatrix, retinaScaleX, retinaScaleY); 110d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CFX_GlyphBitmap* pGlyphBitmap = pNewBitmap.get(); 111d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pSizeCache->m_GlyphMap[charcode] = std::move(pNewBitmap); 1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return pGlyphBitmap; 1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 115d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::unique_ptr<CFX_GlyphBitmap> CPDF_Type3Cache::RenderGlyph( 116d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CPDF_Type3Glyphs* pSize, 117d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann uint32_t charcode, 118d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const CFX_Matrix* pMatrix, 119d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float retinaScaleX, 120d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float retinaScaleY) { 1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode); 122d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!pChar || !pChar->GetBitmap()) 1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann CFX_Matrix text_matrix(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0); 126d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CFX_Matrix image_matrix = pChar->matrix(); 1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image_matrix.Concat(text_matrix); 12833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann 129d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann RetainPtr<CFX_DIBitmap> pBitmap = pChar->GetBitmap(); 130d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann RetainPtr<CFX_DIBitmap> pResBitmap; 1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int left = 0; 1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int top = 0; 133d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (fabs(image_matrix.b) < fabs(image_matrix.a) / 100 && 134d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fabs(image_matrix.c) < fabs(image_matrix.d) / 100) { 1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int top_line = DetectFirstLastScan(pBitmap, true); 1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bottom_line = DetectFirstLastScan(pBitmap, false); 1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (top_line == 0 && bottom_line == pBitmap->GetHeight() - 1) { 138d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float top_y = image_matrix.d + image_matrix.f; 139d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float bottom_y = image_matrix.f; 1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bool bFlipped = top_y > bottom_y; 1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bFlipped) { 142d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float temp = top_y; 1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann top_y = bottom_y; 1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bottom_y = temp; 1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pSize->AdjustBlue(top_y, bottom_y, top_line, bottom_line); 1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pResBitmap = pBitmap->StretchTo( 148d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann static_cast<int>(FXSYS_round(image_matrix.a) * retinaScaleX), 149d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann static_cast<int>( 150d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann (bFlipped ? top_line - bottom_line : bottom_line - top_line) * 151d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann retinaScaleY), 152d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 0, nullptr); 1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann top = top_line; 1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image_matrix.a < 0) { 1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image_matrix.Scale(retinaScaleX, retinaScaleY); 1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann left = FXSYS_round(image_matrix.e + image_matrix.a); 1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else { 1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann left = FXSYS_round(image_matrix.e); 1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!pResBitmap) { 1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image_matrix.Scale(retinaScaleX, retinaScaleY); 164d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pResBitmap = pBitmap->TransformTo(&image_matrix, &left, &top); 1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!pResBitmap) 1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 169d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann auto pGlyph = pdfium::MakeUnique<CFX_GlyphBitmap>(); 1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pGlyph->m_Left = left; 1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pGlyph->m_Top = -top; 172d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann pGlyph->m_pBitmap->TakeOver(std::move(pResBitmap)); 1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return pGlyph; 1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 175