00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "precomp.h"
00028 #include "oemps.h"
00029 #include "resource.h"
00030 #include <math.h>
00031 #include <PRCOMOEM.H>
00032 #include "CCTChar.h"
00033 #include "CCPrintRegistry.h"
00034 #include "GlyphTranslator.h"
00035 #include "CCPrintData.h"
00036
00037 #include "intrface.h"
00038 #include "PngImage.h"
00039 #include "SQLiteDB.h"
00040
00041
00043 extern HINSTANCE ghInstance;
00044
00045
00046
00052 UINT GetLicenseImage(const LicenseInfo& info)
00053 {
00054 switch (info.m_eLicense)
00055 {
00056 case LicenseInfo::LTCC:
00057 if (info.m_eModification != LicenseInfo::MTUnknown)
00058 {
00059 UINT uBase = IDPNG_BY_NC + (int)info.m_eModification;
00060 if (info.m_bCommercialUse)
00061 uBase += 3;
00062 return uBase;
00063 }
00064 break;
00065 case LicenseInfo::LTSampling:
00066 if (info.m_eSampling == LicenseInfo::STUnknown)
00067 break;
00068 return IDPNG_SAMPLING + (int)info.m_eSampling;
00069 case LicenseInfo::LTDevelopingNations:
00070 case LicenseInfo::LTPublicDomain:
00071 return IDPNG_SOMERIGHTS;
00072 default:
00073 break;
00074 }
00075 return 0;
00076 }
00077
00085 BOOL DrawImage(SURFOBJ* pso, SURFOBJ* pSrc, RECTL& rectTarget)
00086 {
00087
00088 XLATEOBJ xlate;
00089 memset(&xlate, 0, sizeof(xlate));
00090
00091
00092 COLORADJUSTMENT clr;
00093 memset(&clr, 0, sizeof(clr));
00094
00095
00096 CLIPOBJ clip;
00097 clip.iUniq = 0;
00098 clip.rclBounds = rectTarget;
00099 clip.iDComplexity = DC_RECT;
00100 clip.iFComplexity = FC_RECT;
00101 clip.iMode = TC_RECTANGLES;
00102 clip.fjOptions = 0;
00103
00104
00105 POINTL pt;
00106 pt.x = pt.y = 0;
00107
00108
00109 RECTL rectSource;
00110 rectSource.top = rectSource.left = 0;
00111 rectSource.right = pSrc->sizlBitmap.cx;
00112 rectSource.bottom = pSrc->sizlBitmap.cy;
00113
00114
00115 BOOL bRet = EngStretchBlt(pso, pSrc, NULL, &clip, &xlate, &clr, &pt, &rectTarget, &rectSource, &pt, COLORONCOLOR);
00116
00117 return bRet;
00118 }
00119
00127 BOOL DrawImage(SURFOBJ* pso, const PngImage& png, RECTL& rectTarget)
00128 {
00129 SIZEL szBitmap;
00130 szBitmap.cx = png.GetWidth();
00131 szBitmap.cy = png.GetHeight();
00132
00133 UINT uFormat;
00134 switch (png.GetBitsPerPixel())
00135 {
00136 case 1:
00137 uFormat = BMF_1BPP;
00138 break;
00139 case 4:
00140 uFormat = BMF_4BPP;
00141 break;
00142 case 8:
00143 uFormat = BMF_8BPP;
00144 break;
00145 case 16:
00146 uFormat = BMF_16BPP;
00147 break;
00148 case 24:
00149 uFormat = BMF_24BPP;
00150 break;
00151 case 32:
00152 uFormat = BMF_32BPP;
00153 break;
00154 }
00155
00156 HBITMAP hEngBmp = EngCreateBitmap(szBitmap, png.GetWidthInBytes(), uFormat, BMF_TOPDOWN|BMF_USERMEM, (void*)png.GetBits());
00157 if (hEngBmp == NULL)
00158 return FALSE;
00159
00160 SURFOBJ* pSrc = EngLockSurface((HSURF)hEngBmp);
00161 BOOL bRet = DrawImage(pso, pSrc, rectTarget);
00162 EngUnlockSurface(pSrc);
00163 EngDeleteSurface((HSURF)hEngBmp);
00164
00165 return bRet;
00166 }
00167
00175 BOOL DrawImage(SURFOBJ* pso, HBITMAP hBmp, RECTL& rectTarget)
00176 {
00177 BITMAP bmp;
00178 ::GetObject(hBmp, sizeof(bmp), &bmp);
00179 SIZEL szBitmap;
00180 szBitmap.cx = bmp.bmWidth;
00181 szBitmap.cy = bmp.bmHeight;
00182 UINT uFormat;
00183 switch (bmp.bmBitsPixel)
00184 {
00185 case 1:
00186 uFormat = BMF_1BPP;
00187 break;
00188 case 4:
00189 uFormat = BMF_4BPP;
00190 break;
00191 case 8:
00192 uFormat = BMF_8BPP;
00193 break;
00194 case 16:
00195 uFormat = BMF_16BPP;
00196 break;
00197 case 24:
00198 uFormat = BMF_24BPP;
00199 break;
00200 case 32:
00201 uFormat = BMF_32BPP;
00202 break;
00203 }
00204
00205 HBITMAP hEngBmp = EngCreateBitmap(szBitmap, bmp.bmWidthBytes, uFormat, BMF_USERMEM, (void*)bmp.bmBits);
00206 if (hEngBmp == NULL)
00207 return FALSE;
00208
00209 SURFOBJ* pSrc = EngLockSurface((HSURF)hEngBmp);
00210 BOOL bRet = DrawImage(pso, pSrc, rectTarget);
00211 EngUnlockSurface(pSrc);
00212 EngDeleteSurface((HSURF)hEngBmp);
00213
00214 return bRet;
00215 }
00216
00218 #define URLBOX "\n[ /Rect [%d %d %d %d]\n\
00219 /Action << /Subtype /URI /URI (%s) >>\n\
00220 /Border [0 0 2]\n\
00221 /Color [.7 0 0]\n\
00222 /Subtype /Link\n\
00223 /Title (%s)\n\
00224 /ANN pdfmark\n"
00225
00227 #define HYPERLINK_FUNC "/cc_hyperlink { dup show stringwidth pop neg\n\
00228 gsave 0 currentfont dup\n\
00229 /FontInfo get /UnderlineThickness get exch\n\
00230 /FontMatrix get dtransform setlinewidth 0 currentfont dup\n\
00231 /FontInfo get /UnderlinePosition get exch\n\
00232 /FontMatrix get dtransform rmoveto rlineto stroke\n\
00233 grestore\n\
00234 } def\n"
00235
00237 #define HYPERLINK_START "\ncurrentpoint\n\
00238 %d sub\n\
00239 currentcolor 0 0 128 setrgbcolor\
00240 ("
00241
00243 #define HYPERLINK_END ") cc_hyperlink\n\
00244 setcolor\n\
00245 currentpoint\n\
00246 [ /Rect 6 -4 roll 4 array astore\n\
00247 /Action << /Subtype /URI /URI (%s) >>\n\
00248 /Border [0 0 2]\n\
00249 /Color [.7 0 0]\n\
00250 /Subtype /Link\n\
00251 /ANN pdfmark\n"
00252
00254 #define JUMPBOX "\n[ /Rect [%d %d %d %d]\n\
00255 /Border [0 0 2]\n\
00256 /Color [.7 0 0]\n\
00257 /Dest /%s\n\
00258 /Title (%s)\n\
00259 /Subtype /Link\n\
00260 /ANN pdfmark\n"
00261
00263 #define JUMPDEST "\n[ /Dest /%s\n\
00264 /View [/Fit]\n\
00265 /DEST pdfmark\n"
00266
00268 #define JUMPINTERNAL_TITLE "\n[ /Rect [%d %d %d %d]\n\
00269 /Border [0 0 2]\n\
00270 /Color [.7 0 0]\n\
00271 /Page %d\n\
00272 /View [/XYZ %d %d 0]\n\
00273 /Title (%s)\n\
00274 /Subtype /Link\n\
00275 /ANN pdfmark\n"
00276
00278 #define JUMPINTERNAL "\n[ /Rect [%d %d %d %d]\n\
00279 /Border [0 0 2]\n\
00280 /Color [.7 0 0]\n\
00281 /Page %d\n\
00282 /View [/XYZ %d %d 0]\n\
00283 /Subtype /Link\n\
00284 /ANN pdfmark\n"
00285
00287 #define PS_TEXT_START "/Times-Roman findfont [%d 0 0 -%d 0 0 ] makefont setfont\n\
00288 %d %d moveto\n\
00289 ("
00291 #define PS_TEXT_END ") show\n"
00292
00294 #define PS_JUSTTEXT_START "("
00296 #define PS_JUSTTEXT_END ") show \n"
00297
00299 #define PS_TEXT_END_CENTER ")\n\
00300 dup stringwidth pop\n\
00301 %d exch sub\n\
00302 2 div\n\
00303 0 rmoveto\n\
00304 show\n"
00305
00307 #define PS_CALC_CENTER_START "/Times-Roman findfont [%d 0 0 -%d 0 0 ] makefont setfont\n\
00308 %d %d moveto\n\
00309 ("
00310
00312 #define PS_CALC_CENTER_END ") stringwidth pop\n\
00313 %d exch sub\n\
00314 2 div\n\
00315 0 rmoveto\n"
00316
00318 #define PS_CIRCLE "newpath %d %d %d 0 360 arc fill closepath\n"
00319
00321 #define PS_IMAGE_START "gsave\n\
00322 %d %d translate\n\
00323 %d %d scale\n\
00324 %d %d %d [%d 0 0 -%d 0 %d] {<\n"
00325
00327 #define PS_IMAGE_END "\n>} image\n\
00328 grestore\n";
00329
00331 #define CREATEDBY_TEXT "The document was created by "
00332 #ifdef CC_PDF_CONVERTER
00334 #define CREATEDBY_LINK_TEXT "CC PDF Converter"
00336 #define CREATEDBY_LINK "http://www.cogniview.com/cc-pdf-converter.php"
00337 #elif EXCEL_TO_PDF
00339 #define CREATEDBY_LINK_TEXT "Excel to PDF Converter"
00341 #define CREATEDBY_LINK "http://www.cogniview.com/excel-to-pdf-converter.php"
00342 #else
00343 #error "One of the printer types must be defined"
00344 #endif
00345
00347 #define PS_NO_LICENSE_INFO "\n[ /Rights (False)\n\
00348 /RightsURL ("
00349
00351 #define PS_LICENSE_INFO_START "\n[ /Rights (True)\n\
00352 /RightsURL ("
00353 #define PS_LICENSE_INFO_CONTINUE ")\n\
00354 /RightsStatement (This work is licensed under a "
00355 #define PS_LICENSE_INFO_END ")\n\
00356 /DOCINFO pdfmark\n"
00357
00364 void AddPSText(LPSTR lpString, LPCSTR lpText, std::tstring::size_type dwLen)
00365 {
00366 std::tstring::size_type nLoc = strlen(lpString);
00367 for (std::tstring::size_type i=0;i<dwLen;i++)
00368 {
00369 switch (lpText[i])
00370 {
00371 case '\n':
00372 case '\r':
00373 case '\t':
00374 case '\b':
00375 case '\f':
00376 case '\\':
00377 case '(':
00378 case ')':
00379 lpString[nLoc++] = '\\';
00380 break;
00381 }
00382 lpString[nLoc++] = lpText[i];
00383 }
00384 lpString[nLoc] = '\0';
00385 }
00386
00392 void AddPSText(LPSTR lpString, const std::string& s)
00393 {
00394 AddPSText(lpString, s.c_str(), s.size());
00395 }
00396
00403 void PrintPS(PDEVOBJ pdevobj, POEMPDEV pDevOEM, LPCSTR lpText)
00404 {
00405 DWORD dwResult;
00406 std::tstring::size_type dwLen = strlen(lpText);
00407 pDevOEM->pOEMHelp->DrvWriteSpoolBuf(pdevobj, (void*)lpText, (DWORD)dwLen, &dwResult);
00408 }
00409
00418 void PrintCircle(PDEVOBJ pdevobj, POEMPDEV pDevOEM, int nX, int nY, int nRadius)
00419 {
00420 char cCircle[128];
00421 sprintf_s(cCircle, _S(cCircle) , PS_CIRCLE, nX, nY, nRadius);
00422 PrintPS(pdevobj, pDevOEM, cCircle);
00423 }
00424
00435 void CenterText(PDEVOBJ pdevobj, POEMPDEV pDevOEM, int nFontSize, int nX, int nY, int nWidth, LPCSTR lpText)
00436 {
00437 char cStr[1024];
00438 sprintf_s(cStr, _S(cStr), PS_CALC_CENTER_START, nFontSize, nFontSize, nX, nY + nFontSize);
00439 AddPSText(cStr, lpText, (DWORD)strlen(lpText));
00440 char cEnd[1024];
00441 sprintf_s(cEnd, _S(cEnd), PS_CALC_CENTER_END, nWidth);
00442 strcat_s(cStr, _S(cStr), cEnd);
00443 PrintPS(pdevobj, pDevOEM, cStr);
00444 }
00445
00454 void PrintJumpLink(PDEVOBJ pdevobj, POEMPDEV pDevOEM, LPCSTR lpDestination, const RECTL& rectTarget, LPCSTR lpTitle = NULL)
00455 {
00456 if (lpTitle == NULL)
00457 lpTitle = lpDestination;
00458 char cLink[1024];
00459 sprintf_s(cLink, _S(cLink), JUMPBOX, rectTarget.left, rectTarget.top, rectTarget.right, rectTarget.bottom, lpDestination, lpTitle);
00460 PrintPS(pdevobj, pDevOEM, cLink);
00461 }
00462
00471 void PrintInternalLink(PDEVOBJ pdevobj, POEMPDEV pDevOEM, const RECTL& rectTarget, long lPage, long lX, long lY, LPCSTR lpTitle = NULL)
00472 {
00473 char cLink[1024];
00474 if (lpTitle == NULL)
00475 sprintf_s(cLink, _S(cLink), JUMPINTERNAL, rectTarget.left, rectTarget.top, rectTarget.right, rectTarget.bottom, lPage, lX, lY);
00476 else
00477 sprintf_s(cLink, _S(cLink), JUMPINTERNAL_TITLE, rectTarget.left, rectTarget.top, rectTarget.right, rectTarget.bottom, lPage, lX, lY, lpTitle);
00478 PrintPS(pdevobj, pDevOEM, cLink);
00479 }
00480
00487 void PrintJumpDestination(PDEVOBJ pdevobj, POEMPDEV pDevOEM, LPCSTR lpDestination)
00488 {
00489 char cLink[1024];
00490 sprintf_s(cLink, _S(cLink), JUMPDEST, lpDestination);
00491 PrintPS(pdevobj, pDevOEM, cLink);
00492 }
00493
00502 void PrintURLLink(PDEVOBJ pdevobj, POEMPDEV pDevOEM, LPCSTR lpURL, const RECTL& rectTarget, LPCSTR lpTitle = NULL)
00503 {
00504 char cLink[1024];
00505 if (lpTitle == NULL)
00506 lpTitle = lpURL;
00507 sprintf_s(cLink, _S(cLink), URLBOX, rectTarget.left, rectTarget.top, rectTarget.right, rectTarget.bottom, lpURL, lpTitle);
00508 DWORD dwResult;
00509 std::tstring::size_type dwLen = strlen(cLink);
00510 pDevOEM->pOEMHelp->DrvWriteSpoolBuf(pdevobj, cLink, (DWORD)dwLen, &dwResult);
00511 }
00512
00522 void PrintHyperlink(PDEVOBJ pdevobj, POEMPDEV pDevOEM, int nFontSize, LPCSTR lpText, std::tstring::size_type dwLen, LPCSTR lpURL)
00523 {
00524 char cStr[2048];
00525 sprintf_s(cStr, _S(cStr), HYPERLINK_START, nFontSize);
00526 AddPSText(cStr, lpText, dwLen);
00527 char cEnd[1024];
00528 sprintf_s(cEnd, _S(cEnd), HYPERLINK_END, lpURL);
00529 strcat_s(cStr, _S(cStr), cEnd);
00530 PrintPS(pdevobj, pDevOEM, cStr);
00531 }
00532
00547 size_t PrepareWriteString(LPSTR lpString, int nStringSize, int nFontSize, int nX, int nY, LPCSTR lpText, std::tstring::size_type dwLen, int nWidth = -1)
00548 {
00549 sprintf_s(lpString, nStringSize, PS_TEXT_START, nFontSize, nFontSize, nX, nY);
00550 AddPSText(lpString, lpText, dwLen);
00551 if (nWidth == -1)
00552 strcat_s(lpString, nStringSize, PS_TEXT_END);
00553 else
00554 {
00555 char c[128];
00556 sprintf_s(c, _S(c), PS_TEXT_END_CENTER, nWidth);
00557 strcat_s(lpString, nStringSize, c);
00558 }
00559 return strlen(lpString);
00560 }
00561
00568 void PrintText(PDEVOBJ pdevobj, POEMPDEV pDevOEM, LPCSTR lpText)
00569 {
00570 char cStr[1024];
00571 sprintf_s(cStr, _S(cStr), PS_JUSTTEXT_START);
00572 AddPSText(cStr, lpText, strlen(lpText));
00573 strcat_s(cStr, _S(cStr), PS_JUSTTEXT_END);
00574 PrintPS(pdevobj, pDevOEM, cStr);
00575 }
00576
00590 int PrintText(PDEVOBJ pdevobj, POEMPDEV pDevOEM, int nFontSize, int nX, int nY, int nWidth, int nLineHeight, LPCSTR lpText, bool bCenter = false)
00591 {
00592 char cStr[1024];
00593
00594 DWORD dwResult;
00595 std::tstring::size_type dwWriteLen;
00596 std::tstring::size_type dwLen = strlen(lpText);
00597 int nRet = 0;
00598 while ((dwLen * nFontSize / 2) > nWidth)
00599 {
00600
00601 DWORD dwBreak = max(1, nWidth / (nFontSize / 2));
00602 while ((dwBreak > 1) && (lpText[dwBreak] != ' '))
00603 dwBreak--;
00604
00605 nRet += nLineHeight;
00606 dwWriteLen = PrepareWriteString(cStr, sizeof(cStr), nFontSize, nX, nY + nRet, lpText, dwBreak, bCenter ? nWidth : -1);
00607 pDevOEM->pOEMHelp->DrvWriteSpoolBuf(pdevobj, cStr, (DWORD)dwWriteLen, &dwResult);
00608 lpText += dwBreak + 1;
00609 dwLen -= dwBreak - 1;
00610 }
00611
00612 if (dwLen > 0)
00613 {
00614 nRet += nLineHeight;
00615 dwWriteLen = PrepareWriteString(cStr, sizeof(cStr), nFontSize, nX, nY + nRet, lpText, dwLen, bCenter ? nWidth : -1);
00616 dwWriteLen = strlen(cStr);
00617 pDevOEM->pOEMHelp->DrvWriteSpoolBuf(pdevobj, cStr, (DWORD)dwWriteLen, &dwResult);
00618 }
00619
00620 return nRet;
00621 }
00622
00631 BOOL PrintImage(PDEVOBJ pdevobj, POEMPDEV pDevOEM, HBITMAP hBmp, RECTL& rectTargetArea)
00632 {
00633 double dMultiplier = 1.0;
00634 if (pdevobj->pPublicDM->dmPrintQuality > 0)
00635 dMultiplier = min(2.0, pdevobj->pPublicDM->dmPrintQuality / 72.0);
00636
00637 DIBSECTION dib;
00638 if (::GetObject(hBmp, sizeof(dib), &dib) == 0)
00639 return FALSE;
00640
00641 long nDrawWidth = (long) (dib.dsBmih.biWidth * dMultiplier);
00642 long nDrawHeight = (long) (dib.dsBmih.biHeight * dMultiplier);
00643 rectTargetArea.left = ((rectTargetArea.left + rectTargetArea.right) / 2) - (nDrawWidth / 2);
00644 rectTargetArea.right = rectTargetArea.left + nDrawWidth;
00645 rectTargetArea.bottom = rectTargetArea.top + nDrawHeight;
00646
00647 char cStr[1024];
00648 sprintf_s(cStr, _S(cStr), PS_IMAGE_START, rectTargetArea.left, rectTargetArea.top,
00649 nDrawWidth, nDrawHeight,
00650 dib.dsBm.bmWidth, dib.dsBm.bmHeight, dib.dsBm.bmBitsPixel, dib.dsBm.bmWidth, dib.dsBm.bmHeight, dib.dsBm.bmHeight);
00651 std::string sWrite(cStr);
00652
00653 int nByteWidth = dib.dsBmih.biSizeImage / dib.dsBmih.biHeight;
00654 int nRealByteWidth = dib.dsBmih.biBitCount == 0 ? 8 : (dib.dsBm.bmWidth * 8) / dib.dsBmih.biBitCount;
00655 for (int i=0;i<dib.dsBm.bmHeight;i++)
00656 {
00657 for (int j=0;j<nRealByteWidth;j++)
00658 {
00659 sprintf_s(cStr, _S(cStr), "%02x", *(((unsigned char*)dib.dsBm.bmBits) + (i * nByteWidth) + j));
00660 sWrite += cStr;
00661 }
00662 sWrite += "\n";
00663 }
00664
00665 sWrite += PS_IMAGE_END;
00666 DWORD dwWriteLen = (DWORD) sWrite.size(), dwResult;
00667 DWORD dwRes = pDevOEM->pOEMHelp->DrvWriteSpoolBuf(pdevobj, (void*)sWrite.c_str(), dwWriteLen, &dwResult);
00668 return (dwRes == S_OK) && (dwWriteLen == dwResult);
00669 }
00670
00676 BOOL DoLicensePage(SURFOBJ* pso)
00677 {
00678 PDEVOBJ pdevobj;
00679 POEMPDEV poempdev;
00680
00681 pdevobj = (PDEVOBJ)pso->dhpdev;
00682 poempdev = (POEMPDEV)pdevobj->pdevOEM;
00683 PCOEMDEV pDevMode = (PCOEMDEV)pdevobj->pOEMDM;
00684
00685
00686 PrintJumpDestination(pdevobj, poempdev, "TheLicense");
00687
00688
00689 int nLang = 6;
00690
00691
00692 SQLite::DB db;
00693 std::tstring sPath = CCPrintRegistry::GetRegistryString(pdevobj->hPrinter, _T("DB Path"), _T(""));
00694 if (sPath.empty())
00695 return FALSE;
00696 if (!db.Open(sPath.c_str()))
00697 return FALSE;
00698
00699
00700 int nHeight = pso->sizlBitmap.cy;
00701 int nLineHeight = nHeight / 60;
00702 int nFontSize = nLineHeight - 2;
00703 int nY = nLineHeight * 6;
00704 int nX = nLineHeight * 2;
00705
00706
00707 TCHAR cQuery[256];
00708 int nMode;
00709 switch (pDevMode->info.m_eLicense)
00710 {
00711 case LicenseInfo::LTCC:
00712 nMode = 0;
00713 _stprintf_s(cQuery, _S(cQuery), _T("SELECT * FROM TblLicenseType WHERE commercial = %d AND derivs = %d AND mode = %d"), pDevMode->info.m_bCommercialUse ? 1 : 0, pDevMode->info.m_eModification, nMode);
00714 break;
00715 case LicenseInfo::LTSampling:
00716 nMode = 1;
00717 _stprintf_s(cQuery, _S(cQuery), _T("SELECT * FROM TblLicenseType WHERE derivs = %d AND mode = %d"), pDevMode->info.m_eSampling, nMode);
00718 break;
00719 case LicenseInfo::LTDevelopingNations:
00720 nMode = 2;
00721 _stprintf_s(cQuery, _S(cQuery), _T("SELECT * FROM TblLicenseType WHERE mode = %d"), nMode);
00722 break;
00723 default:
00724 return FALSE;
00725 }
00726
00727
00728 SQLite::Recordset records = db.Query(cQuery);
00729 if (!records.IsValid() || (records.GetRecordCount() == 0))
00730 {
00731 std::tstring s = db.GetLastError();
00732 return FALSE;
00733 }
00734
00735 int nLicenseID = records.GetRecord(0).GetNumField(_T("LicenseTypeID"));
00736 std::string sLicenseShortName = MakeAnsiString(records.GetRecord(0).GetField(_T("LicenseShortName")));
00737 _stprintf_s(cQuery, _S(cQuery), _T("SELECT LicenseName FROM tblLicenseName WHERE LicenseTypeID = %d AND LangID = %d"), nLicenseID, nLang);
00738 records = db.Query(cQuery);
00739 if (!records.IsValid() || (records.GetRecordCount() == 0))
00740 {
00741 std::tstring s = db.GetLastError();
00742 return FALSE;
00743 }
00744
00745
00746 std::tstring sLicenseName = records.GetRecord(0).GetField(_T("LicenseName"));
00747
00748 int nJuri = 1;
00749 if (pDevMode->info.HasJurisdiction())
00750 {
00751
00752 _stprintf_s(cQuery, _S(cQuery), _T("SELECT jurisdictionsID FROM tblJurisdictionName WHERE LanguageID = 6 AND JurisdictionName = '%s'"), pDevMode->info.m_cJurisdiction);
00753 records = db.Query(cQuery);
00754 if (records.IsValid() && (records.GetRecordCount() > 0))
00755 nJuri = records.GetRecord(0).GetNumField(_T("jurisdictionsID"));
00756 }
00757
00758
00759 _stprintf_s(cQuery, _S(cQuery), _T("SELECT * FROM tblJurisdiction WHERE JurisdictionID = %d AND mode = %d"), nJuri, nMode);
00760 records = db.Query(cQuery);
00761 SQLite::Record recJuri;
00762 if (records.IsValid() && (records.GetRecordCount() > 0))
00763 recJuri = records.GetRecord(0);
00764
00765 std::string sVersion, sJuriShortName;
00766 if (recJuri.IsValid())
00767 {
00768 sVersion = MakeAnsiString(recJuri.GetField(_T("Version")));
00769 sJuriShortName = MakeAnsiString(recJuri.GetField(_T("ShortName")));
00770 sLicenseName += _T(" ") + MakeTString(sVersion);
00771 }
00772
00773
00774 _stprintf_s(cQuery, _S(cQuery), _T("SELECT JurisdictionName FROM TblJurisdictionName WHERE JurisdictionsID = %d AND LanguageID = %d"), nJuri, nLang);
00775 records = db.Query(cQuery);
00776 if (records.IsValid() && (records.GetRecordCount() > 0))
00777 {
00778 sLicenseName += _T(" ") + records.GetRecord(0).GetField(_T("JurisdictionName"));
00779 }
00780 else
00781 {
00782 std::tstring s = db.GetLastError();
00783 return FALSE;
00784 }
00785
00786
00787 sPath = CCPrintRegistry::GetRegistryString(pdevobj->hPrinter, _T("Image Path"), sPath.c_str());
00788 if (sPath.empty() || (*sPath.rbegin() != '\\'))
00789 sPath += '\\';
00790 RECTL rectTarget;
00791 rectTarget.left = 0;
00792 rectTarget.right = pso->sizlBitmap.cx;
00793 rectTarget.top = nY;
00794 rectTarget.bottom = nY + 1;
00795 HBITMAP hBmp = (HBITMAP)LoadImage(ghInstance, (sPath + _T("CCLogo.bmp")).c_str(), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
00796 if (hBmp != NULL)
00797 {
00798 if (PrintImage(pdevobj, poempdev, hBmp, rectTarget))
00799 nY = rectTarget.bottom + nLineHeight;
00800 ::DeleteObject(hBmp);
00801 }
00802
00803
00804 PrintPS(pdevobj, poempdev, HYPERLINK_FUNC);
00805 int nTextHeight;
00806
00807 CenterText(pdevobj, poempdev, (nFontSize * 3) / 2, 0, nY, pso->sizlBitmap.cx, MakeAnsiString(sLicenseName).c_str());
00808 std::string sLink = "http://creativecommons.org/licenses/" + sLicenseShortName + "/";
00809 if (!sVersion.empty())
00810 sLink += sVersion + "/";
00811 if (!sJuriShortName.empty())
00812 sLink += sJuriShortName + "/";
00813 PrintHyperlink(pdevobj, poempdev, (nFontSize * 3) / 2, MakeAnsiString(sLicenseName).c_str(), sLicenseName.size(), sLink.c_str());
00814
00815 nY += (nFontSize * 3) / 2;
00816 nY += nLineHeight;
00817
00818
00819 _stprintf_s(cQuery, _S(cQuery), _T("SELECT * FROM tblTextOrder INNER JOIN tblText ON tblText.Text_ID = tblTextOrder.textid LEFT JOIN tblImages ON tblText.Imageid = tblImages.ImageID WHERE tblTextOrder.LicenseTypeID = %d AND tblText.Lang = %d ORDER BY textorder"), nLicenseID, nLang);
00820 SQLite::Recordset setText = db.Query(cQuery);
00821 if (!setText.IsValid())
00822 {
00823 std::tstring s = db.GetLastError();
00824 return FALSE;
00825 }
00826
00827 for (int iText = 0; iText < setText.GetRecordCount(); iText++)
00828 {
00829 SQLite::Record recText = setText.GetRecord(iText);
00830 if (recText.GetNumField(_T("header")) == 1)
00831 {
00832 nY += PrintText(pdevobj, poempdev, (nFontSize * 5) / 4, nX, nY, pso->sizlBitmap.cx - (2 * nX), (nLineHeight * 5) / 4, MakeAnsiString(recText.GetField(_T("Data"))).c_str());
00833 }
00834 else
00835 {
00836 int nImageHeight = 0;
00837 std::tstring sImage = recText.GetField(_T("ImageFile"));
00838 if (!sImage.empty())
00839 {
00840 hBmp = (HBITMAP)LoadImage(ghInstance, (sPath + sImage).c_str(), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
00841 if (hBmp != NULL)
00842 {
00843 nY += nLineHeight / 2;
00844 rectTarget.left = nX;
00845 rectTarget.top = nY;
00846 rectTarget.right = nX + nLineHeight * 5;
00847 rectTarget.bottom = rectTarget.top + 1;
00848 if (PrintImage(pdevobj, poempdev, hBmp, rectTarget))
00849 nImageHeight = rectTarget.bottom - nY;
00850 ::DeleteObject(hBmp);
00851 }
00852 }
00853 nTextHeight = PrintText(pdevobj, poempdev, nLineHeight, nX + nLineHeight * 5, nY, pso->sizlBitmap.cx - ((2 * nX) + (nLineHeight * 5)), nLineHeight, MakeAnsiString(recText.GetField(_T("Data"))).c_str());
00854 if (nImageHeight == 0)
00855 {
00856
00857 PrintCircle(pdevobj, poempdev, nX + (nLineHeight * 5 / 2), nY + (nLineHeight / 2), nLineHeight / 4);
00858 }
00859 nY += max(nTextHeight, nImageHeight);
00860 }
00861 nY += nLineHeight / 2;
00862 }
00863
00864
00865 CenterText(pdevobj, poempdev, nFontSize, 0, nHeight - 2 * nLineHeight, pso->sizlBitmap.cx, CREATEDBY_TEXT CREATEDBY_LINK);
00866 PrintText(pdevobj, poempdev, CREATEDBY_TEXT);
00867 PrintHyperlink(pdevobj, poempdev, nFontSize, CREATEDBY_LINK_TEXT, (DWORD)strlen(CREATEDBY_LINK_TEXT), CREATEDBY_LINK);
00868
00869
00870 return (((PFN_DrvSendPage)(poempdev->pfnPS[UD_DrvSendPage]))(pso));
00871 }
00872
00873
00874
00880 BOOL APIENTRY OEMStartPage(SURFOBJ* pso)
00881 {
00882 PDEVOBJ pdevobj;
00883 POEMPDEV poempdev;
00884
00885 VERBOSE(DLLTEXT("OEMStartPage() entry.\r\n"));
00886
00887 pdevobj = (PDEVOBJ)pso->dhpdev;
00888 poempdev = (POEMPDEV)pdevobj->pdevOEM;
00889 poempdev->nPage++;
00890
00891
00892
00893
00894
00895
00896 if (poempdev->bLoadedData)
00897 poempdev->bNeedText = poempdev->dataLinks.IsTestPage() || poempdev->dataLinks.GetPageData(poempdev->nPage).HasTextLink();
00898 #ifdef _DEBUG
00899 poempdev->bNeedText = true;
00900 #endif
00901
00902 return (((PFN_DrvStartPage)(poempdev->pfnPS[UD_DrvStartPage]))(pso));
00903
00904 }
00905
00911 BOOL APIENTRY OEMSendPage(SURFOBJ* pso)
00912 {
00913 PDEVOBJ pdevobj;
00914 POEMPDEV poempdev;
00915
00916 VERBOSE(DLLTEXT("OEMSendPage() entry.\r\n"));
00917
00918 pdevobj = (PDEVOBJ)pso->dhpdev;
00919 poempdev = (POEMPDEV)pdevobj->pdevOEM;
00920
00921
00922 POEMDEV pDevMode = (POEMDEV)pdevobj->pOEMDM;
00923 if (poempdev->dataLinks.HasData())
00924 {
00925 poempdev->bUsedPrintData = true;
00926 RECTL rcArea;
00927
00928
00929 VERBOSE(DLLTEXT("Processing page %d for links\r\n"), poempdev->nPage);
00930 if (poempdev->dataLinks.IsTestPage())
00931 {
00932
00933 if (poempdev->oText.empty())
00934 {
00935
00936 poempdev->bUsedPrintData = false;
00937 }
00938 else
00939 {
00940
00941 if (poempdev->nPage == 1)
00942 {
00943
00944 CCPrintData dataCompute;
00945 dataCompute.SetTestPage();
00946
00947
00948 const CCPrintData::PageData& data = poempdev->dataLinks.GetPageData(poempdev->nPage);
00949 for (CCPrintData::PageData::const_iterator i = data.begin(); i != data.end(); i++)
00950 {
00951
00952 const CCPrintData::LinkData& link = (*i);
00953 ASSERT(!link.IsLocation());
00954 ASSERT(link.nRepeat == 1);
00955
00956
00957 poempdev->oText.InitSearch();
00958 STRLIST words;
00959 words.push_back(link.sText);
00960
00961 if (poempdev->oText.SearchFor(words, rcArea, link.nRepeat))
00962
00963 dataCompute.AddLink(link.sURL, rcArea, 1);
00964 }
00965
00966 dataCompute.SetPageSize(1, pso->sizlBitmap);
00967 dataCompute.UpdateProcessData(pdevobj->hPrinter);
00968
00969 poempdev->bUsedPrintData = false;
00970 }
00971 }
00972 }
00973 else
00974 {
00975
00976 const CCPrintData::PageData& data = poempdev->dataLinks.GetPageData(poempdev->nPage);
00977 if (!data.empty())
00978 {
00979
00980 poempdev->oText.InitSearch();
00981 for (CCPrintData::PageData::const_iterator i = data.begin(); i != data.end(); i++)
00982 {
00983
00984 const CCPrintData::LinkData& link = (*i);
00985
00986
00987 if (link.IsLocation())
00988 {
00989
00990 if (link.IsInner())
00991 {
00992
00993 PrintInternalLink(pdevobj, poempdev, link.rectLocation, link.nPage, link.ptOffset.x, link.ptOffset.y);
00994 }
00995 else
00996 {
00997
00998 poempdev->pLinks = new InnerEscapeLinkData(link.rectLocation, MakeAnsiString(link.sURL).c_str(), poempdev->pLinks, link.sTitle.empty() ? NULL : MakeAnsiString(link.sTitle).c_str());
00999 VERBOSE(DLLTEXT("Adding location-based link to %s:\r\n(%d,%d)-(%d,%d)\r\n"), link.sURL.c_str(), link.rectLocation.left, link.rectLocation.top, link.rectLocation.right, link.rectLocation.bottom);
01000 }
01001 }
01002 else
01003 {
01004
01005 std::tstring::size_type pos = link.sText.find(' '), oldpos = 0;
01006 STRLIST words;
01007 while ((oldpos < link.sText.size()) && (pos != std::tstring::npos))
01008 {
01009 if (pos > oldpos)
01010 words.push_back(link.sText.substr(oldpos, pos - oldpos));
01011 oldpos = pos + 1;
01012 pos = link.sText.find(' ', oldpos);
01013 }
01014 if (oldpos < link.sText.size())
01015 words.push_back(link.sText.substr(oldpos));
01016
01017
01018 if (!poempdev->oText.SearchFor(words, rcArea, link.nRepeat))
01019 break;
01020
01021 poempdev->pLinks = new InnerEscapeLinkData(rcArea, MakeAnsiString(link.sURL).c_str(), poempdev->pLinks, link.sTitle.empty() ? NULL : MakeAnsiString(link.sTitle).c_str());
01022 }
01023 }
01024 }
01025 }
01026 }
01027 else if (pDevMode->bAutoURLs)
01028 {
01029
01030 std::wstring sURL;
01031 RECTL rcArea;
01032 poempdev->oText.InitSearch();
01033 while (poempdev->oText.SearchForURL(rcArea, sURL))
01034
01035 poempdev->pLinks = new InnerEscapeLinkData(rcArea, MakeAnsiString(sURL).c_str(), poempdev->pLinks);
01036 }
01037 poempdev->oText.clear();
01038
01039
01040 if (poempdev->pLinks != NULL)
01041 {
01042 while (poempdev->pLinks != NULL)
01043 {
01044
01045 InnerEscapeLinkData* pLink = (InnerEscapeLinkData*)poempdev->pLinks;
01046 poempdev->pLinks = pLink->pNext;
01047
01048
01049 RECTL rectTarget;
01050 rectTarget.left = pLink->pData->left;
01051 rectTarget.top = pLink->pData->top;
01052 rectTarget.right = pLink->pData->right;
01053 rectTarget.bottom = pLink->pData->bottom;
01054
01055 if (pLink->pData->lTitleOffset > 0)
01056
01057 PrintURLLink(pdevobj, poempdev, pLink->pData->url, rectTarget, pLink->pData->url + pLink->pData->lTitleOffset);
01058 else
01059
01060 PrintURLLink(pdevobj, poempdev, pLink->pData->url, rectTarget);
01061
01062 delete pLink;
01063 }
01064 }
01065
01066
01067 bool bFirstPage = poempdev->nPage == 1;
01068 LicenseLocation eLocation = LLNone;
01069 if (bFirstPage)
01070 eLocation = pDevMode->location.eFirstPage;
01071 else
01072 {
01073 eLocation = pDevMode->location.eOtherPages;
01074 if (eLocation == LLOther)
01075 eLocation = pDevMode->location.eFirstPage;
01076 }
01077
01078 if (bFirstPage && pDevMode->bSetProperties)
01079 {
01080
01081 switch (pDevMode->info.m_eLicense)
01082 {
01083 case LicenseInfo::LTPublicDomain:
01084
01085 {
01086 char c[2048];
01087 sprintf_s(c, _S(c), PS_NO_LICENSE_INFO);
01088 std::string sURL = MakeAnsiString(pDevMode->info.m_cURI);
01089 AddPSText(c, sURL);
01090 strcat_s(c, _S(c), PS_LICENSE_INFO_END);
01091 PrintPS(pdevobj, poempdev, c);
01092 }
01093 break;
01094 case LicenseInfo::LTNone:
01095 case LicenseInfo::LTUnknown:
01096
01097 break;
01098 default:
01099
01100 {
01101 char c[2048];
01102 sprintf_s(c, _S(c), PS_LICENSE_INFO_START);
01103 std::string sURL = MakeAnsiString(pDevMode->info.m_cURI), sName = MakeAnsiString(pDevMode->info.m_cName);
01104 AddPSText(c, sURL);
01105 strcat_s(c, _S(c), PS_LICENSE_INFO_CONTINUE);
01106 AddPSText(c, sName);
01107 strcat_s(c, _S(c), " license ");
01108 AddPSText(c, sURL);
01109 strcat_s(c, _S(c), PS_LICENSE_INFO_END);
01110 PrintPS(pdevobj, poempdev, c);
01111 }
01112 break;
01113 }
01114
01115 }
01116
01117 if (eLocation != LLNone)
01118 {
01119
01120 UINT uImage = GetLicenseImage(pDevMode->info);
01121 if (uImage > 0)
01122 {
01123
01124 PngImage png;
01125 if (png.LoadFromResource(uImage, true, ghInstance))
01126 {
01127
01128 RECTL rectTarget;
01129 SIZEL szTarget;
01130 double dMultiplier = 1.0;
01131 if (pdevobj->pPublicDM->dmPrintQuality > 0)
01132 dMultiplier = pdevobj->pPublicDM->dmPrintQuality / 72.0;
01133 szTarget.cx = (long) (png.GetWidth() * dMultiplier);
01134 szTarget.cy = (long) (png.GetHeight() * dMultiplier);
01135
01136 POINT ptTarget = pDevMode->location.LocationForPage(bFirstPage, pso->sizlBitmap, szTarget);
01137 rectTarget.left = ptTarget.x;
01138 rectTarget.top = ptTarget.y;
01139 rectTarget.right = rectTarget.left + szTarget.cx;
01140 rectTarget.bottom = rectTarget.top + szTarget.cy;
01141
01142 DrawImage(pso, png, rectTarget);
01143
01144
01145 switch (pDevMode->info.m_eLicense)
01146 {
01147 case LicenseInfo::LTCC:
01148 case LicenseInfo::LTSampling:
01149 case LicenseInfo::LTDevelopingNations:
01150 PrintJumpLink(pdevobj, poempdev, "TheLicense", rectTarget);
01151 break;
01152 default:
01153 if (pDevMode->info.m_cURI[0] != '\0')
01154 PrintURLLink(pdevobj, poempdev, MakeAnsiString(&pDevMode->info.m_cURI[0]).c_str(), rectTarget);
01155 break;
01156 }
01157 }
01158 }
01159 }
01160
01161
01162
01163
01164
01165 return (((PFN_DrvSendPage)(poempdev->pfnPS[UD_DrvSendPage]))(pso));
01166
01167 }
01168
01176 BOOL APIENTRY OEMStartDoc(SURFOBJ* pso, PWSTR pwszDocName,DWORD dwJobId)
01177 {
01178 PDEVOBJ pdevobj;
01179 POEMPDEV poempdev;
01180
01181 VERBOSE(DLLTEXT("OEMStartDoc() entry.\r\n"));
01182
01183 pdevobj = (PDEVOBJ)pso->dhpdev;
01184 poempdev = (POEMPDEV)pdevobj->pdevOEM;
01185
01186
01187
01188
01189
01190 if (!(((PFN_DrvStartDoc)(poempdev->pfnPS[UD_DrvStartDoc])) (
01191 pso,
01192 pwszDocName,
01193 dwJobId)))
01194 return FALSE;
01195
01196 POEMDEV pDevMode = (POEMDEV)pdevobj->pOEMDM;
01197 std::string sFilename = MakeAnsiString(pDevMode->cFilename);
01198
01199 poempdev->pLinks = NULL;
01200 if (poempdev->pTranslator == NULL)
01201 poempdev->pTranslator = new GlyphTranslator;
01202 poempdev->bNeedText = pDevMode->bAutoURLs ? true : false;
01203
01204
01205 poempdev->bUsedPrintData = false;
01206 if (poempdev->bLoadedData = poempdev->dataLinks.LoadProcessData(pdevobj->hPrinter))
01207 {
01208 VERBOSE(DLLTEXT("Found process data\r\n"));
01209 pDevMode->bAutoURLs = false;
01210 if (poempdev->dataLinks.IsTestPage())
01211 {
01212 if (poempdev->dataLinks.GetPageCount() != 1)
01213 poempdev->dataLinks.SetTestPage(false);
01214 else
01215 {
01216 poempdev->bNeedText = true;
01217 sFilename = ":dropfile:";
01218 }
01219 }
01220 }
01221
01222
01223 if (!sFilename.empty())
01224 {
01225
01226 sFilename = "%%File: " + sFilename + "\r\n";
01227 DWORD dwResult;
01228 std::tstring::size_type dwLen = sFilename.size();
01229
01230 poempdev->pOEMHelp->DrvWriteSpoolBuf(pdevobj, (LPVOID)sFilename.c_str(), (DWORD)dwLen, &dwResult);
01231 if (dwResult != dwLen)
01232 return FALSE;
01233
01234
01235 if (pDevMode->bAutoOpen)
01236 {
01237 if (pDevMode->bCreateAsTemp)
01238 sFilename = "%%CreateAsTemp\r\n";
01239 else
01240 sFilename = "%%FileAutoOpen\r\n";
01241 dwLen = (DWORD) sFilename.size();
01242 poempdev->pOEMHelp->DrvWriteSpoolBuf(pdevobj, (LPVOID)sFilename.c_str(), (DWORD)dwLen, &dwResult);
01243 if (dwResult != dwLen)
01244 return FALSE;
01245
01246 }
01247 }
01248
01249 return TRUE;
01250 }
01251
01258 BOOL APIENTRY OEMEndDoc(SURFOBJ* pso, FLONG fl)
01259 {
01260 PDEVOBJ pdevobj;
01261 POEMPDEV poempdev;
01262
01263 VERBOSE(DLLTEXT("OEMEndDoc() entry.\r\n"));
01264
01265
01266 pdevobj = (PDEVOBJ)pso->dhpdev;
01267 poempdev = (POEMPDEV)pdevobj->pdevOEM;
01268 POEMDEV pDevMode = (POEMDEV)pdevobj->pOEMDM;
01269
01270
01271 if (poempdev->pTranslator != NULL)
01272 {
01273 delete poempdev->pTranslator;
01274 poempdev->pTranslator = NULL;
01275 }
01276
01277 if (poempdev->bUsedPrintData)
01278 {
01279 poempdev->dataLinks.CleanSaved(pdevobj->hPrinter);
01280 }
01281
01282 if (fl != ED_ABORTDOC)
01283 {
01284 switch (pDevMode->info.m_eLicense)
01285 {
01286 case LicenseInfo::LTCC:
01287 case LicenseInfo::LTSampling:
01288 case LicenseInfo::LTDevelopingNations:
01289
01290 if (!OEMStartPage(pso))
01291 return FALSE;
01292 if (!DoLicensePage(pso))
01293 return FALSE;
01294 break;
01295 }
01296 }
01297
01298
01299
01300
01301
01302 return (((PFN_DrvEndDoc)(poempdev->pfnPS[UD_DrvEndDoc])) (
01303 pso,
01304 fl));
01305
01306 }
01307
01320 ULONG APIENTRY OEMEscape(SURFOBJ* pso, ULONG iEsc, ULONG cjIn, PVOID pvIn, ULONG cjOut, PVOID pvOut)
01321 {
01322 PDEVOBJ pdevobj;
01323 POEMPDEV poempdev;
01324
01325
01326 pdevobj = (PDEVOBJ)pso->dhpdev;
01327 poempdev = (POEMPDEV)pdevobj->pdevOEM;
01328
01329
01330 if ((iEsc == QUERYESCSUPPORT) && (cjIn == 4))
01331 {
01332
01333 DWORD* pQuery = (DWORD*)pvIn;
01334 switch (*pQuery)
01335 {
01336 case ESCAPE_LINK_DATA:
01337 case ESCAPE_DISABLE_AUTO_URL:
01338
01339 return TRUE;
01340 default:
01341 break;
01342 }
01343 }
01344 else
01345 {
01346 #ifdef _DEBUG
01347 VERBOSE(DLLTEXT("OEMEscape(%d, %d, %p) entry.\r\n"), iEsc, cjIn, pvIn);
01348 if (cjIn == 4)
01349 {
01350 VERBOSE(DLLTEXT("... Data: %p\r\n"), *((DWORD*)pvIn));
01351 }
01352 #endif
01353
01354
01355 switch (iEsc)
01356 {
01357 case ESCAPE_LINK_DATA:
01358
01359 VERBOSE(DLLTEXT("OEMEscape: size(%d,%d), logpixel(%d)\r\n"), pso->sizlBitmap.cx, pso->sizlBitmap.cy, pdevobj->pPublicDM->dmLogPixels);
01360 if (cjIn < sizeof(EscapeLinkData))
01361 return FALSE;
01362
01363 poempdev->pLinks = new InnerEscapeLinkData((const char*)pvIn, cjIn, poempdev->pLinks);
01364 return TRUE;
01365 case ESCAPE_DISABLE_AUTO_URL:
01366
01367 poempdev->bNeedText = false;
01368 return TRUE;
01369 }
01370 }
01371
01372
01373 return (((PFN_DrvEscape)(poempdev->pfnPS[UD_DrvEscape])) (pso, iEsc, cjIn, pvIn, cjOut, pvOut));
01374 }
01375
01376
01391 BOOL APIENTRY OEMTextOut(SURFOBJ *pso, STROBJ *pstro, FONTOBJ *pfo, CLIPOBJ *pco, RECTL *prclExtra, RECTL *prclOpaque, BRUSHOBJ *pboFore, BRUSHOBJ *pboOpaque, POINTL *pptlOrg, MIX mix)
01392 {
01393 PDEVOBJ pdevobj;
01394 POEMPDEV poempdev;
01395 VERBOSE(DLLTEXT("OEMTextOut\r\n"));
01396
01397
01398 pdevobj = (PDEVOBJ)pso->dhpdev;
01399 poempdev = (POEMPDEV)pdevobj->pdevOEM;
01400
01401
01402 if (poempdev->bNeedText && ((pstro->cGlyphs > 0) && (pstro->pwszOrg != NULL)))
01403 {
01404
01405 PGLYPHPOS pGlyphPos;
01406 POINTQF* pWidths = NULL;
01407 bool bValid = false;
01408
01409
01410 if (pstro->ulCharInc == 0)
01411 {
01412
01413 ULONG uCount;
01414 BOOL bRet = STROBJ_bEnumPositionsOnly(pstro, &uCount, &pGlyphPos);
01415
01416 if ((bRet != DDI_ERROR) && (uCount == pstro->cGlyphs))
01417 {
01418 pWidths = new POINTQF[uCount];
01419 if (STROBJ_bGetAdvanceWidths(pstro, 0, uCount, pWidths))
01420 bValid = true;
01421 }
01422 }
01423 else
01424 bValid = true;
01425
01426 if (bValid)
01427 {
01428
01429 std::wstring sText;
01430 if ((pstro->flAccel & SO_GLYPHINDEX_TEXTOUT) != 0)
01431 {
01432
01433 const GlyphToText* pGlyphMap = NULL;
01434 PIFIMETRICS pifi;
01435
01436 TRACE(DLLTEXT("Found glyph text:\r\n"));
01437
01438
01439 pifi = FONTOBJ_pifi(pfo);
01440 if (pifi != NULL)
01441 {
01442 LOGFONT lfFont;
01443
01444 XFORMOBJ* pFormObj = FONTOBJ_pxoGetXform(pfo);
01445 XFORML xForm;
01446 ULONG uXForm = XFORMOBJ_iGetXform(pFormObj, &xForm);
01447
01448 double dXScale = sqrt(xForm.eM11 * xForm.eM11 + xForm.eM12 * xForm.eM12);
01449 double dYScale = sqrt(xForm.eM22 * xForm.eM22 + xForm.eM21 * xForm.eM21);
01450
01451
01452 lfFont.lfHeight = (int)(0.5 + dYScale * pifi->fwdUnitsPerEm * 72) / pfo->sizLogResPpi.cy;
01453 lfFont.lfWidth = 0;
01454 lfFont.lfEscapement = 0;
01455 lfFont.lfOrientation = 0;
01456 lfFont.lfWeight = pifi->usWinWeight;
01457 lfFont.lfItalic = (pifi->fsSelection & FM_SEL_ITALIC) ? TRUE : FALSE;
01458 lfFont.lfUnderline = (pifi->fsSelection & FM_SEL_UNDERSCORE) ? TRUE : FALSE;
01459 lfFont.lfStrikeOut = (pifi->fsSelection & FM_SEL_STRIKEOUT) ? TRUE : FALSE;
01460 lfFont.lfCharSet = pifi->jWinCharSet;
01461 lfFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
01462 lfFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
01463 lfFont.lfQuality = DEFAULT_QUALITY;
01464 lfFont.lfPitchAndFamily = pifi->jWinPitchAndFamily;
01465 wcsncpy_s(lfFont.lfFaceName, _S(lfFont.lfFaceName), (TCHAR*)(((char*)pifi) + (DWORD)pifi->dpwszFamilyName), LF_FACESIZE);
01466
01467
01468 pGlyphMap = (poempdev->pTranslator == NULL) ? NULL : poempdev->pTranslator->GetFontTranslation(lfFont);
01469 if (pGlyphMap != NULL)
01470 {
01471
01472 GlyphToText::const_iterator iChar;
01473 for (unsigned int i=0;i<pstro->cGlyphs;i++)
01474 {
01475
01476 iChar = pGlyphMap->find(pstro->pwszOrg[i]);
01477 if (iChar != pGlyphMap->end())
01478 sText += (*iChar).second;
01479 else
01480 sText += (WCHAR)0x7F;
01481 }
01482 TRACE(DLLTEXT("%s\r\n"), sText.c_str());
01483 }
01484 }
01485 if (sText.empty())
01486 {
01487 TRACE(DLLTEXT("Could not unglyph it...\r\n"));
01488 }
01489 }
01490 else
01491 {
01492
01493 sText.assign(pstro->pwszOrg, pstro->cGlyphs);
01494 TRACE(DLLTEXT("Got the following text:\r\n"));
01495 }
01496
01497 if (!sText.empty())
01498 {
01499
01500 TRACE(DLLTEXT("%s [at %d,%d-%d,%d]\r\n"), sText.c_str(), pstro->rclBkGround.left, pstro->rclBkGround.top, pstro->rclBkGround.right, pstro->rclBkGround.bottom);
01501
01502
01503 if (pstro->ulCharInc == 0)
01504 {
01505
01506 ASSERT(pWidths != NULL);
01507 poempdev->oText.AddLine(TextLine(sText, pstro->rclBkGround, pGlyphPos, pWidths));
01508 delete [] pWidths;
01509 }
01510 else
01511 {
01512
01513 ASSERT(pWidths == NULL);
01514 poempdev->oText.AddLine(TextLine(sText, pstro->rclBkGround, pstro->ulCharInc));
01515 }
01516 }
01517 }
01518 }
01519
01520
01521 return (((PFN_DrvTextOut)(poempdev->pfnPS[UD_DrvTextOut])) (pso, pstro, pfo, pco, prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix));
01522 }