1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved. 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file. 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxge/fx_ge.h" 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_render.h" 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_pageobj.h" 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../fpdf_page/pageint.h" 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "render_int.h" 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix); 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Type3Cache::~CPDF_Type3Cache() 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_POSITION pos = m_SizeMap.GetStartPosition(); 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_ByteString Key; 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Type3Glyphs* pSizeCache = NULL; 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(pos) { 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pSizeCache = (CPDF_Type3Glyphs*)m_SizeMap.GetNextValue(pos); 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete pSizeCache; 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_SizeMap.RemoveAll(); 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY) 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _CPDF_UniqueKeyGen keygen; 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov keygen.Generate(4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000), 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000)); 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Type3Glyphs* pSizeCache = NULL; 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) { 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pSizeCache = FX_NEW CPDF_Type3Glyphs; 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_GlyphBitmap* pGlyphBitmap; 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR)charcode, (void*&)pGlyphBitmap)) { 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pGlyphBitmap; 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyphBitmap = RenderGlyph(pSizeCache, charcode, pMatrix, retinaScaleX, retinaScaleY); 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)charcode, pGlyphBitmap); 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pGlyphBitmap; 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Type3Glyphs::~CPDF_Type3Glyphs() 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_POSITION pos = m_GlyphMap.GetStartPosition(); 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPVOID Key; 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_GlyphBitmap* pGlyphBitmap; 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(pos) { 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap); 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete pGlyphBitmap; 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic int _AdjustBlue(FX_FLOAT pos, int& count, int blues[]) 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT min_distance = 1000000.0f * 1.0f; 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int closest_pos = -1; 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int i = 0; i < count; i ++) { 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT distance = (FX_FLOAT)FXSYS_fabs(pos - (FX_FLOAT)blues[i]); 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (distance < 1.0f * 80.0f / 100.0f && distance < min_distance) { 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min_distance = distance; 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov closest_pos = i; 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (closest_pos >= 0) { 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return blues[closest_pos]; 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int new_pos = FXSYS_round(pos); 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (count == TYPE3_MAX_BLUES) { 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return new_pos; 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov blues[count++] = new_pos; 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return new_pos; 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Type3Glyphs::AdjustBlue(FX_FLOAT top, FX_FLOAT bottom, int& top_line, int& bottom_line) 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top_line = _AdjustBlue(top, m_TopBlueCount, m_TopBlue); 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom_line = _AdjustBlue(bottom, m_BottomBlueCount, m_BottomBlue); 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_BOOL _IsScanLine1bpp(FX_LPBYTE pBuf, int width) 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int size = width / 8; 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int i = 0; i < size; i ++) 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pBuf[i]) { 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (width % 8) 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pBuf[width / 8] & (0xff << (8 - width % 8))) { 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_BOOL _IsScanLine8bpp(FX_LPBYTE pBuf, int width) 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int i = 0; i < width; i ++) 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pBuf[i] > 0x40) { 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic int _DetectFirstLastScan(const CFX_DIBitmap* pBitmap, FX_BOOL bFirst) 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int height = pBitmap->GetHeight(), pitch = pBitmap->GetPitch(), width = pBitmap->GetWidth(); 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int bpp = pBitmap->GetBPP(); 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bpp > 8) { 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov width *= bpp / 8; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPBYTE pBuf = pBitmap->GetBuffer(); 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int line = bFirst ? 0 : height - 1; 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int line_step = bFirst ? 1 : -1; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int line_end = bFirst ? height : -1; 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (line != line_end) { 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bpp == 1) { 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (_IsScanLine1bpp(pBuf + line * pitch, width)) { 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return line; 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (_IsScanLine8bpp(pBuf + line * pitch, width)) { 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return line; 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line += line_step; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY) 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode); 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pChar == NULL || pChar->m_pBitmap == NULL) { 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_DIBitmap* pBitmap = pChar->m_pBitmap; 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix image_matrix, text_matrix; 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_matrix = pChar->m_ImageMatrix; 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0); 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_matrix.Concat(text_matrix); 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_DIBitmap* pResBitmap = NULL; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int left, top; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (FXSYS_fabs(image_matrix.b) < FXSYS_fabs(image_matrix.a) / 100 && FXSYS_fabs(image_matrix.c) < FXSYS_fabs(image_matrix.d) / 100) { 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int top_line, bottom_line; 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top_line = _DetectFirstLastScan(pBitmap, TRUE); 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom_line = _DetectFirstLastScan(pBitmap, FALSE); 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (top_line == 0 && bottom_line == pBitmap->GetHeight() - 1) { 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT top_y = image_matrix.d + image_matrix.f; 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT bottom_y = image_matrix.f; 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bFlipped = top_y > bottom_y; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bFlipped) { 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT temp = top_y; 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top_y = bottom_y; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom_y = temp; 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pSize->AdjustBlue(top_y, bottom_y, top_line, bottom_line); 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pResBitmap = pBitmap->StretchTo((int)(FXSYS_round(image_matrix.a) * retinaScaleX), (int)((bFlipped ? top_line - bottom_line : bottom_line - top_line) * retinaScaleY)); 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = top_line; 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (image_matrix.a < 0) { 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_matrix.Scale(retinaScaleX, retinaScaleY); 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov left = FXSYS_round(image_matrix.e + image_matrix.a); 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov left = FXSYS_round(image_matrix.e); 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pResBitmap == NULL) { 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_matrix.Scale(retinaScaleX, retinaScaleY); 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pResBitmap = pBitmap->TransformTo(&image_matrix, left, top); 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pResBitmap == NULL) { 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_GlyphBitmap* pGlyph = FX_NEW CFX_GlyphBitmap; 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyph->m_Left = left; 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyph->m_Top = -top; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyph->m_Bitmap.TakeOver(pResBitmap); 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete pResBitmap; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pGlyph; 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _CPDF_UniqueKeyGen::Generate(int count, ...) 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_list argList; 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_start(argList, count); 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int i = 0; i < count; i ++) { 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int p = va_arg(argList, int); 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((FX_DWORD*)m_Key)[i] = p; 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_end(argList); 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_KeyLen = count * sizeof(FX_DWORD); 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, CFX_PathData* pClippingPath) 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(textobj->m_nChars == 0) { 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode; 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (text_render_mode == 3) { 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Font* pFont = textobj->m_TextState.GetFont(); 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pFont->GetFontType() == PDFFONT_TYPE3) { 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ProcessType3Text(textobj, pObj2Device); 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bFill = FALSE, bStroke = FALSE, bClip = FALSE; 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pClippingPath) { 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bClip = TRUE; 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (text_render_mode) { 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 0: 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 4: 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bFill = TRUE; 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 5: 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bFill = TRUE; 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bStroke = TRUE; 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 2: 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 6: 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bFill = TRUE; 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bFill = bStroke = TRUE; 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 3: 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 7: 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bFill = TRUE; 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_ARGB stroke_argb = 0, fill_argb = 0; 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bPattern = FALSE; 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bStroke) { 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) { 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bPattern = TRUE; 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov stroke_argb = GetStrokeArgb(textobj); 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bFill) { 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (textobj->m_ColorState.GetFillColor()->IsPattern()) { 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bPattern = TRUE; 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fill_argb = GetFillArgb(textobj); 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix text_matrix; 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov textobj->GetTextMatrix(&text_matrix); 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(IsAvailableMatrix(text_matrix) == FALSE) { 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bPattern) { 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, &text_matrix, bFill, bStroke); 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined(_FPDFAPI_MINI_) 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bFill) { 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bStroke = FALSE; 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bStroke) { 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (font_size * text_matrix.GetXUnit() * pObj2Device->GetXUnit() < 6) { 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bStroke = FALSE; 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bClip || bStroke) { 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_AffineMatrix* pDeviceMatrix = pObj2Device; 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix device_matrix; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bStroke) { 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM; 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov text_matrix.ConcatInverse(ctm); 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov device_matrix.Copy(ctm); 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov device_matrix.Concat(*pObj2Device); 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pDeviceMatrix = &device_matrix; 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int flag = 0; 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bStroke && bFill) { 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flag |= FX_FILL_STROKE; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flag |= FX_STROKE_TEXT_MODE; 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)textobj)->m_GeneralState; 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pGeneralData && pGeneralData->m_StrokeAdjust) { 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flag |= FX_STROKE_ADJUST; 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) { 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flag |= FXFILL_NOPATHSMOOTH; 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return CPDF_TextRenderer::DrawTextPath(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &text_matrix, pDeviceMatrix, textobj->m_GraphState, fill_argb, stroke_argb, pClippingPath, flag); 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov text_matrix.Concat(*pObj2Device); 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return CPDF_TextRenderer::DrawNormalText(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &text_matrix, fill_argb, &m_Options); 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Type3Cache* CPDF_RenderStatus::GetCachedType3(CPDF_Type3Font* pFont) 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pFont->m_pDocument == NULL) { 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFont->m_pDocument->GetPageData()->GetFont(pFont->GetFontDict(), FALSE); 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pFont->m_pDocument->GetRenderData()->GetCachedType3(pFont); 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void ReleaseCachedType3(CPDF_Type3Font* pFont) 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pFont->m_pDocument == NULL) { 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFont->m_pDocument->GetRenderData()->ReleaseCachedType3(pFont); 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict()); 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m_pBitmap != NULL || m_pForm == NULL) { 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m_pForm->CountObjects() == 1 && !m_bColored) { 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_PageObject *pPageObj = m_pForm->GetObjectAt(m_pForm->GetFirstObjectPosition()); 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pPageObj->m_Type == PDFPAGE_IMAGE) { 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_ImageObject* pImage = (CPDF_ImageObject*)pPageObj; 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_ImageMatrix = pImage->m_Matrix; 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_DIBSource* pSource = pImage->m_pImage->LoadDIBSource(); 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pSource) { 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pBitmap = pSource->Clone(); 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete pSource; 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete m_pForm; 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pForm = NULL; 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pPageObj->m_Type == PDFPAGE_INLINES) { 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_InlineImages *pInlines = (CPDF_InlineImages *)pPageObj; 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pInlines->m_pStream) { 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_ImageMatrix = pInlines->m_Matrices[0]; 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_DIBSource dibsrc; 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!dibsrc.Load(pContext->m_pDocument, pInlines->m_pStream, NULL, NULL, NULL, NULL)) { 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pBitmap = dibsrc.Clone(); 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete m_pForm; 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pForm = NULL; 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_RefType3Cache 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic: 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_RefType3Cache(CPDF_Type3Font* pType3Font) 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_dwCount = 0; 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pType3Font = pType3Font; 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ~CPDF_RefType3Cache() 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(m_dwCount--) { 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ReleaseCachedType3(m_pType3Font); 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD m_dwCount; 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Type3Font* m_pType3Font; 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device) 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font(); 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int j = 0; j < m_Type3FontCache.GetSize(); j++) 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((CPDF_Type3Font*)m_Type3FontCache.GetAt(j) == pType3Font) { 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_Matrix dCTM = m_pDevice->GetCTM(); 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT sa = FXSYS_fabs(dCTM.a); 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT sd = FXSYS_fabs(dCTM.d); 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix text_matrix; 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov textobj->GetTextMatrix(&text_matrix); 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix char_matrix = pType3Font->GetFontMatrix(); 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_matrix.Scale(font_size, font_size); 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_ARGB fill_argb = GetFillArgb(textobj, TRUE); 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int fill_alpha = FXARGB_A(fill_argb); 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int device_class = m_pDevice->GetDeviceClass(); 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXTEXT_GLYPHPOS* pGlyphAndPos = NULL; 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (device_class == FXDC_DISPLAY) { 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars); 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXSYS_memset32(pGlyphAndPos, 0, sizeof(FXTEXT_GLYPHPOS) * textobj->m_nChars); 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (fill_alpha < 255) { 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_RefType3Cache refTypeCache(pType3Font); 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD *pChars = textobj->m_pCharCodes; 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (textobj->m_nChars == 1) { 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pChars = (FX_DWORD*)(&textobj->m_pCharCodes); 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) { 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD charcode = pChars[iChar]; 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (charcode == (FX_DWORD) - 1) { 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode); 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pType3Char == NULL) { 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix matrix = char_matrix; 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0; 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.Concat(text_matrix); 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.Concat(*pObj2Device); 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pType3Char->LoadBitmap(m_pContext)) { 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pGlyphAndPos) { 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int i = 0; i < iChar; i ++) { 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i]; 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (glyph.m_pGlyph == NULL) { 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap, 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph.m_OriginX + glyph.m_pGlyph->m_Left, 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph.m_OriginY - glyph.m_pGlyph->m_Top, fill_argb); 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(pGlyphAndPos); 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyphAndPos = NULL; 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE); 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_RenderOptions Options = m_Options; 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA; 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE; 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Dictionary* pFormResource = NULL; 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) { 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFormResource = pType3Char->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (fill_alpha == 255) { 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_RenderStatus status; 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov status.Initialize(m_Level + 1, m_pContext, m_pDevice, NULL, NULL, this, pStates, &Options, 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb); 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov status.m_Type3FontCache.Append(m_Type3FontCache); 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov status.m_Type3FontCache.Add(pType3Font); 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDevice->SaveState(); 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov status.RenderObjectList(pType3Char->m_pForm, &matrix); 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDevice->RestoreState(); 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox(); 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rect_f.Transform(&matrix); 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_RECT rect = rect_f.GetOutterRect(); 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_FxgeDevice bitmap_device; 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!bitmap_device.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_Argb)) { 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bitmap_device.GetBitmap()->Clear(0); 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_RenderStatus status; 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov status.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL, NULL, this, pStates, &Options, 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb); 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov status.m_Type3FontCache.Append(m_Type3FontCache); 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov status.m_Type3FontCache.Add(pType3Font); 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.TranslateI(-rect.left, -rect.top); 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.Scale(sa, sd); 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov status.RenderObjectList(pType3Char->m_pForm, &matrix); 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top); 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete pStates; 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (pType3Char->m_pBitmap) { 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (device_class == FXDC_DISPLAY) { 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Type3Cache* pCache = GetCachedType3(pType3Font); 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov refTypeCache.m_dwCount++; 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_GlyphBitmap* pBitmap = pCache->LoadGlyph(charcode, &matrix, sa, sd); 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pBitmap == NULL) { 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int origin_x = FXSYS_round(matrix.e); 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int origin_y = FXSYS_round(matrix.f); 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pGlyphAndPos) { 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyphAndPos[iChar].m_pGlyph = pBitmap; 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyphAndPos[iChar].m_OriginX = origin_x; 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGlyphAndPos[iChar].m_OriginY = origin_y; 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, origin_y - pBitmap->m_Top, fill_argb); 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix image_matrix = pType3Char->m_ImageMatrix; 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov image_matrix.Concat(matrix); 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_ImageRenderer renderer; 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (renderer.Start(this, pType3Char->m_pBitmap, fill_argb, 255, &image_matrix, 0, FALSE)) { 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov renderer.Continue(NULL); 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!renderer.m_Result) { 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pGlyphAndPos) { 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_RECT rect = FXGE_GetGlyphsBBox(pGlyphAndPos, textobj->m_nChars, 0, sa, sd); 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_DIBitmap bitmap; 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!bitmap.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_8bppMask)) { 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(pGlyphAndPos); 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bitmap.Clear(0); 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) { 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar]; 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (glyph.m_pGlyph == NULL) { 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bitmap.TransferBitmap((int)((glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa), 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (int)((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) * sd), 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph.m_pGlyph->m_Bitmap.GetWidth(), glyph.m_pGlyph->m_Bitmap.GetHeight(), 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &glyph.m_pGlyph->m_Bitmap, 0, 0); 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb); 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(pGlyphAndPos); 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_CharPosList 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic: 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_CharPosList(); 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ~CPDF_CharPosList(); 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void Load(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, FX_FLOAT font_size); 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXTEXT_CHARPOS* m_pCharPos; 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD m_nChars; 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_FLOAT _CIDTransformToFloat(FX_BYTE ch); 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CharPosList::CPDF_CharPosList() 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pCharPos = NULL; 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CharPosList::~CPDF_CharPosList() 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m_pCharPos) { 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(m_pCharPos); 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CharPosList::Load(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT FontSize) 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars); 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXSYS_memset32(m_pCharPos, 0, sizeof(FXTEXT_CHARPOS) * nChars); 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_nChars = 0; 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int iChar = 0; iChar < nChars; iChar ++) { 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD CharCode = nChars == 1 ? (FX_DWORD)(FX_UINTPTR)pCharCodes : pCharCodes[iChar]; 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (CharCode == (FX_DWORD) - 1) { 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bVert = FALSE; 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pCIDFont) { 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_bFontStyle = pCIDFont->IsFontStyleFromCharCode(CharCode); 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!pFont->IsEmbedded() && pFont->GetFontType() != PDFFONT_CIDFONT) { 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_FontCharWidth = 0; 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_OriginY = 0; 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_bGlyphAdjust = FALSE; 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pCIDFont == NULL) { 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_WORD CID = pCIDFont->CIDFromCharCode(CharCode); 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (bVertWriting) { 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_OriginY = charpos.m_OriginX; 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_OriginX = 0; 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov short vx, vy; 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCIDFont->GetVertOrigin(CID, vx, vy); 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_OriginX -= FontSize * vx / 1000; 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_OriginY -= FontSize * vy / 1000; 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPCBYTE pTransform = pCIDFont->GetCIDTransform(CID); 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pTransform && !bVert) { 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_AdjustMatrix[0] = _CIDTransformToFloat(pTransform[0]); 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_AdjustMatrix[2] = _CIDTransformToFloat(pTransform[2]); 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_AdjustMatrix[1] = _CIDTransformToFloat(pTransform[1]); 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_AdjustMatrix[3] = _CIDTransformToFloat(pTransform[3]); 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_OriginX += _CIDTransformToFloat(pTransform[4]) * FontSize; 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_OriginY += _CIDTransformToFloat(pTransform[5]) * FontSize; 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_bGlyphAdjust = TRUE; 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Font* pFont, FX_FLOAT font_size, 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_AffineMatrix* pText2User, const CFX_AffineMatrix* pUser2Device, 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_GraphStateData* pGraphState, 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_ARGB fill_argb, FX_ARGB stroke_argb, CFX_PathData* pClippingPath, int nFlag) 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_FontCache* pCache = pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() : NULL; 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_CharPosList CharPosList; 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pDevice->DrawTextPath(CharPosList.m_nChars, CharPosList.m_pCharPos, 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &pFont->m_Font, pCache, font_size, pText2User, pUser2Device, 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pGraphState, fill_argb, stroke_argb, pClippingPath, nFlag); 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, int left, int top, CPDF_Font* pFont, int height, 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_ByteString& str, FX_ARGB argb) 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_RECT font_bbox; 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pFont->GetFontBBox(font_bbox); 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT font_size = (FX_FLOAT)height * 1000.0f / (FX_FLOAT)(font_bbox.top - font_bbox.bottom); 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT origin_x = (FX_FLOAT)left; 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT origin_y = (FX_FLOAT)top + font_size * (FX_FLOAT)font_bbox.top / 1000.0f; 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix matrix(1.0f, 0, 0, -1.0f, 0, 0); 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DrawTextString(pDevice, origin_x, origin_y, pFont, font_size, &matrix, str, argb); 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, FX_FLOAT origin_x, FX_FLOAT origin_y, CPDF_Font* pFont, FX_FLOAT font_size, 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_AffineMatrix* pMatrix, const CFX_ByteString& str, FX_ARGB fill_argb, 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_ARGB stroke_argb, const CFX_GraphStateData* pGraphState, const CPDF_RenderOptions* pOptions) 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int nChars = pFont->CountChar(str, str.GetLength()); 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChars == 0) { 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD charcode; 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int offset = 0; 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD* pCharCodes; 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT* pCharPos; 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChars == 1) { 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode = pFont->GetNextChar(str, offset); 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCharCodes = (FX_DWORD*)(FX_UINTPTR)charcode; 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCharPos = NULL; 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCharCodes = FX_Alloc(FX_DWORD, nChars); 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCharPos = FX_Alloc(FX_FLOAT, nChars - 1); 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT cur_pos = 0; 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int i = 0; i < nChars; i ++) { 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCharCodes[i] = pFont->GetNextChar(str, offset); 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (i) { 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCharPos[i - 1] = cur_pos; 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur_pos += pFont->GetCharWidthF(pCharCodes[i]) * font_size / 1000; 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix matrix; 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pMatrix) { 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix = *pMatrix; 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.e = origin_x; 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.f = origin_y; 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pFont->GetFontType() == PDFFONT_TYPE3) 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ; 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if (stroke_argb == 0) { 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, &matrix, fill_argb, pOptions); 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, &matrix, NULL, pGraphState, 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fill_argb, stroke_argb, NULL); 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChars > 1) { 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(pCharCodes); 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_Free(pCharPos); 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Font* pFont, FX_FLOAT font_size, 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_AffineMatrix* pText2Device, 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_ARGB fill_argb, const CPDF_RenderOptions* pOptions) 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_FontCache* pCache = pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() : NULL; 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_CharPosList CharPosList; 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int FXGE_flags = 0; 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pOptions) { 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD dwFlags = pOptions->m_Flags; 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & RENDER_CLEARTYPE) { 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXGE_flags |= FXTEXT_CLEARTYPE; 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & RENDER_BGR_STRIPE) { 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXGE_flags |= FXTEXT_BGR_STRIPE; 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & RENDER_NOTEXTSMOOTH) { 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXGE_flags |= FXTEXT_NOSMOOTH; 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & RENDER_PRINTGRAPHICTEXT) { 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT; 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & RENDER_NO_NATIVETEXT) { 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXGE_flags |= FXTEXT_NO_NATIVETEXT; 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & RENDER_PRINTIMAGETEXT) { 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXGE_flags |= FXTEXT_PRINTIMAGETEXT; 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXGE_flags = FXTEXT_CLEARTYPE; 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pFont->GetFontType() & PDFFONT_CIDFONT) { 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXGE_flags |= FXFONT_CIDFONT; 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pDevice->DrawNormalText(CharPosList.m_nChars, CharPosList.m_pCharPos, &pFont->m_Font, pCache, font_size, pText2Device, fill_argb, FXGE_flags); 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Font* pFont, FX_FLOAT font_size, 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_AffineMatrix* pTextMatrix, FX_BOOL bFill, FX_BOOL bStroke) 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!bStroke) { 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_PathObject path; 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_TextObject* pCopy = FX_NEW CPDF_TextObject; 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCopy->Copy(textobj); 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_bStroke = FALSE; 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_FillType = FXFILL_WINDING; 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_ClipPath.AppendTexts(&pCopy, 1); 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_ColorState = textobj->m_ColorState; 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_Path.New()->AppendRect(textobj->m_Left, textobj->m_Bottom, textobj->m_Right, textobj->m_Top); 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_Left = textobj->m_Left; 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_Bottom = textobj->m_Bottom; 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_Right = textobj->m_Right; 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_Top = textobj->m_Top; 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RenderSingleObject(&path, pObj2Device); 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_FontCache* pCache; 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pFont->m_pDocument) { 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCache = pFont->m_pDocument->GetRenderData()->GetFontCache(); 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pCache = CFX_GEModule::Get()->GetFontCache(); 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_FaceCache* pFaceCache = pCache->GetCachedFace(&pFont->m_Font); 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FONTCACHE_DEFINE(pCache, &pFont->m_Font); 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_CharPosList CharPosList; 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size); 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_DWORD i = 0; i < CharPosList.m_nChars; i ++) { 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const CFX_PathData* pPath = pFaceCache->LoadGlyphPath(&pFont->m_Font, charpos.m_GlyphIndex, 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_FontCharWidth); 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pPath == NULL) { 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_PathObject path; 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_GraphState = textobj->m_GraphState; 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_ColorState = textobj->m_ColorState; 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_AffineMatrix matrix; 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (charpos.m_bGlyphAdjust) 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_OriginY); 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_Path.New()->Append(pPath, &matrix); 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_Matrix = *pTextMatrix; 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_bStroke = bStroke; 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.m_FillType = bFill ? FXFILL_WINDING : 0; 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path.CalcBoundingBox(); 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ProcessPath(&path, pObj2Device); 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_PathData* CPDF_Font::LoadGlyphPath(FX_DWORD charcode, int dest_width) 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int glyph_index = GlyphFromCharCode(charcode); 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m_Font.m_Face == NULL) { 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return m_Font.LoadGlyphPath(glyph_index, dest_width); 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 761