void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const { pInfo->m_CharCode = m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[index]; pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0; pInfo->m_OriginY = 0; if (pInfo->m_CharCode == -1) { return; } CPDF_Font* pFont = m_TextState.GetFont(); if (pFont->GetFontType() != PDFFONT_CIDFONT) { return; } if (!((CPDF_CIDFont*)pFont)->IsVertWriting()) { return; } FX_WORD CID = ((CPDF_CIDFont*)pFont)->CIDFromCharCode(pInfo->m_CharCode); pInfo->m_OriginY = pInfo->m_OriginX; pInfo->m_OriginX = 0; short vx, vy; ((CPDF_CIDFont*)pFont)->GetVertOrigin(CID, vx, vy); FX_FLOAT fontsize = m_TextState.GetFontSize(); pInfo->m_OriginX -= fontsize * vx / 1000; pInfo->m_OriginY -= fontsize * vy / 1000; }
CPDF_Font* CPDF_DocPageData::GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding) { if (fontName.IsEmpty()) { return NULL; } FX_POSITION pos = m_FontMap.GetStartPosition(); while (pos) { CPDF_Dictionary* fontDict; CPDF_CountedObject<CPDF_Font*>* fontData; m_FontMap.GetNextAssoc(pos, fontDict, fontData); CPDF_Font* pFont = fontData->m_Obj; if (!pFont) { continue; } if (pFont->GetBaseFont() != fontName) { continue; } if (pFont->IsEmbedded()) { continue; } if (pFont->GetFontType() != PDFFONT_TYPE1) { continue; } if (pFont->GetFontDict()->KeyExist(FX_BSTRC("Widths"))) { continue; } CPDF_Type1Font* pT1Font = pFont->GetType1Font(); if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) { continue; } fontData->m_nCount ++; return pFont; } CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font")); pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1")); pDict->SetAtName(FX_BSTRC("BaseFont"), fontName); if (pEncoding) { pDict->SetAt(FX_BSTRC("Encoding"), pEncoding->Realize()); } m_pPDFDoc->AddIndirectObject(pDict); CPDF_CountedObject<CPDF_Font*>* fontData = FX_NEW CPDF_CountedObject<CPDF_Font*>; if (!fontData) { return NULL; } CPDF_Font* pFont = CPDF_Font::CreateFontF(m_pPDFDoc, pDict); if (!pFont) { delete fontData; return NULL; } fontData->m_nCount = 2; fontData->m_Obj = pFont; m_FontMap.SetAt(pDict, fontData); return pFont; }
FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, CFX_PathData* pClippingPath) { if(textobj->m_nChars == 0) { return TRUE; } int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode; if (text_render_mode == 3) { return TRUE; } CPDF_Font* pFont = textobj->m_TextState.GetFont(); if (pFont->GetFontType() == PDFFONT_TYPE3) { return ProcessType3Text(textobj, pObj2Device); } FX_BOOL bFill = FALSE, bStroke = FALSE, bClip = FALSE; if (pClippingPath) { bClip = TRUE; } else { switch (text_render_mode) { case 0: case 4: bFill = TRUE; break; case 1: case 5: if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { bFill = TRUE; } else { bStroke = TRUE; } break; case 2: case 6: if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { bFill = TRUE; } else { bFill = bStroke = TRUE; } break; case 3: case 7: return TRUE; default: bFill = TRUE; } } FX_ARGB stroke_argb = 0, fill_argb = 0; FX_BOOL bPattern = FALSE; if (bStroke) { if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) { bPattern = TRUE; } else { stroke_argb = GetStrokeArgb(textobj); } } if (bFill) { if (textobj->m_ColorState.GetFillColor()->IsPattern()) { bPattern = TRUE; } else { fill_argb = GetFillArgb(textobj); } } CFX_AffineMatrix text_matrix; textobj->GetTextMatrix(&text_matrix); if(IsAvailableMatrix(text_matrix) == FALSE) { return TRUE; } FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); if (bPattern) { DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, &text_matrix, bFill, bStroke); return TRUE; } #if defined(_FPDFAPI_MINI_) if (bFill) { bStroke = FALSE; } if (bStroke) { if (font_size * text_matrix.GetXUnit() * pObj2Device->GetXUnit() < 6) { bStroke = FALSE; } } #endif if (bClip || bStroke) { const CFX_AffineMatrix* pDeviceMatrix = pObj2Device; CFX_AffineMatrix device_matrix; if (bStroke) { const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM; if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { CFX_AffineMatrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); text_matrix.ConcatInverse(ctm); device_matrix.Copy(ctm); device_matrix.Concat(*pObj2Device); pDeviceMatrix = &device_matrix; } } int flag = 0; if (bStroke && bFill) { flag |= FX_FILL_STROKE; flag |= FX_STROKE_TEXT_MODE; } #if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)textobj)->m_GeneralState; if (pGeneralData && pGeneralData->m_StrokeAdjust) { flag |= FX_STROKE_ADJUST; } #endif if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) { flag |= FXFILL_NOPATHSMOOTH; } return CPDF_TextRenderer::DrawTextPath(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, &text_matrix, pDeviceMatrix, textobj->m_GraphState, fill_argb, stroke_argb, pClippingPath, flag); } text_matrix.Concat(*pObj2Device); return CPDF_TextRenderer::DrawNormalText(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, &text_matrix, fill_argb, &m_Options); }
void CPDF_ProgressiveReflowPageRender::Display(IFX_Pause* pPause) { if (NULL == m_pReflowPage) { m_Status = Done; return; } FX_RECT clipBox = m_pFXDevice->GetClipBox(); int size = m_pReflowPage->m_pReflowed->GetSize(); if (size < 1 || NULL == m_pDisplayMatrix) { m_Status = Done; return; } for(int i = m_CurrNum; i < size; i++) { CRF_Data* pData = (*m_pReflowPage->m_pReflowed)[i]; if(!pData) { continue; } CFX_FloatRect rect (pData->m_PosX, pData->m_PosY + pData->m_Height, pData->m_PosX + pData->m_Width, pData->m_PosY); m_pDisplayMatrix->TransformRect(rect); if(rect.left > clipBox.right || rect.right < clipBox.left || rect.bottom > clipBox.bottom || rect.top < clipBox.top) { continue; } if(pData->GetType() == CRF_Data::Text) { CRF_CharData* pCharData = (CRF_CharData*)pData; CPDF_Font* pPDFFont = pCharData->m_pCharState->m_pFont; if(pPDFFont->GetFontType() == PDFFONT_TYPE3) { continue; } FX_FLOAT x = pData->m_PosX, y = pData->m_PosY - pCharData->m_pCharState->m_fDescent; FXTEXT_CHARPOS charpos ; charpos.m_GlyphIndex = pPDFFont->GlyphFromCharCode(pCharData->m_CharCode); charpos.m_FontCharWidth = pPDFFont->m_Font.GetGlyphWidth(charpos.m_GlyphIndex); charpos.m_OriginX = x; charpos.m_OriginY = y; FX_FLOAT charW = pData->m_Width * 1000 / pData->m_Height; if(charW != charpos.m_FontCharWidth) { charpos.m_bGlyphAdjust = TRUE; charpos.m_AdjustMatrix[0] = charW / charpos.m_FontCharWidth; charpos.m_AdjustMatrix[1] = 0; charpos.m_AdjustMatrix[2] = 0; charpos.m_AdjustMatrix[3] = 1; } else { charpos.m_bGlyphAdjust = FALSE; } FX_BOOL bRet = FALSE; if(m_DisplayColor == -1) bRet = m_pFXDevice->DrawNormalText(1, &charpos, &(pPDFFont->m_Font), NULL, pCharData->m_pCharState->m_fFontSize, m_pDisplayMatrix, pCharData->m_pCharState->m_Color + 0xff000000, FXTEXT_CLEARTYPE); else bRet = m_pFXDevice->DrawNormalText(1, &charpos, &(pPDFFont->m_Font), NULL, pCharData->m_pCharState->m_fFontSize, m_pDisplayMatrix, m_DisplayColor, FXTEXT_CLEARTYPE); } else if(pData->GetType() == CRF_Data::Image) { CRF_ImageData* pImageData = (CRF_ImageData*)pData; if(!pImageData->m_pBitmap) { continue; } int left = 0, top = 0; CFX_DIBitmap* pDiBmp = NULL; CFX_DIBSource* pDispSource = pImageData->m_pBitmap; if(pImageData->m_Matrix.d < 0) { CFX_AffineMatrix matrix(pImageData->m_Matrix.a, 0, 0, -pImageData->m_Matrix.d, 0, 0); int left, top; pDiBmp = pImageData->m_pBitmap->TransformTo(&matrix, left, top); pDispSource = pDiBmp; } if (NULL == pDispSource) { continue; } if (pDispSource->GetFormat() == FXDIB_1bppMask || pDispSource->GetFormat() == FXDIB_8bppMask) { m_pFXDevice->StretchBitMask(pDispSource, (int)(rect.left + 0.5), (int)(rect.bottom + 0.5), (int)(rect.Width() + 0.5), (int)(rect.Height() + 0.5), 0xff000000); } else { m_pFXDevice->StretchDIBits(pDispSource, (int)(rect.left + 0.5), (int)(rect.bottom + 0.5), (int)(rect.Width() + 0.5), (int)(rect.Height() + 0.5)); } if(m_pFXDevice->GetBitmap() && m_pFXDevice->GetBitmap()->GetFormat() == FXDIB_8bppRgb && m_pFXDevice->GetBitmap()->GetPalette() == NULL) { int nPalette = 0; switch(m_DitherBits) { case 0: nPalette = 0; break; case 1: nPalette = 2; break; case 2: nPalette = 4; break; case 3: nPalette = 8; break; case 4: nPalette = 16; break; case 5: nPalette = 32; break; case 6: nPalette = 64; break; case 7: nPalette = 128; break; default: nPalette = 256; break; } if(nPalette >= 2) { FX_ARGB * palette = FX_Alloc(FX_ARGB, nPalette); nPalette --; palette[0] = 0; palette[nPalette] = 255; FX_FLOAT Dither = (FX_FLOAT)255 / (nPalette); for(int i = 1; i < nPalette; i++) { palette[i] = (FX_ARGB)(Dither * i + 0.5); } FX_RECT tmpRect = rect.GetOutterRect(); m_pFXDevice->GetBitmap()->DitherFS(palette, nPalette + 1, &tmpRect); FX_Free (palette); } } if(pDiBmp) { delete pDiBmp; } } else if(pData->GetType() == CRF_Data::Path) { } if(!(i % 10)) { if(pPause && pPause->NeedToPauseNow()) { i++; m_CurrNum = i; m_Status = ToBeContinued; return; } } } m_CurrNum = size; m_Status = Done; }
void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, FX_FLOAT fInitKerning, FX_FLOAT* pKerning, int nsegs) { CPDF_Font* pFont = m_pCurStates->m_TextState.GetFont(); if (!pFont) { return; } if (fInitKerning != 0) { if (!pFont->IsVertWriting()) { m_pCurStates->m_TextX -= FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1000; } else { m_pCurStates->m_TextY -= FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1000; } } if (nsegs == 0) { return; } int textmode; if (pFont->GetFontType() == PDFFONT_TYPE3) { textmode = 0; } else { textmode = m_pCurStates->m_TextState.GetObject()->m_TextMode; } CPDF_TextObject* pText = new CPDF_TextObject; m_pLastTextObject = pText; SetGraphicStates(pText, TRUE, TRUE, TRUE); if (textmode && textmode != 3 && textmode != 4 && textmode != 7) { FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM; pCTM[0] = m_pCurStates->m_CTM.a; pCTM[1] = m_pCurStates->m_CTM.c; pCTM[2] = m_pCurStates->m_CTM.b; pCTM[3] = m_pCurStates->m_CTM.d; } pText->SetSegments(pStrs, pKerning, nsegs); pText->m_PosX = m_pCurStates->m_TextX; pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise; ConvertTextSpace(pText->m_PosX, pText->m_PosY); FX_FLOAT x_advance, y_advance; pText->CalcPositionData(&x_advance, &y_advance, m_pCurStates->m_TextHorzScale, m_Level); m_pCurStates->m_TextX += x_advance; m_pCurStates->m_TextY += y_advance; if (textmode > 3) { CPDF_TextObject* pCopy = new CPDF_TextObject; pCopy->Copy(pText); m_ClipTextList.Add(pCopy); } m_pObjectList->m_ObjectList.AddTail(pText); if (pKerning && pKerning[nsegs - 1] != 0) { if (!pFont->IsVertWriting()) { m_pCurStates->m_TextX -= FXSYS_Mul(pKerning[nsegs - 1], m_pCurStates->m_TextState.GetFontSize()) / 1000; } else { m_pCurStates->m_TextY -= FXSYS_Mul(pKerning[nsegs - 1], m_pCurStates->m_TextState.GetFontSize()) / 1000; } } }