📄 pdf.c
字号:
* vAddFooter - add a page footer */static voidvAddFooter(diagram_type *pDiag){ const hdrftr_block_type *pFtrInfo; fail(pDiag == NULL); NO_DBG_MSG("vAddFooter"); pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE, odd(iPageCount), bFirstInSection); bFirstInSection = FALSE; if (pFtrInfo == NULL || pFtrInfo->pText == NULL || pFtrInfo->lHeight <= 0) { fail(pFtrInfo != NULL && pFtrInfo->lHeight < 0); fail(pFtrInfo != NULL && pFtrInfo->pText != NULL && pFtrInfo->lHeight == 0); return; } bInFtrSpace = TRUE; DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, pFtrInfo->lHeight); DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, lFooterHeight); DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, pDiag->lYtop); DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, lFooterHeight + PS_BOTTOM_MARGIN); if (pDiag->lYtop > lFooterHeight + PS_BOTTOM_MARGIN) { /* Move down to the start of the footer */ pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN; vMoveTo(pDiag, 0); } else if (pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN / 2) { DBG_FIXME(); /* * Move up to the start of the footer, to prevent moving * of the bottom edge of the paper */ pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN; vMoveTo(pDiag, 0); } DBG_FLT_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, dDrawUnits2Points(lFooterHeight + PS_BOTTOM_MARGIN - pDiag->lYtop)); vAddHdrFtr(pDiag, pFtrInfo); bInFtrSpace = FALSE;} /* end of vAddFooter *//* * vEndPageObject - end the current page object */static voidvEndPageObject(FILE *pOutFile){ long lStreamEnd; if (lStreamStart < 0) { /* There is no current page object */ return; } vFPprintf(pOutFile, "ET\n"); lStreamEnd = lFilePosition; vFPprintf(pOutFile, "endstream\n"); vFPprintf(pOutFile, "endobj\n"); iObjectNumberCurr++; vSetLocation(iObjectNumberCurr); vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); vFPprintf(pOutFile, "%lu\n", lStreamEnd - lStreamStart); vFPprintf(pOutFile, "endobj\n");} /* end of vEndPageObject *//* * vMove2NextPage - move to the start of the next page */static voidvMove2NextPage(diagram_type *pDiag, BOOL bNewSection){ FILE *pOutFile; fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); pOutFile = pDiag->pOutFile; vAddFooter(pDiag); /* End the old page object */ vEndPageObject(pOutFile); if (bNewSection) { iSectionIndex++; bFirstInSection = TRUE; } /* Start the new page object */ iObjectNumberCurr++; vSetLocation(iObjectNumberCurr); vFillNextPageObject(); vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); vFPprintf(pOutFile, "<<\n"); vFPprintf(pOutFile, "/Type /Page\n"); vFPprintf(pOutFile, "/Parent 3 0 R\n"); vFPprintf(pOutFile, "/Resources 17 0 R\n"); vFPprintf(pOutFile, "/Contents %d 0 R\n", iObjectNumberCurr + 1); vFPprintf(pOutFile, ">>\n"); vFPprintf(pOutFile, "endobj\n"); /* Start the new text object */ iObjectNumberCurr++; vSetLocation(iObjectNumberCurr); vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); vFPprintf(pOutFile, "<<\n"); vFPprintf(pOutFile, "/Length %d 0 R\n", iObjectNumberCurr + 1); vFPprintf(pOutFile, ">>\n"); vFPprintf(pOutFile, "stream\n"); lStreamStart = lFilePosition; vFPprintf(pOutFile, "BT\n"); /* Set variables to their start of page values */ pDiag->lYtop = lPageHeight - PS_TOP_MARGIN; tFontRefCurr = (drawfile_fontref)-1; usFontSizeCurr = 0; iFontColorCurr = -1; lYtopCurr = -1; vAddHeader(pDiag);} /* end of vMove2NextPage *//* * vMoveTo - move to the specified X,Y coordinates * * Move the current position of the specified diagram to its X,Y coordinates, * start on a new page if needed */static voidvMoveTo(diagram_type *pDiag, long lLastVerticalMovement){ fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) { vMove2NextPage(pDiag, FALSE); /* Repeat the last vertical movement on the new page */ pDiag->lYtop -= lLastVerticalMovement; } fail(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace); DBG_DEC_C(pDiag->lYtop < PS_BOTTOM_MARGIN, pDiag->lYtop); fail(pDiag->lYtop < PS_BOTTOM_MARGIN / 3); if (pDiag->lYtop != lYtopCurr) { vFPprintf(pDiag->pOutFile, "1 0 0 1 %.2f %.2f Tm\n", dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), dDrawUnits2Points(pDiag->lYtop)); lYtopCurr = pDiag->lYtop; }} /* end of vMoveTo *//* * vProloguePDF - set options and perform the PDF initialization */voidvProloguePDF(diagram_type *pDiag, const char *szTask, const options_type *pOptions){ FILE *pOutFile; fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); fail(pOptions == NULL); pOutFile = pDiag->pOutFile; eEncoding = pOptions->eEncoding; /* Create an empty location array */ tLocations = INITIAL_LOCATION_SIZE; alLocation = xcalloc(tLocations, sizeof(long)); /* Create an empty pageobject array */ tMaxPageObjects = INITIAL_PAGEOBJECT_SIZE; aiPageObject = xcalloc(tMaxPageObjects, sizeof(int)); if (pOptions->iPageHeight == INT_MAX) { lPageHeight = LONG_MAX; } else { lPageHeight = lPoints2DrawUnits(pOptions->iPageHeight); } DBG_DEC(lPageHeight); if (pOptions->iPageWidth == INT_MAX) { lPageWidth = LONG_MAX; } else { lPageWidth = lPoints2DrawUnits(pOptions->iPageWidth); } DBG_DEC(lPageWidth); lFooterHeight = 0; bInFtrSpace = FALSE; tFontRefCurr = (drawfile_fontref)-1; usFontSizeCurr = 0; iFontColorCurr = -1; lYtopCurr = -1; iPageCount = 0; iImageCount = 0; iSectionIndex = 0; bFirstInSection = TRUE; lFilePosition = 0; iMaxLocationNumber = 0; lStreamStart = -1; iObjectNumberCurr = 17; pDiag->lXleft = 0; pDiag->lYtop = 0; szProducer = szTask; vFPprintf(pOutFile, "%%PDF-1.3\n"); vFPprintf(pOutFile, "%%%c%c%c%c\n", 0xe2, 0xe3, 0xcf, 0xd3); /* Root catalog */ vSetLocation(1); vFPprintf(pOutFile, "1 0 obj\n"); vFPprintf(pOutFile, "<<\n"); vFPprintf(pOutFile, "/Type /Catalog\n"); vFPprintf(pOutFile, "/Pages 3 0 R\n"); vFPprintf(pOutFile, ">>\n"); vFPprintf(pOutFile, "endobj\n");} /* end of vProloguePDF *//* * vEpiloguePDF - clean up after everything is done */voidvEpiloguePDF(diagram_type *pDiag){ FILE *pOutFile; long lXref; int iIndex; fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); pOutFile = pDiag->pOutFile; vAddFooter(pDiag); /* End the old page object */ vEndPageObject(pOutFile); vSetLocation(3); vFPprintf(pOutFile, "3 0 obj\n"); vFPprintf(pOutFile, "<<\n"); vFPprintf(pOutFile, "/Type /Pages\n"); vFPprintf(pOutFile, "/Count %d\n", iPageCount); vFPprintf(pOutFile, "/MediaBox [ 0 0 %.0f %.0f ]\n", dDrawUnits2Points(lPageWidth), dDrawUnits2Points(lPageHeight)); vFPprintf(pOutFile, "/Kids [ "); for (iIndex = 1; iIndex <= iPageCount; iIndex++) { vFPprintf(pOutFile, "\t%d 0 R\n", aiPageObject[iIndex]); } vFPprintf(pOutFile, "]\n"); vFPprintf(pOutFile, ">>\n"); vFPprintf(pOutFile, "endobj\n"); lXref = lFilePosition; vFPprintf(pOutFile, "xref\n"); vFPprintf(pOutFile, "0 %d\n", iMaxLocationNumber + 1); vFPprintf(pOutFile, "0000000000 65535 f \n"); for (iIndex = 1; iIndex <= iMaxLocationNumber; iIndex++) { vFPprintf(pOutFile, "%.10ld 00000 n \n", alLocation[iIndex]); } vFPprintf(pOutFile, "trailer\n"); vFPprintf(pOutFile, "<<\n"); vFPprintf(pOutFile, "/Size %d\n", iMaxLocationNumber + 1); vFPprintf(pOutFile, "/Root 1 0 R\n"); vFPprintf(pOutFile, "/Info 2 0 R\n"); vFPprintf(pOutFile, ">>\n"); vFPprintf(pOutFile, "startxref\n"); vFPprintf(pOutFile, "%ld\n", lXref); vFPprintf(pOutFile, "%%%%EOF\n"); szProducer = NULL; aiPageObject = xfree(aiPageObject); alLocation = xfree(alLocation);} /* end of vEpiloguePDF *//* * vPrintPalette - print a pdf color space (palette) */static voidvPrintPalette(FILE *pOutFile, const imagedata_type *pImg){ int iIndex; fail(pOutFile == NULL); fail(pImg == NULL); fail(pImg->iColorsUsed < 2); fail(pImg->iColorsUsed > 256); vFPprintf(pOutFile, "\t/ColorSpace [ /Indexed\n"); vFPprintf(pOutFile, "\t/Device%s %d\n", pImg->bColorImage ? "RGB" : "Gray", pImg->iColorsUsed - 1); vFPprintf(pOutFile, "<"); for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) { vFPprintf(pOutFile, "%02x", (unsigned int)pImg->aucPalette[iIndex][0]); if (pImg->bColorImage) { vFPprintf(pOutFile, "%02x%02x", (unsigned int)pImg->aucPalette[iIndex][1], (unsigned int)pImg->aucPalette[iIndex][2]); } if (iIndex % 8 == 7) { vFPprintf(pOutFile, "\n"); } else { vFPprintf(pOutFile, " "); } } vFPprintf(pOutFile, "> ]\n");} /* end of vPrintPalette *//* * vImageProloguePDF - perform the image initialization */voidvImageProloguePDF(diagram_type *pDiag, const imagedata_type *pImg){ FILE *pOutFile; fail(pDiag == NULL); fail(pDiag->pOutFile == NULL); fail(pImg == NULL); if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) { return; } iImageCount++; DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled); vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled)); pOutFile = pDiag->pOutFile; vFPprintf(pOutFile, "ET\n"); vFPprintf(pOutFile, "q %% Image %03d\n", iImageCount); if (pImg->eImageType == imagetype_is_dib) { /* Scanning from left to right and bottom to top */ vFPprintf(pOutFile, "%d 0 0 %d %.2f %.2f cm\n", pImg->iHorSizeScaled, -pImg->iVerSizeScaled, dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), dDrawUnits2Points(pDiag->lYtop) + pImg->iVerSizeScaled); } else { /* Scanning from left to right and top to bottom */ vFPprintf(pOutFile, "%d 0 0 %d %.2f %.2f cm\n", pImg->iHorSizeScaled, pImg->iVerSizeScaled, dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), dDrawUnits2Points(pDiag->lYtop)); } vFPprintf(pOutFile, "BI\n"); vFPprintf(pOutFile, "\t/Width %d\n", pImg->iWidth); vFPprintf(pOutFile, "\t/Height %d\n", pImg->iHeight); switch (pImg->eImageType) { case imagetype_is_jpeg: switch (pImg->iComponents) { case 1: vFPprintf(pOutFile, "\t/ColorSpace /DeviceGray\n"); break; case 3: vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n"); break; case 4: vFPprintf(pOutFile, "\t/ColorSpace /DeviceCMYK\n"); if (pImg->bAdobe) { /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -