| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fpdfapi/fpdf_render/render_int.h" | 7 #include "core/fpdfapi/fpdf_render/render_int.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 : m_dwCount(0), m_pType3Font(pType3Font) {} | 364 : m_dwCount(0), m_pType3Font(pType3Font) {} |
| 365 ~CPDF_RefType3Cache() { | 365 ~CPDF_RefType3Cache() { |
| 366 while (m_dwCount--) { | 366 while (m_dwCount--) { |
| 367 ReleaseCachedType3(m_pType3Font); | 367 ReleaseCachedType3(m_pType3Font); |
| 368 } | 368 } |
| 369 } | 369 } |
| 370 uint32_t m_dwCount; | 370 uint32_t m_dwCount; |
| 371 CPDF_Type3Font* const m_pType3Font; | 371 CPDF_Type3Font* const m_pType3Font; |
| 372 }; | 372 }; |
| 373 | 373 |
| 374 // TODO(npm): Font fallback for type 3 fonts? (Completely separate code!!) |
| 374 FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, | 375 FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, |
| 375 const CFX_Matrix* pObj2Device) { | 376 const CFX_Matrix* pObj2Device) { |
| 376 CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->AsType3Font(); | 377 CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->AsType3Font(); |
| 377 for (int i = 0; i < m_Type3FontCache.GetSize(); ++i) { | 378 for (int i = 0; i < m_Type3FontCache.GetSize(); ++i) { |
| 378 if (m_Type3FontCache.GetAt(i) == pType3Font) | 379 if (m_Type3FontCache.GetAt(i) == pType3Font) |
| 379 return TRUE; | 380 return TRUE; |
| 380 } | 381 } |
| 381 | 382 |
| 382 CFX_Matrix dCTM = m_pDevice->GetCTM(); | 383 CFX_Matrix dCTM = m_pDevice->GetCTM(); |
| 383 FX_FLOAT sa = FXSYS_fabs(dCTM.a); | 384 FX_FLOAT sa = FXSYS_fabs(dCTM.a); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 nChars == 1 ? (uint32_t)(uintptr_t)pCharCodes : pCharCodes[iChar]; | 566 nChars == 1 ? (uint32_t)(uintptr_t)pCharCodes : pCharCodes[iChar]; |
| 566 if (CharCode == (uint32_t)-1) { | 567 if (CharCode == (uint32_t)-1) { |
| 567 continue; | 568 continue; |
| 568 } | 569 } |
| 569 bool bVert = false; | 570 bool bVert = false; |
| 570 FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; | 571 FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; |
| 571 if (pCIDFont) { | 572 if (pCIDFont) { |
| 572 charpos.m_bFontStyle = true; | 573 charpos.m_bFontStyle = true; |
| 573 } | 574 } |
| 574 charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); | 575 charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); |
| 576 if (charpos.m_GlyphIndex != static_cast<uint32_t>(-1)) { |
| 577 charpos.m_FallbackFontPosition = -1; |
| 578 } else { |
| 579 charpos.m_FallbackFontPosition = |
| 580 pFont->FallbackFontFromCharcode(CharCode); |
| 581 charpos.m_GlyphIndex = pFont->FallbackGlyphFromCharcode( |
| 582 charpos.m_FallbackFontPosition, CharCode); |
| 583 } |
| 584 // TODO(npm): Figure out how this affects m_ExtGID |
| 575 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 585 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 576 charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); | 586 charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); |
| 577 #endif | 587 #endif |
| 578 if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) { | 588 if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) { |
| 579 charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); | 589 charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); |
| 580 } else { | 590 } else { |
| 581 charpos.m_FontCharWidth = 0; | 591 charpos.m_FontCharWidth = 0; |
| 582 } | 592 } |
| 583 charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; | 593 charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; |
| 584 charpos.m_OriginY = 0; | 594 charpos.m_OriginY = 0; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 const CFX_GraphStateData* pGraphState, | 632 const CFX_GraphStateData* pGraphState, |
| 623 FX_ARGB fill_argb, | 633 FX_ARGB fill_argb, |
| 624 FX_ARGB stroke_argb, | 634 FX_ARGB stroke_argb, |
| 625 CFX_PathData* pClippingPath, | 635 CFX_PathData* pClippingPath, |
| 626 int nFlag) { | 636 int nFlag) { |
| 627 CFX_FontCache* pCache = | 637 CFX_FontCache* pCache = |
| 628 pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() | 638 pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() |
| 629 : nullptr; | 639 : nullptr; |
| 630 CPDF_CharPosList CharPosList; | 640 CPDF_CharPosList CharPosList; |
| 631 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); | 641 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); |
| 632 return pDevice->DrawTextPath(CharPosList.m_nChars, CharPosList.m_pCharPos, | 642 if (CharPosList.m_nChars == 0) |
| 633 &pFont->m_Font, pCache, font_size, pText2User, | 643 return TRUE; |
| 634 pUser2Device, pGraphState, fill_argb, | 644 bool bDraw = true; |
| 635 stroke_argb, pClippingPath, nFlag); | 645 int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition; |
| 646 uint32_t startIndex = 0; |
| 647 for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { |
| 648 int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition; |
| 649 if (fontPosition == curFontPosition) |
| 650 continue; |
| 651 auto* font = fontPosition == -1 |
| 652 ? &pFont->m_Font |
| 653 : pFont->m_FontFallbacks[fontPosition].get(); |
| 654 if (!pDevice->DrawTextPath( |
| 655 i - startIndex, CharPosList.m_pCharPos + startIndex, font, pCache, |
| 656 font_size, pText2User, pUser2Device, pGraphState, fill_argb, |
| 657 stroke_argb, pClippingPath, nFlag)) { |
| 658 bDraw = false; |
| 659 } |
| 660 fontPosition = curFontPosition; |
| 661 startIndex = i; |
| 662 } |
| 663 auto* font = fontPosition == -1 ? &pFont->m_Font |
| 664 : pFont->m_FontFallbacks[fontPosition].get(); |
| 665 if (!pDevice->DrawTextPath(CharPosList.m_nChars - startIndex, |
| 666 CharPosList.m_pCharPos + startIndex, font, pCache, |
| 667 font_size, pText2User, pUser2Device, pGraphState, |
| 668 fill_argb, stroke_argb, pClippingPath, nFlag)) { |
| 669 bDraw = false; |
| 670 } |
| 671 return bDraw; |
| 636 } | 672 } |
| 637 | 673 |
| 638 // static | 674 // static |
| 639 void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, | 675 void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, |
| 640 FX_FLOAT origin_x, | 676 FX_FLOAT origin_x, |
| 641 FX_FLOAT origin_y, | 677 FX_FLOAT origin_y, |
| 642 CPDF_Font* pFont, | 678 CPDF_Font* pFont, |
| 643 FX_FLOAT font_size, | 679 FX_FLOAT font_size, |
| 644 const CFX_Matrix* pMatrix, | 680 const CFX_Matrix* pMatrix, |
| 645 const CFX_ByteString& str, | 681 const CFX_ByteString& str, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 CPDF_Font* pFont, | 737 CPDF_Font* pFont, |
| 702 FX_FLOAT font_size, | 738 FX_FLOAT font_size, |
| 703 const CFX_Matrix* pText2Device, | 739 const CFX_Matrix* pText2Device, |
| 704 FX_ARGB fill_argb, | 740 FX_ARGB fill_argb, |
| 705 const CPDF_RenderOptions* pOptions) { | 741 const CPDF_RenderOptions* pOptions) { |
| 706 CFX_FontCache* pCache = | 742 CFX_FontCache* pCache = |
| 707 pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() | 743 pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() |
| 708 : nullptr; | 744 : nullptr; |
| 709 CPDF_CharPosList CharPosList; | 745 CPDF_CharPosList CharPosList; |
| 710 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); | 746 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); |
| 747 if (CharPosList.m_nChars == 0) |
| 748 return TRUE; |
| 711 int FXGE_flags = 0; | 749 int FXGE_flags = 0; |
| 712 if (pOptions) { | 750 if (pOptions) { |
| 713 uint32_t dwFlags = pOptions->m_Flags; | 751 uint32_t dwFlags = pOptions->m_Flags; |
| 714 if (dwFlags & RENDER_CLEARTYPE) { | 752 if (dwFlags & RENDER_CLEARTYPE) { |
| 715 FXGE_flags |= FXTEXT_CLEARTYPE; | 753 FXGE_flags |= FXTEXT_CLEARTYPE; |
| 716 if (dwFlags & RENDER_BGR_STRIPE) { | 754 if (dwFlags & RENDER_BGR_STRIPE) { |
| 717 FXGE_flags |= FXTEXT_BGR_STRIPE; | 755 FXGE_flags |= FXTEXT_BGR_STRIPE; |
| 718 } | 756 } |
| 719 } | 757 } |
| 720 if (dwFlags & RENDER_NOTEXTSMOOTH) { | 758 if (dwFlags & RENDER_NOTEXTSMOOTH) { |
| 721 FXGE_flags |= FXTEXT_NOSMOOTH; | 759 FXGE_flags |= FXTEXT_NOSMOOTH; |
| 722 } | 760 } |
| 723 if (dwFlags & RENDER_PRINTGRAPHICTEXT) { | 761 if (dwFlags & RENDER_PRINTGRAPHICTEXT) { |
| 724 FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT; | 762 FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT; |
| 725 } | 763 } |
| 726 if (dwFlags & RENDER_NO_NATIVETEXT) { | 764 if (dwFlags & RENDER_NO_NATIVETEXT) { |
| 727 FXGE_flags |= FXTEXT_NO_NATIVETEXT; | 765 FXGE_flags |= FXTEXT_NO_NATIVETEXT; |
| 728 } | 766 } |
| 729 if (dwFlags & RENDER_PRINTIMAGETEXT) { | 767 if (dwFlags & RENDER_PRINTIMAGETEXT) { |
| 730 FXGE_flags |= FXTEXT_PRINTIMAGETEXT; | 768 FXGE_flags |= FXTEXT_PRINTIMAGETEXT; |
| 731 } | 769 } |
| 732 } else { | 770 } else { |
| 733 FXGE_flags = FXTEXT_CLEARTYPE; | 771 FXGE_flags = FXTEXT_CLEARTYPE; |
| 734 } | 772 } |
| 735 if (pFont->IsCIDFont()) { | 773 if (pFont->IsCIDFont()) { |
| 736 FXGE_flags |= FXFONT_CIDFONT; | 774 FXGE_flags |= FXFONT_CIDFONT; |
| 737 } | 775 } |
| 738 return pDevice->DrawNormalText(CharPosList.m_nChars, CharPosList.m_pCharPos, | 776 bool bDraw = true; |
| 739 &pFont->m_Font, pCache, font_size, | 777 int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition; |
| 740 pText2Device, fill_argb, FXGE_flags); | 778 uint32_t startIndex = 0; |
| 779 for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { |
| 780 int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition; |
| 781 if (fontPosition == curFontPosition) |
| 782 continue; |
| 783 auto* font = fontPosition == -1 |
| 784 ? &pFont->m_Font |
| 785 : pFont->m_FontFallbacks[fontPosition].get(); |
| 786 if (!pDevice->DrawNormalText( |
| 787 i - startIndex, CharPosList.m_pCharPos + startIndex, font, pCache, |
| 788 font_size, pText2Device, fill_argb, FXGE_flags)) { |
| 789 bDraw = false; |
| 790 } |
| 791 fontPosition = curFontPosition; |
| 792 startIndex = i; |
| 793 } |
| 794 auto* font = fontPosition == -1 ? &pFont->m_Font |
| 795 : pFont->m_FontFallbacks[fontPosition].get(); |
| 796 if (!pDevice->DrawNormalText(CharPosList.m_nChars - startIndex, |
| 797 CharPosList.m_pCharPos + startIndex, font, |
| 798 pCache, font_size, pText2Device, fill_argb, |
| 799 FXGE_flags)) { |
| 800 bDraw = false; |
| 801 } |
| 802 return bDraw; |
| 741 } | 803 } |
| 742 | 804 |
| 743 void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, | 805 void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, |
| 744 const CFX_Matrix* pObj2Device, | 806 const CFX_Matrix* pObj2Device, |
| 745 CPDF_Font* pFont, | 807 CPDF_Font* pFont, |
| 746 FX_FLOAT font_size, | 808 FX_FLOAT font_size, |
| 747 const CFX_Matrix* pTextMatrix, | 809 const CFX_Matrix* pTextMatrix, |
| 748 FX_BOOL bFill, | 810 FX_BOOL bFill, |
| 749 FX_BOOL bStroke) { | 811 FX_BOOL bStroke) { |
| 750 if (!bStroke) { | 812 if (!bStroke) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 763 path.m_Top = textobj->m_Top; | 825 path.m_Top = textobj->m_Top; |
| 764 RenderSingleObject(&path, pObj2Device); | 826 RenderSingleObject(&path, pObj2Device); |
| 765 return; | 827 return; |
| 766 } | 828 } |
| 767 CFX_FontCache* pCache; | 829 CFX_FontCache* pCache; |
| 768 if (pFont->m_pDocument) { | 830 if (pFont->m_pDocument) { |
| 769 pCache = pFont->m_pDocument->GetRenderData()->GetFontCache(); | 831 pCache = pFont->m_pDocument->GetRenderData()->GetFontCache(); |
| 770 } else { | 832 } else { |
| 771 pCache = CFX_GEModule::Get()->GetFontCache(); | 833 pCache = CFX_GEModule::Get()->GetFontCache(); |
| 772 } | 834 } |
| 773 CFX_FaceCache* pFaceCache = pCache->GetCachedFace(&pFont->m_Font); | |
| 774 CFX_AutoFontCache autoFontCache(pCache, &pFont->m_Font); | |
| 775 CPDF_CharPosList CharPosList; | 835 CPDF_CharPosList CharPosList; |
| 776 CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes, | 836 CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes, |
| 777 textobj->m_pCharPos, pFont, font_size); | 837 textobj->m_pCharPos, pFont, font_size); |
| 838 std::vector<CFX_FaceCache*> faceCaches; |
| 839 std::vector<CFX_AutoFontCache> autoFontCaches; |
| 840 faceCaches.push_back(pCache->GetCachedFace(&pFont->m_Font)); |
| 841 autoFontCaches.push_back(CFX_AutoFontCache(pCache, &pFont->m_Font)); |
| 842 for (const auto& font : pFont->m_FontFallbacks) { |
| 843 faceCaches.push_back(pCache->GetCachedFace(font.get())); |
| 844 autoFontCaches.push_back(CFX_AutoFontCache(pCache, font.get())); |
| 845 } |
| 778 for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { | 846 for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { |
| 779 FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; | 847 FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; |
| 780 const CFX_PathData* pPath = pFaceCache->LoadGlyphPath( | 848 auto font = |
| 781 &pFont->m_Font, charpos.m_GlyphIndex, charpos.m_FontCharWidth); | 849 charpos.m_FallbackFontPosition == -1 |
| 850 ? &pFont->m_Font |
| 851 : pFont->m_FontFallbacks[charpos.m_FallbackFontPosition].get(); |
| 852 const CFX_PathData* pPath = |
| 853 faceCaches[charpos.m_FallbackFontPosition + 1]->LoadGlyphPath( |
| 854 font, charpos.m_GlyphIndex, charpos.m_FontCharWidth); |
| 782 if (!pPath) { | 855 if (!pPath) { |
| 783 continue; | 856 continue; |
| 784 } | 857 } |
| 785 CPDF_PathObject path; | 858 CPDF_PathObject path; |
| 786 path.m_GraphState = textobj->m_GraphState; | 859 path.m_GraphState = textobj->m_GraphState; |
| 787 path.m_ColorState = textobj->m_ColorState; | 860 path.m_ColorState = textobj->m_ColorState; |
| 788 CFX_Matrix matrix; | 861 CFX_Matrix matrix; |
| 789 if (charpos.m_bGlyphAdjust) | 862 if (charpos.m_bGlyphAdjust) |
| 790 matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], | 863 matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], |
| 791 charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); | 864 charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); |
| 792 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, | 865 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, |
| 793 charpos.m_OriginY); | 866 charpos.m_OriginY); |
| 794 path.m_Path.New()->Append(pPath, &matrix); | 867 path.m_Path.New()->Append(pPath, &matrix); |
| 795 path.m_Matrix = *pTextMatrix; | 868 path.m_Matrix = *pTextMatrix; |
| 796 path.m_bStroke = bStroke; | 869 path.m_bStroke = bStroke; |
| 797 path.m_FillType = bFill ? FXFILL_WINDING : 0; | 870 path.m_FillType = bFill ? FXFILL_WINDING : 0; |
| 798 path.CalcBoundingBox(); | 871 path.CalcBoundingBox(); |
| 799 ProcessPath(&path, pObj2Device); | 872 ProcessPath(&path, pObj2Device); |
| 800 } | 873 } |
| 801 } | 874 } |
| OLD | NEW |