static int InsertNewPage(CPDF_Document* pDoc, int iPage, CPDF_Dictionary* pPageDict, CFX_DWordArray &pageList) { CPDF_Dictionary* pRoot = pDoc->GetRoot(); if (!pRoot) { return -1; } CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); if (!pPages) { return -1; } int nPages = pDoc->GetPageCount(); if (iPage < 0 || iPage > nPages) { return -1; } if (iPage == nPages) { CPDF_Array* pPagesList = pPages->GetArray(FX_BSTRC("Kids")); if (!pPagesList) { pPagesList = FX_NEW CPDF_Array; pPages->SetAt(FX_BSTRC("Kids"), pPagesList); } pPagesList->Add(pPageDict, pDoc); pPages->SetAtInteger(FX_BSTRC("Count"), nPages + 1); pPageDict->SetAtReference(FX_BSTRC("Parent"), pDoc, pPages->GetObjNum()); } else { CFX_PtrArray stack; stack.Add(pPages); if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, stack) < 0) { return -1; } } pageList.InsertAt(iPage, pPageDict->GetObjNum()); return iPage; }
CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, FX_DWORD size) { int32_t width; int32_t height; int32_t num_comps; int32_t bits; FX_BOOL color_trans; if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo( pData, size, width, height, num_comps, bits, color_trans)) { return NULL; } CPDF_Dictionary* pDict = new CPDF_Dictionary; pDict->SetAtName("Type", "XObject"); pDict->SetAtName("Subtype", "Image"); pDict->SetAtInteger("Width", width); pDict->SetAtInteger("Height", height); const FX_CHAR* csname = NULL; if (num_comps == 1) { csname = "DeviceGray"; } else if (num_comps == 3) { csname = "DeviceRGB"; } else if (num_comps == 4) { csname = "DeviceCMYK"; CPDF_Array* pDecode = new CPDF_Array; for (int n = 0; n < 4; n++) { pDecode->AddInteger(1); pDecode->AddInteger(0); } pDict->SetAt("Decode", pDecode); } pDict->SetAtName("ColorSpace", csname); pDict->SetAtInteger("BitsPerComponent", bits); pDict->SetAtName("Filter", "DCTDecode"); if (!color_trans) { CPDF_Dictionary* pParms = new CPDF_Dictionary; pDict->SetAt("DecodeParms", pParms); pParms->SetAtInteger("ColorTransform", 0); } m_bIsMask = FALSE; m_Width = width; m_Height = height; if (!m_pStream) { m_pStream = new CPDF_Stream(NULL, 0, NULL); } return pDict; }
void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox, const CFX_Matrix& matrix, const CFX_ByteString& sContents, const CFX_ByteString& sAPState) { CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP"); if (!pAPDict) { pAPDict = new CPDF_Dictionary; m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict); } CPDF_Stream* pStream = nullptr; CPDF_Dictionary* pParentDict = nullptr; if (sAPState.IsEmpty()) { pParentDict = pAPDict; pStream = pAPDict->GetStreamBy(sAPType); } else { CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictBy(sAPType); if (!pAPTypeDict) { pAPTypeDict = new CPDF_Dictionary; pAPDict->SetAt(sAPType, pAPTypeDict); } pParentDict = pAPTypeDict; pStream = pAPTypeDict->GetStreamBy(sAPState); } if (!pStream) { pStream = new CPDF_Stream(nullptr, 0, nullptr); CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); int32_t objnum = pDoc->AddIndirectObject(pStream); pParentDict->SetAtReference(sAPType, pDoc, objnum); } CPDF_Dictionary* pStreamDict = pStream->GetDict(); if (!pStreamDict) { pStreamDict = new CPDF_Dictionary; pStreamDict->SetAtName("Type", "XObject"); pStreamDict->SetAtName("Subtype", "Form"); pStreamDict->SetAtInteger("FormType", 1); pStream->InitStream(nullptr, 0, pStreamDict); } if (pStreamDict) { pStreamDict->SetAtMatrix("Matrix", matrix); pStreamDict->SetAtRect("BBox", rcBBox); } pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), FALSE, FALSE); }
// border void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) { CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border"); if (pBorder) { pBorder->SetAt(2, new CPDF_Number(nWidth)); } else { CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS"); if (!pBSDict) { pBSDict = new CPDF_Dictionary; m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict); } pBSDict->SetAtInteger("W", nWidth); } }
//border void CPDFSDK_Annot::SetBorderWidth(int nWidth) { ASSERT(m_pAnnot != NULL); ASSERT(m_pAnnot->m_pAnnotDict != NULL); CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border"); if (pBorder) { pBorder->SetAt(2, FX_NEW CPDF_Number(nWidth)); } else { CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS"); if (!pBSDict) { pBSDict = FX_NEW CPDF_Dictionary; m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict); } pBSDict->SetAtInteger("W", nWidth); } }
void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress, IFX_FileWrite* pFileWrite, IFX_FileRead* pFileRead, const CFX_DIBitmap* pMask, const CPDF_ImageSetParam* pParam) { int32_t BitmapWidth = pBitmap->GetWidth(); int32_t BitmapHeight = pBitmap->GetHeight(); if (BitmapWidth < 1 || BitmapHeight < 1) { return; } uint8_t* src_buf = pBitmap->GetBuffer(); int32_t src_pitch = pBitmap->GetPitch(); int32_t bpp = pBitmap->GetBPP(); FX_BOOL bUseMatte = pParam && pParam->pMatteColor && (pBitmap->GetFormat() == FXDIB_Argb); CPDF_Dictionary* pDict = new CPDF_Dictionary; pDict->SetAtName("Type", "XObject"); pDict->SetAtName("Subtype", "Image"); pDict->SetAtInteger("Width", BitmapWidth); pDict->SetAtInteger("Height", BitmapHeight); uint8_t* dest_buf = NULL; FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; if (bpp == 1) { int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0; if (!pBitmap->IsAlphaMask()) { ArgbDecode(pBitmap->GetPaletteArgb(0), reset_a, reset_r, reset_g, reset_b); ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b); } if (set_a == 0 || reset_a == 0) { pDict->SetAt("ImageMask", new CPDF_Boolean(TRUE)); if (reset_a == 0) { CPDF_Array* pArray = new CPDF_Array; pArray->AddInteger(1); pArray->AddInteger(0); pDict->SetAt("Decode", pArray); } } else { CPDF_Array* pCS = new CPDF_Array; pCS->AddName("Indexed"); pCS->AddName("DeviceRGB"); pCS->AddInteger(1); CFX_ByteString ct; FX_CHAR* pBuf = ct.GetBuffer(6); pBuf[0] = (FX_CHAR)reset_r; pBuf[1] = (FX_CHAR)reset_g; pBuf[2] = (FX_CHAR)reset_b; pBuf[3] = (FX_CHAR)set_r; pBuf[4] = (FX_CHAR)set_g; pBuf[5] = (FX_CHAR)set_b; ct.ReleaseBuffer(6); pCS->Add(new CPDF_String(ct, TRUE)); pDict->SetAt("ColorSpace", pCS); } pDict->SetAtInteger("BitsPerComponent", 1); dest_pitch = (BitmapWidth + 7) / 8; if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { opType = 1; } else { opType = 0; } } else if (bpp == 8) { int32_t iPalette = pBitmap->GetPaletteSize(); if (iPalette > 0) { CPDF_Array* pCS = new CPDF_Array; m_pDocument->AddIndirectObject(pCS); pCS->AddName("Indexed"); pCS->AddName("DeviceRGB"); pCS->AddInteger(iPalette - 1); uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3); uint8_t* ptr = pColorTable; for (int32_t i = 0; i < iPalette; i++) { FX_DWORD argb = pBitmap->GetPaletteArgb(i); ptr[0] = (uint8_t)(argb >> 16); ptr[1] = (uint8_t)(argb >> 8); ptr[2] = (uint8_t)argb; ptr += 3; } CPDF_Stream* pCTS = new CPDF_Stream(pColorTable, iPalette * 3, new CPDF_Dictionary); m_pDocument->AddIndirectObject(pCTS); pCS->AddReference(m_pDocument, pCTS); pDict->SetAtReference("ColorSpace", m_pDocument, pCS); } else {
CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { if (pFont == NULL) { return NULL; } FX_BOOL bCJK = charset == FXFONT_CHINESEBIG5_CHARSET || charset == FXFONT_GB2312_CHARSET || charset == FXFONT_HANGEUL_CHARSET || charset == FXFONT_SHIFTJIS_CHARSET; CFX_ByteString basefont = pFont->GetFamilyName(); basefont.Replace(" ", ""); int flags = 0; if (pFont->IsBold()) { flags |= PDFFONT_FORCEBOLD; } if (pFont->IsItalic()) { flags |= PDFFONT_ITALIC; } if (pFont->IsFixedWidth()) { flags |= PDFFONT_FIXEDPITCH; } CPDF_Dictionary* pBaseDict = FX_NEW CPDF_Dictionary; pBaseDict->SetAtName("Type", "Font"); IFX_FontEncoding* pEncoding = FXGE_CreateUnicodeEncoding(pFont); CPDF_Dictionary* pFontDict = pBaseDict; if (!bCJK) { CPDF_Array* pWidths = FX_NEW CPDF_Array; int charcode; for (charcode = 32; charcode < 128; charcode ++) { int glyph_index = pEncoding->GlyphFromCharCode(charcode); int char_width = pFont->GetGlyphWidth(glyph_index); pWidths->AddInteger(char_width); } if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET || charset == FXFONT_SYMBOL_CHARSET) { if (charset == FXFONT_SYMBOL_CHARSET) { flags |= PDFFONT_SYMBOLIC; } else { flags |= PDFFONT_NONSYMBOLIC; } pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding"); for (charcode = 128; charcode <= 255; charcode ++) { int glyph_index = pEncoding->GlyphFromCharCode(charcode); int char_width = pFont->GetGlyphWidth(glyph_index); pWidths->AddInteger(char_width); } } else { flags |= PDFFONT_NONSYMBOLIC; int i; for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes); i ++) if (g_FX_CharsetUnicodes[i].m_Charset == charset) { break; } if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) { CPDF_Dictionary* pEncodingDict = FX_NEW CPDF_Dictionary; pEncodingDict->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding"); CPDF_Array* pArray = FX_NEW CPDF_Array; pArray->AddInteger(128); const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; for (int j = 0; j < 128; j ++) { CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); if (name.IsEmpty()) { pArray->AddName(FX_BSTRC(".notdef")); } else { pArray->AddName(name); } int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]); int char_width = pFont->GetGlyphWidth(glyph_index); pWidths->AddInteger(char_width); } pEncodingDict->SetAt(FX_BSTRC("Differences"), pArray); AddIndirectObject(pEncodingDict); pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncodingDict); } } if (pFont->IsBold() && pFont->IsItalic()) { basefont += ",BoldItalic"; } else if (pFont->IsBold()) { basefont += ",Bold"; } else if (pFont->IsItalic()) { basefont += ",Italic"; } pBaseDict->SetAtName("Subtype", "TrueType"); pBaseDict->SetAtName("BaseFont", basefont); pBaseDict->SetAtNumber("FirstChar", 32); pBaseDict->SetAtNumber("LastChar", 255); pBaseDict->SetAt("Widths", pWidths); } else { flags |= PDFFONT_NONSYMBOLIC; pFontDict = FX_NEW CPDF_Dictionary; CFX_ByteString cmap; CFX_ByteString ordering; int supplement; CPDF_Array* pWidthArray = FX_NEW CPDF_Array; switch (charset) { case FXFONT_CHINESEBIG5_CHARSET: cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; ordering = "CNS1"; supplement = 4; pWidthArray->AddInteger(1); _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7e, pWidthArray); break; case FXFONT_GB2312_CHARSET: cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H"; ordering = "GB1", supplement = 2; pWidthArray->AddInteger(7716); _InsertWidthArray1(pFont, pEncoding, 0x20, 0x20, pWidthArray); pWidthArray->AddInteger(814); _InsertWidthArray1(pFont, pEncoding, 0x21, 0x7e, pWidthArray); break; case FXFONT_HANGEUL_CHARSET: cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H"; ordering = "Korea1"; supplement = 2; pWidthArray->AddInteger(1); _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7e, pWidthArray); break; case FXFONT_SHIFTJIS_CHARSET: cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H"; ordering = "Japan1"; supplement = 5; pWidthArray->AddInteger(231); _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7d, pWidthArray); pWidthArray->AddInteger(326); _InsertWidthArray1(pFont, pEncoding, 0xa0, 0xa0, pWidthArray); pWidthArray->AddInteger(327); _InsertWidthArray1(pFont, pEncoding, 0xa1, 0xdf, pWidthArray); pWidthArray->AddInteger(631); _InsertWidthArray1(pFont, pEncoding, 0x7e, 0x7e, pWidthArray); break; } pBaseDict->SetAtName("Subtype", "Type0"); pBaseDict->SetAtName("BaseFont", basefont); pBaseDict->SetAtName("Encoding", cmap); pFontDict->SetAt("W", pWidthArray); pFontDict->SetAtName("Type", "Font"); pFontDict->SetAtName("Subtype", "CIDFontType2"); pFontDict->SetAtName("BaseFont", basefont); CPDF_Dictionary* pCIDSysInfo = FX_NEW CPDF_Dictionary; pCIDSysInfo->SetAtString("Registry", "Adobe"); pCIDSysInfo->SetAtString("Ordering", ordering); pCIDSysInfo->SetAtInteger("Supplement", supplement); pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo); CPDF_Array* pArray = FX_NEW CPDF_Array; pBaseDict->SetAt("DescendantFonts", pArray); AddIndirectObject(pFontDict); pArray->AddReference(this, pFontDict); } AddIndirectObject(pBaseDict); CPDF_Dictionary* pFontDesc = FX_NEW CPDF_Dictionary; pFontDesc->SetAtName("Type", "FontDescriptor"); pFontDesc->SetAtName("FontName", basefont); pFontDesc->SetAtInteger("Flags", flags); pFontDesc->SetAtInteger("ItalicAngle", pFont->m_pSubstFont ? pFont->m_pSubstFont->m_ItalicAngle : 0); pFontDesc->SetAtInteger("Ascent", pFont->GetAscent()); pFontDesc->SetAtInteger("Descent", pFont->GetDescent()); FX_RECT bbox; pFont->GetBBox(bbox); CPDF_Array* pBBox = FX_NEW CPDF_Array; pBBox->AddInteger(bbox.left); pBBox->AddInteger(bbox.bottom); pBBox->AddInteger(bbox.right); pBBox->AddInteger(bbox.top); pFontDesc->SetAt("FontBBox", pBBox); FX_INT32 nStemV = 0; if (pFont->m_pSubstFont) { nStemV = pFont->m_pSubstFont->m_Weight / 5; } else { static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'}; const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]); FX_DWORD glyph = pEncoding->GlyphFromCharCode(stem_chars[0]); nStemV = pFont->GetGlyphWidth(glyph); for (size_t i = 1; i < count; i++) { glyph = pEncoding->GlyphFromCharCode(stem_chars[i]); int width = pFont->GetGlyphWidth(glyph); if (width > 0 && width < nStemV) { nStemV = width; } } } if (pEncoding) { delete pEncoding; } pFontDesc->SetAtInteger("StemV", nStemV); AddIndirectObject(pFontDesc); pFontDict->SetAtReference("FontDescriptor", this, pFontDesc); return LoadFont(pBaseDict); }
CPDF_Font* CPDF_Document::AddMacFont(CTFontRef pFont, FX_BOOL bVert, FX_BOOL bTranslateName) { CTFontRef font = (CTFontRef)pFont; CTFontDescriptorRef descriptor = CTFontCopyFontDescriptor(font); if (descriptor == NULL) { return NULL; } CFX_ByteString basefont; FX_BOOL bCJK = FALSE; int flags = 0, italicangle = 0, ascend = 0, descend = 0, capheight = 0, bbox[4]; FXSYS_memset32(bbox, 0, sizeof(int) * 4); CFArrayRef languages = (CFArrayRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontLanguagesAttribute); if (languages == NULL) { CFRelease(descriptor); return NULL; } CFX_DWordArray charSets; charSets.Add(FXFONT_CHINESEBIG5_CHARSET); charSets.Add(FXFONT_GB2312_CHARSET); charSets.Add(FXFONT_HANGEUL_CHARSET); charSets.Add(FXFONT_SHIFTJIS_CHARSET); if (IsHasCharSet(languages, charSets)) { bCJK = TRUE; } CFRelease(descriptor); CFDictionaryRef traits = (CFDictionaryRef)CTFontCopyTraits(font); if (traits == NULL) { CFRelease(languages); return NULL; } CFNumberRef sybolicTrait = (CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait); CTFontSymbolicTraits trait = 0; CFNumberGetValue(sybolicTrait, kCFNumberSInt32Type, &trait); if (trait & kCTFontItalicTrait) { flags |= PDFFONT_ITALIC; } if (trait & kCTFontMonoSpaceTrait) { flags |= PDFFONT_FIXEDPITCH; } if (trait & kCTFontModernSerifsClass) { flags |= PDFFONT_SERIF; } if (trait & kCTFontScriptsClass) { flags |= PDFFONT_SCRIPT; } CFNumberRef weightTrait = (CFNumberRef)CFDictionaryGetValue(traits, kCTFontWeightTrait); Float32 weight = 0; CFNumberGetValue(weightTrait, kCFNumberFloat32Type, &weight); italicangle = CTFontGetSlantAngle(font); ascend = CTFontGetAscent(font); descend = CTFontGetDescent(font); capheight = CTFontGetCapHeight(font); CGRect box = CTFontGetBoundingBox(font); bbox[0] = box.origin.x; bbox[1] = box.origin.y; bbox[2] = box.origin.x + box.size.width; bbox[3] = box.origin.y + box.size.height; if (bTranslateName && bCJK) { CFStringRef postName = CTFontCopyPostScriptName(font); _CFString2CFXByteString(postName, basefont); CFRelease(postName); } if (basefont.IsEmpty()) { CFStringRef fullName = CTFontCopyFullName(font); _CFString2CFXByteString(fullName, basefont); CFRelease(fullName); } basefont.Replace(" ", ""); CPDF_Dictionary* pFontDict = NULL; CPDF_Dictionary* pBaseDict = FX_NEW CPDF_Dictionary; pFontDict = pBaseDict; if (!bCJK) { charSets.RemoveAll(); charSets.Add(FXFONT_ANSI_CHARSET); charSets.Add(FXFONT_DEFAULT_CHARSET); charSets.Add(FXFONT_SYMBOL_CHARSET); if (IsHasCharSet(languages, charSets)) { charSets.RemoveAll(); charSets.Add(FXFONT_SYMBOL_CHARSET); if (IsHasCharSet(languages, charSets)) { flags |= PDFFONT_SYMBOLIC; } else { flags |= PDFFONT_NONSYMBOLIC; } pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding"); } else { flags |= PDFFONT_NONSYMBOLIC; int i; for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes); i ++) { charSets.RemoveAll(); charSets.Add(g_FX_CharsetUnicodes[i].m_Charset); if (IsHasCharSet(languages, charSets)) { break; } } if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) { CPDF_Dictionary* pEncoding = FX_NEW CPDF_Dictionary; pEncoding->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding"); CPDF_Array* pArray = FX_NEW CPDF_Array; pArray->AddInteger(128); const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; for (int j = 0; j < 128; j ++) { CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); if (name.IsEmpty()) { pArray->AddName(FX_BSTRC(".notdef")); } else { pArray->AddName(name); } } pEncoding->SetAt(FX_BSTRC("Differences"), pArray); AddIndirectObject(pEncoding); pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncoding); } } if (weight > 0.0 && trait & kCTFontItalicTrait) { basefont += ",BoldItalic"; } else if (weight > 0.0) { basefont += ",Bold"; } else if (trait & kCTFontItalicTrait) { basefont += ",Italic"; } pBaseDict->SetAtName("Subtype", "TrueType"); pBaseDict->SetAtName("BaseFont", basefont); pBaseDict->SetAtNumber("FirstChar", 32); pBaseDict->SetAtNumber("LastChar", 255); int char_widths[224]; FX_GetCharWidth(font, 32, 255, char_widths); CPDF_Array* pWidths = FX_NEW CPDF_Array; for (int i = 0; i < 224; i ++) { pWidths->AddInteger(char_widths[i]); } pBaseDict->SetAt("Widths", pWidths); } else { flags |= PDFFONT_NONSYMBOLIC; CPDF_Array* pArray = NULL; pFontDict = FX_NEW CPDF_Dictionary; CFX_ByteString cmap; CFX_ByteString ordering; int supplement; FX_BOOL bFound = FALSE; CPDF_Array* pWidthArray = FX_NEW CPDF_Array; charSets.RemoveAll(); charSets.Add(FXFONT_CHINESEBIG5_CHARSET); if (IsHasCharSet(languages, charSets)) { cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; ordering = "CNS1"; supplement = 4; pWidthArray->AddInteger(1); _InsertWidthArray(font, 0x20, 0x7e, pWidthArray); bFound = TRUE; } charSets.RemoveAll(); charSets.Add(FXFONT_GB2312_CHARSET); if (!bFound && IsHasCharSet(languages, charSets)) { cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H"; ordering = "GB1", supplement = 2; pWidthArray->AddInteger(7716); _InsertWidthArray(font, 0x20, 0x20, pWidthArray); pWidthArray->AddInteger(814); _InsertWidthArray(font, 0x21, 0x7e, pWidthArray); bFound = TRUE; } charSets.RemoveAll(); charSets.Add(FXFONT_HANGEUL_CHARSET); if (!bFound && IsHasCharSet(languages, charSets)) { cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H"; ordering = "Korea1"; supplement = 2; pWidthArray->AddInteger(1); _InsertWidthArray(font, 0x20, 0x7e, pWidthArray); bFound = TRUE; } charSets.RemoveAll(); charSets.Add(FXFONT_SHIFTJIS_CHARSET); if (!bFound && IsHasCharSet(languages, charSets)) { cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H"; ordering = "Japan1"; supplement = 5; pWidthArray->AddInteger(231); _InsertWidthArray(font, 0x20, 0x7d, pWidthArray); pWidthArray->AddInteger(326); _InsertWidthArray(font, 0xa0, 0xa0, pWidthArray); pWidthArray->AddInteger(327); _InsertWidthArray(font, 0xa1, 0xdf, pWidthArray); pWidthArray->AddInteger(631); _InsertWidthArray(font, 0x7e, 0x7e, pWidthArray); } pBaseDict->SetAtName("Subtype", "Type0"); pBaseDict->SetAtName("BaseFont", basefont); pBaseDict->SetAtName("Encoding", cmap); pFontDict->SetAt("W", pWidthArray); pFontDict->SetAtName("Type", "Font"); pFontDict->SetAtName("Subtype", "CIDFontType2"); pFontDict->SetAtName("BaseFont", basefont); CPDF_Dictionary* pCIDSysInfo = FX_NEW CPDF_Dictionary; pCIDSysInfo->SetAtString("Registry", "Adobe"); pCIDSysInfo->SetAtString("Ordering", ordering); pCIDSysInfo->SetAtInteger("Supplement", supplement); pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo); pArray = FX_NEW CPDF_Array; pBaseDict->SetAt("DescendantFonts", pArray); AddIndirectObject(pFontDict); pArray->AddReference(this, pFontDict); } AddIndirectObject(pBaseDict); CPDF_Dictionary* pFontDesc = FX_NEW CPDF_Dictionary; pFontDesc->SetAtName("Type", "FontDescriptor"); pFontDesc->SetAtName("FontName", basefont); pFontDesc->SetAtInteger("Flags", flags); CPDF_Array* pBBox = FX_NEW CPDF_Array; for (int i = 0; i < 4; i ++) { pBBox->AddInteger(bbox[i]); } pFontDesc->SetAt("FontBBox", pBBox); pFontDesc->SetAtInteger("ItalicAngle", italicangle); pFontDesc->SetAtInteger("Ascent", ascend); pFontDesc->SetAtInteger("Descent", descend); pFontDesc->SetAtInteger("CapHeight", capheight); CGFloat fStemV = 0; int16_t min_width = SHRT_MAX; static const UniChar stem_chars[] = {'i', 'I', '!', '1'}; const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]); CGGlyph glyphs[count]; CGRect boundingRects[count]; if (CTFontGetGlyphsForCharacters(font, stem_chars, glyphs, count)) { CTFontGetBoundingRectsForGlyphs(font, kCTFontHorizontalOrientation, glyphs, boundingRects, count); for (size_t i = 0; i < count; i++) { int16_t width = boundingRects[i].size.width; if (width > 0 && width < min_width) { min_width = width; fStemV = min_width; } } } pFontDesc->SetAtInteger("StemV", fStemV); AddIndirectObject(pFontDesc); pFontDict->SetAtReference("FontDescriptor", this, pFontDesc); CFRelease(traits); CFRelease(languages); return LoadFont(pBaseDict); }
CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, FX_BOOL bVert, FX_BOOL bTranslateName) { pLogFont->lfHeight = -1000; pLogFont->lfWidth = 0; HGDIOBJ hFont = CreateFontIndirectA(pLogFont); HDC hDC = CreateCompatibleDC(NULL); hFont = SelectObject(hDC, hFont); int tm_size = GetOutlineTextMetrics(hDC, 0, NULL); if (tm_size == 0) { hFont = SelectObject(hDC, hFont); DeleteObject(hFont); DeleteDC(hDC); return NULL; } LPBYTE tm_buf = FX_Alloc(BYTE, tm_size); OUTLINETEXTMETRIC* ptm = (OUTLINETEXTMETRIC*)tm_buf; GetOutlineTextMetrics(hDC, tm_size, ptm); int flags = 0, italicangle, ascend, descend, capheight, bbox[4]; if (pLogFont->lfItalic) { flags |= PDFFONT_ITALIC; } if ((pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH) { flags |= PDFFONT_FIXEDPITCH; } if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN) { flags |= PDFFONT_SERIF; } if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT) { flags |= PDFFONT_SCRIPT; } FX_BOOL bCJK = pLogFont->lfCharSet == CHINESEBIG5_CHARSET || pLogFont->lfCharSet == GB2312_CHARSET || pLogFont->lfCharSet == HANGEUL_CHARSET || pLogFont->lfCharSet == SHIFTJIS_CHARSET; CFX_ByteString basefont; if (bTranslateName && bCJK) { basefont = _FPDF_GetPSNameFromTT(hDC); } if (basefont.IsEmpty()) { basefont = pLogFont->lfFaceName; } italicangle = ptm->otmItalicAngle / 10; ascend = ptm->otmrcFontBox.top; descend = ptm->otmrcFontBox.bottom; capheight = ptm->otmsCapEmHeight; bbox[0] = ptm->otmrcFontBox.left; bbox[1] = ptm->otmrcFontBox.bottom; bbox[2] = ptm->otmrcFontBox.right; bbox[3] = ptm->otmrcFontBox.top; FX_Free(tm_buf); basefont.Replace(" ", ""); CPDF_Dictionary* pBaseDict = FX_NEW CPDF_Dictionary; pBaseDict->SetAtName("Type", "Font"); CPDF_Dictionary* pFontDict = pBaseDict; if (!bCJK) { if (pLogFont->lfCharSet == ANSI_CHARSET || pLogFont->lfCharSet == DEFAULT_CHARSET || pLogFont->lfCharSet == SYMBOL_CHARSET) { if (pLogFont->lfCharSet == SYMBOL_CHARSET) { flags |= PDFFONT_SYMBOLIC; } else { flags |= PDFFONT_NONSYMBOLIC; } pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding"); } else { flags |= PDFFONT_NONSYMBOLIC; int i; for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes); i ++) if (g_FX_CharsetUnicodes[i].m_Charset == pLogFont->lfCharSet) { break; } if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) { CPDF_Dictionary* pEncoding = FX_NEW CPDF_Dictionary; pEncoding->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding"); CPDF_Array* pArray = FX_NEW CPDF_Array; pArray->AddInteger(128); const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; for (int j = 0; j < 128; j ++) { CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); if (name.IsEmpty()) { pArray->AddName(FX_BSTRC(".notdef")); } else { pArray->AddName(name); } } pEncoding->SetAt(FX_BSTRC("Differences"), pArray); AddIndirectObject(pEncoding); pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncoding); } } if (pLogFont->lfWeight > FW_MEDIUM && pLogFont->lfItalic) { basefont += ",BoldItalic"; } else if (pLogFont->lfWeight > FW_MEDIUM) { basefont += ",Bold"; } else if (pLogFont->lfItalic) { basefont += ",Italic"; } pBaseDict->SetAtName("Subtype", "TrueType"); pBaseDict->SetAtName("BaseFont", basefont); pBaseDict->SetAtNumber("FirstChar", 32); pBaseDict->SetAtNumber("LastChar", 255); int char_widths[224]; GetCharWidth(hDC, 32, 255, char_widths); CPDF_Array* pWidths = FX_NEW CPDF_Array; for (int i = 0; i < 224; i ++) { pWidths->AddInteger(char_widths[i]); } pBaseDict->SetAt("Widths", pWidths); } else { flags |= PDFFONT_NONSYMBOLIC; pFontDict = FX_NEW CPDF_Dictionary; CFX_ByteString cmap; CFX_ByteString ordering; int supplement; CPDF_Array* pWidthArray = FX_NEW CPDF_Array; switch (pLogFont->lfCharSet) { case CHINESEBIG5_CHARSET: cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; ordering = "CNS1"; supplement = 4; pWidthArray->AddInteger(1); _InsertWidthArray(hDC, 0x20, 0x7e, pWidthArray); break; case GB2312_CHARSET: cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H"; ordering = "GB1", supplement = 2; pWidthArray->AddInteger(7716); _InsertWidthArray(hDC, 0x20, 0x20, pWidthArray); pWidthArray->AddInteger(814); _InsertWidthArray(hDC, 0x21, 0x7e, pWidthArray); break; case HANGEUL_CHARSET: cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H"; ordering = "Korea1"; supplement = 2; pWidthArray->AddInteger(1); _InsertWidthArray(hDC, 0x20, 0x7e, pWidthArray); break; case SHIFTJIS_CHARSET: cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H"; ordering = "Japan1"; supplement = 5; pWidthArray->AddInteger(231); _InsertWidthArray(hDC, 0x20, 0x7d, pWidthArray); pWidthArray->AddInteger(326); _InsertWidthArray(hDC, 0xa0, 0xa0, pWidthArray); pWidthArray->AddInteger(327); _InsertWidthArray(hDC, 0xa1, 0xdf, pWidthArray); pWidthArray->AddInteger(631); _InsertWidthArray(hDC, 0x7e, 0x7e, pWidthArray); break; } pBaseDict->SetAtName("Subtype", "Type0"); pBaseDict->SetAtName("BaseFont", basefont); pBaseDict->SetAtName("Encoding", cmap); pFontDict->SetAt("W", pWidthArray); pFontDict->SetAtName("Type", "Font"); pFontDict->SetAtName("Subtype", "CIDFontType2"); pFontDict->SetAtName("BaseFont", basefont); CPDF_Dictionary* pCIDSysInfo = FX_NEW CPDF_Dictionary; pCIDSysInfo->SetAtString("Registry", "Adobe"); pCIDSysInfo->SetAtString("Ordering", ordering); pCIDSysInfo->SetAtInteger("Supplement", supplement); pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo); CPDF_Array* pArray = FX_NEW CPDF_Array; pBaseDict->SetAt("DescendantFonts", pArray); AddIndirectObject(pFontDict); pArray->AddReference(this, pFontDict); } AddIndirectObject(pBaseDict); CPDF_Dictionary* pFontDesc = FX_NEW CPDF_Dictionary; pFontDesc->SetAtName("Type", "FontDescriptor"); pFontDesc->SetAtName("FontName", basefont); pFontDesc->SetAtInteger("Flags", flags); CPDF_Array* pBBox = FX_NEW CPDF_Array; for (int i = 0; i < 4; i ++) { pBBox->AddInteger(bbox[i]); } pFontDesc->SetAt("FontBBox", pBBox); pFontDesc->SetAtInteger("ItalicAngle", italicangle); pFontDesc->SetAtInteger("Ascent", ascend); pFontDesc->SetAtInteger("Descent", descend); pFontDesc->SetAtInteger("CapHeight", capheight); pFontDesc->SetAtInteger("StemV", pLogFont->lfWeight / 5); AddIndirectObject(pFontDesc); pFontDict->SetAtReference("FontDescriptor", this, pFontDesc); hFont = SelectObject(hDC, hFont); DeleteObject(hFont); DeleteDC(hDC); return LoadFont(pBaseDict); }
void CPDFSDK_Annot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox, const CPDF_Matrix& matrix, const CFX_ByteString& sContents, const CFX_ByteString& sAPState) { ASSERT(m_pAnnot != NULL); ASSERT(m_pAnnot->m_pAnnotDict != NULL); CPDF_Dictionary* pAPDict = m_pAnnot->m_pAnnotDict->GetDict("AP"); if (!pAPDict) { pAPDict = FX_NEW CPDF_Dictionary; m_pAnnot->m_pAnnotDict->SetAt("AP", pAPDict); } CPDF_Stream* pStream = NULL; CPDF_Dictionary* pParentDict = NULL; if (sAPState.IsEmpty()) { pParentDict = pAPDict; pStream = pAPDict->GetStream(sAPType); } else { CPDF_Dictionary* pAPTypeDict = pAPDict->GetDict(sAPType); if (!pAPTypeDict) { pAPTypeDict = FX_NEW CPDF_Dictionary; pAPDict->SetAt(sAPType, pAPTypeDict); } pParentDict = pAPTypeDict; pStream = pAPTypeDict->GetStream(sAPState); } if (!pStream) { ASSERT(m_pPageView != NULL); CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); ASSERT(pDoc != NULL); pStream = FX_NEW CPDF_Stream(NULL, 0, NULL); FX_INT32 objnum = pDoc->AddIndirectObject(pStream); //pAPDict->SetAtReference(sAPType, pDoc, objnum); ASSERT(pParentDict != NULL); pParentDict->SetAtReference(sAPType, pDoc, objnum); } CPDF_Dictionary * pStreamDict = pStream->GetDict(); if (!pStreamDict) { pStreamDict = FX_NEW CPDF_Dictionary; pStreamDict->SetAtName("Type", "XObject"); pStreamDict->SetAtName("Subtype", "Form"); pStreamDict->SetAtInteger("FormType", 1); pStream->InitStream(NULL,0,pStreamDict); } if (pStreamDict) { pStreamDict->SetAtMatrix("Matrix",matrix); pStreamDict->SetAtRect("BBox", rcBBox); } pStream->SetData((FX_BYTE*)sContents.c_str(), sContents.GetLength(), FALSE, FALSE); }
DLLEXPORT int STDCALL FPDFPage_Flatten( FPDF_PAGE page, int nFlag) { if (!page) { return FLATTEN_FAIL; } CPDF_Page * pPage = (CPDF_Page*)( page ); CPDF_Document * pDocument = pPage->m_pDocument; CPDF_Dictionary * pPageDict = pPage->m_pFormDict; if ( !pDocument || !pPageDict ) { return FLATTEN_FAIL; } CPDF_ObjectArray ObjectArray; CPDF_RectArray RectArray; int iRet = FLATTEN_FAIL; iRet = ParserAnnots( pDocument, pPageDict, &RectArray, &ObjectArray, nFlag); if (iRet == FLATTEN_NOTINGTODO) { return FLATTEN_NOTINGTODO; }else if (iRet == FLATTEN_FAIL) { return FLATTEN_FAIL; } CPDF_Rect rcOriginalCB; CPDF_Rect rcMerger = CalculateRect( &RectArray ); CPDF_Rect rcOriginalMB = pPageDict->GetRect("MediaBox"); if (pPageDict->KeyExist("CropBox")) rcOriginalMB = pPageDict->GetRect("CropBox"); if (rcOriginalMB.IsEmpty()) { rcOriginalMB = CPDF_Rect(0.0f, 0.0f, 612.0f, 792.0f); } rcMerger.left = rcMerger.left < rcOriginalMB.left? rcOriginalMB.left : rcMerger.left; rcMerger.right = rcMerger.right > rcOriginalMB.right? rcOriginalMB.right : rcMerger.right; rcMerger.top = rcMerger.top > rcOriginalMB.top? rcOriginalMB.top : rcMerger.top; rcMerger.bottom = rcMerger.bottom < rcOriginalMB.bottom? rcOriginalMB.bottom : rcMerger.bottom; if (pPageDict->KeyExist("ArtBox")) rcOriginalCB = pPageDict->GetRect("ArtBox"); else rcOriginalCB = rcOriginalMB; if (!rcOriginalMB.IsEmpty()) { CPDF_Array* pMediaBox = FX_NEW CPDF_Array(); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.left)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.bottom)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.right)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.top)); pPageDict->SetAt("MediaBox",pMediaBox); } if (!rcOriginalCB.IsEmpty()) { CPDF_Array* pCropBox = FX_NEW CPDF_Array(); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.left)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.bottom)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.right)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.top)); pPageDict->SetAt("ArtBox", pCropBox); } CPDF_Dictionary* pRes = NULL; pRes = pPageDict->GetDict("Resources"); if (!pRes) { pRes = FX_NEW CPDF_Dictionary; pPageDict->SetAt( "Resources", pRes ); } CPDF_Stream* pNewXObject = FX_NEW CPDF_Stream(NULL, 0, FX_NEW CPDF_Dictionary); FX_DWORD dwObjNum = pDocument->AddIndirectObject(pNewXObject); CPDF_Dictionary* pPageXObject = pRes->GetDict("XObject"); if (!pPageXObject) { pPageXObject = FX_NEW CPDF_Dictionary; pRes->SetAt("XObject", pPageXObject); } CFX_ByteString key = ""; int nStreams = ObjectArray.GetSize(); if (nStreams > 0) { for (int iKey = 0; /*iKey < 100*/; iKey++) { char sExtend[5] = {0}; FXSYS_itoa(iKey, sExtend, 10); key = CFX_ByteString("FFT") + CFX_ByteString(sExtend); if (!pPageXObject->KeyExist(key)) break; } } SetPageContents(key, pPageDict, pDocument); CPDF_Dictionary* pNewXORes = NULL; if (!key.IsEmpty()) { pPageXObject->SetAtReference(key, pDocument, dwObjNum); CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict(); pNewXORes = FX_NEW CPDF_Dictionary; pNewOXbjectDic->SetAt("Resources", pNewXORes); pNewOXbjectDic->SetAtName("Type", "XObject"); pNewOXbjectDic->SetAtName("Subtype", "Form"); pNewOXbjectDic->SetAtInteger("FormType", 1); pNewOXbjectDic->SetAtName("Name", "FRM"); CPDF_Rect rcBBox = pPageDict->GetRect("ArtBox"); pNewOXbjectDic->SetAtRect("BBox", rcBBox); } for (int i = 0; i < nStreams; i++) { CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i); if (!pAnnotDic)continue; CPDF_Rect rcAnnot = pAnnotDic->GetRect("Rect"); rcAnnot.Normalize(); CFX_ByteString sAnnotState = pAnnotDic->GetString("AS"); CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDict("AP"); if (!pAnnotAP)continue; CPDF_Stream* pAPStream = pAnnotAP->GetStream("N"); if (!pAPStream) { CPDF_Dictionary* pAPDic = pAnnotAP->GetDict("N"); if (!pAPDic)continue; if (!sAnnotState.IsEmpty()) { pAPStream = pAPDic->GetStream(sAnnotState); } else { FX_POSITION pos = pAPDic->GetStartPos(); if (pos) { CFX_ByteString sKey; CPDF_Object* pFirstObj = pAPDic->GetNextElement(pos, sKey); if (pFirstObj) { if (pFirstObj->GetType() == PDFOBJ_REFERENCE) pFirstObj = pFirstObj->GetDirect(); if (pFirstObj->GetType() != PDFOBJ_STREAM) continue; pAPStream = (CPDF_Stream*)pFirstObj; } } } } if (!pAPStream)continue; CPDF_Dictionary* pAPDic = pAPStream->GetDict(); CFX_AffineMatrix matrix = pAPDic->GetMatrix("Matrix"); CPDF_Rect rcStream; if (pAPDic->KeyExist("Rect")) rcStream = pAPDic->GetRect("Rect"); else if (pAPDic->KeyExist("BBox")) rcStream = pAPDic->GetRect("BBox"); if (rcStream.IsEmpty())continue; CPDF_Object* pObj = pAPStream; if (pObj) { CPDF_Dictionary* pObjDic = pObj->GetDict(); if (pObjDic) { pObjDic->SetAtName("Type", "XObject"); pObjDic->SetAtName("Subtype", "Form"); } } CPDF_Dictionary* pXObject = pNewXORes->GetDict("XObject"); if (!pXObject) { pXObject = FX_NEW CPDF_Dictionary; pNewXORes->SetAt("XObject", pXObject); } CFX_ByteString sFormName; sFormName.Format("F%d", i); FX_DWORD dwObjNum = pDocument->AddIndirectObject(pObj); pXObject->SetAtReference(sFormName, pDocument, dwObjNum); CPDF_StreamAcc acc; acc.LoadAllData(pNewXObject); FX_LPCBYTE pData = acc.GetData(); CFX_ByteString sStream(pData, acc.GetSize()); CFX_ByteString sTemp; if (matrix.IsIdentity()) { matrix.a = 1.0f; matrix.b = 0.0f; matrix.c = 0.0f; matrix.d = 1.0f; matrix.e = 0.0f; matrix.f = 0.0f; } CFX_AffineMatrix m = GetMatrix(rcAnnot, rcStream, matrix); sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, sFormName.c_str()); sStream += sTemp; pNewXObject->SetData((FX_LPCBYTE)sStream, sStream.GetLength(), FALSE, FALSE); } pPageDict->RemoveAt( "Annots" ); ObjectArray.RemoveAll(); RectArray.RemoveAll(); return FLATTEN_SUCCESS; }