void CPDF_RenderStatus::DrawTextPathWithPattern( const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_AffineMatrix* pTextMatrix, FX_BOOL bFill, FX_BOOL bStroke) { if (!bStroke) { CPDF_PathObject path; CPDF_TextObject* pCopy = new CPDF_TextObject; pCopy->Copy(textobj); path.m_bStroke = FALSE; path.m_FillType = FXFILL_WINDING; path.m_ClipPath.AppendTexts(&pCopy, 1); path.m_ColorState = textobj->m_ColorState; path.m_Path.New()->AppendRect(textobj->m_Left, textobj->m_Bottom, textobj->m_Right, textobj->m_Top); path.m_Left = textobj->m_Left; path.m_Bottom = textobj->m_Bottom; path.m_Right = textobj->m_Right; path.m_Top = textobj->m_Top; RenderSingleObject(&path, pObj2Device); return; } CFX_FontCache* pCache; if (pFont->m_pDocument) { pCache = pFont->m_pDocument->GetRenderData()->GetFontCache(); } else { pCache = CFX_GEModule::Get()->GetFontCache(); } CFX_FaceCache* pFaceCache = pCache->GetCachedFace(&pFont->m_Font); FX_FONTCACHE_DEFINE(pCache, &pFont->m_Font); CPDF_CharPosList CharPosList; CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size); for (FX_DWORD i = 0; i < CharPosList.m_nChars; i++) { FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; const CFX_PathData* pPath = pFaceCache->LoadGlyphPath( &pFont->m_Font, charpos.m_GlyphIndex, charpos.m_FontCharWidth); if (pPath == NULL) { continue; } CPDF_PathObject path; path.m_GraphState = textobj->m_GraphState; path.m_ColorState = textobj->m_ColorState; CFX_AffineMatrix matrix; if (charpos.m_bGlyphAdjust) matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_OriginY); path.m_Path.New()->Append(pPath, &matrix); path.m_Matrix = *pTextMatrix; path.m_bStroke = bStroke; path.m_FillType = bFill ? FXFILL_WINDING : 0; path.CalcBoundingBox(); ProcessPath(&path, pObj2Device); } }
FX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_AffineMatrix* pText2User, const CFX_AffineMatrix* pUser2Device, const CFX_GraphStateData* pGraphState, FX_ARGB fill_argb, FX_ARGB stroke_argb, CFX_PathData* pClippingPath, int nFlag) { CFX_FontCache* pCache = pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() : NULL; CPDF_CharPosList CharPosList; CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); return pDevice->DrawTextPath(CharPosList.m_nChars, CharPosList.m_pCharPos, &pFont->m_Font, pCache, font_size, pText2User, pUser2Device, pGraphState, fill_argb, stroke_argb, pClippingPath, nFlag); }
// static bool CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, int nChars, uint32_t* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_Matrix* pText2User, const CFX_Matrix* pUser2Device, const CFX_GraphStateData* pGraphState, FX_ARGB fill_argb, FX_ARGB stroke_argb, CFX_PathData* pClippingPath, int nFlag) { CPDF_CharPosList CharPosList; CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); if (CharPosList.m_nChars == 0) return true; bool bDraw = true; int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition; uint32_t startIndex = 0; for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition; if (fontPosition == curFontPosition) continue; auto* font = fontPosition == -1 ? &pFont->m_Font : pFont->m_FontFallbacks[fontPosition].get(); if (!pDevice->DrawTextPath(i - startIndex, CharPosList.m_pCharPos + startIndex, font, font_size, pText2User, pUser2Device, pGraphState, fill_argb, stroke_argb, pClippingPath, nFlag)) { bDraw = false; } fontPosition = curFontPosition; startIndex = i; } auto* font = fontPosition == -1 ? &pFont->m_Font : pFont->m_FontFallbacks[fontPosition].get(); if (!pDevice->DrawTextPath(CharPosList.m_nChars - startIndex, CharPosList.m_pCharPos + startIndex, font, font_size, pText2User, pUser2Device, pGraphState, fill_argb, stroke_argb, pClippingPath, nFlag)) { bDraw = false; } return bDraw; }
FX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device, FX_ARGB fill_argb, const CPDF_RenderOptions* pOptions) { CFX_FontCache* pCache = pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() : NULL; CPDF_CharPosList CharPosList; CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); int FXGE_flags = 0; if (pOptions) { FX_DWORD dwFlags = pOptions->m_Flags; if (dwFlags & RENDER_CLEARTYPE) { FXGE_flags |= FXTEXT_CLEARTYPE; if (dwFlags & RENDER_BGR_STRIPE) { FXGE_flags |= FXTEXT_BGR_STRIPE; } } if (dwFlags & RENDER_NOTEXTSMOOTH) { FXGE_flags |= FXTEXT_NOSMOOTH; } if (dwFlags & RENDER_PRINTGRAPHICTEXT) { FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT; } if (dwFlags & RENDER_NO_NATIVETEXT) { FXGE_flags |= FXTEXT_NO_NATIVETEXT; } if (dwFlags & RENDER_PRINTIMAGETEXT) { FXGE_flags |= FXTEXT_PRINTIMAGETEXT; } } else { FXGE_flags = FXTEXT_CLEARTYPE; } if (pFont->GetFontType() & PDFFONT_CIDFONT) { FXGE_flags |= FXFONT_CIDFONT; } return pDevice->DrawNormalText(CharPosList.m_nChars, CharPosList.m_pCharPos, &pFont->m_Font, pCache, font_size, pText2Device, fill_argb, FXGE_flags); }
// static bool CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, int nChars, uint32_t* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_Matrix* pText2Device, FX_ARGB fill_argb, const CPDF_RenderOptions* pOptions) { CPDF_CharPosList CharPosList; CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); if (CharPosList.m_nChars == 0) return true; int FXGE_flags = 0; if (pOptions) { uint32_t dwFlags = pOptions->m_Flags; if (dwFlags & RENDER_CLEARTYPE) { FXGE_flags |= FXTEXT_CLEARTYPE; if (dwFlags & RENDER_BGR_STRIPE) { FXGE_flags |= FXTEXT_BGR_STRIPE; } } if (dwFlags & RENDER_NOTEXTSMOOTH) { FXGE_flags |= FXTEXT_NOSMOOTH; } if (dwFlags & RENDER_PRINTGRAPHICTEXT) { FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT; } if (dwFlags & RENDER_NO_NATIVETEXT) { FXGE_flags |= FXTEXT_NO_NATIVETEXT; } if (dwFlags & RENDER_PRINTIMAGETEXT) { FXGE_flags |= FXTEXT_PRINTIMAGETEXT; } } else { FXGE_flags = FXTEXT_CLEARTYPE; } if (pFont->IsCIDFont()) { FXGE_flags |= FXFONT_CIDFONT; } bool bDraw = true; int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition; uint32_t startIndex = 0; for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition; if (fontPosition == curFontPosition) continue; auto* font = fontPosition == -1 ? &pFont->m_Font : pFont->m_FontFallbacks[fontPosition].get(); if (!pDevice->DrawNormalText( i - startIndex, CharPosList.m_pCharPos + startIndex, font, font_size, pText2Device, fill_argb, FXGE_flags)) { bDraw = false; } fontPosition = curFontPosition; startIndex = i; } auto* font = fontPosition == -1 ? &pFont->m_Font : pFont->m_FontFallbacks[fontPosition].get(); if (!pDevice->DrawNormalText(CharPosList.m_nChars - startIndex, CharPosList.m_pCharPos + startIndex, font, font_size, pText2Device, fill_argb, FXGE_flags)) { bDraw = false; } return bDraw; }