| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #ifdef AFX_PRINT_SEG
- #pragma code_seg(AFX_PRINT_SEG)
- #endif
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define new DEBUG_NEW
- /////////////////////////////////////////////////////////////////////////////
- // CMetaFileDC
- CMetaFileDC::CMetaFileDC()
- {
- }
- void CMetaFileDC::SetOutputDC(HDC)
- {
- TRACE0("Must use Create() or Get() to set Metafile Output DC.\n");
- ASSERT(FALSE);
- }
- void CMetaFileDC::ReleaseOutputDC()
- {
- TRACE0("Must use Close() to release output Metafile DC.\n");
- ASSERT(FALSE);
- }
- void CMetaFileDC::SetAttribDC(HDC hDC) // Set the Attribute DC
- {
- if (hDC != m_hDC)
- CDC::SetAttribDC(hDC);
- if (m_hDC == m_hAttribDC) // if we somehow got to this, correct it
- ReleaseAttribDC();
- }
- CMetaFileDC::~CMetaFileDC()
- {
- if (m_hDC != NULL) // Must be not wanting to keep the metafile
- {
- TRACE0("Warning! Destroying CMetaFileDC without closing.\n");
- HMETAFILE hmfTemp = Close();
- ::DeleteMetaFile(hmfTemp);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // Device-Context Functions
- // Clipping Functions
- // Normally both Set and Get clipping functions go directly to the output DC
- // With metafiles, we must mirror to both DCs and ask the Attribute DC for
- // the Get.
- int CMetaFileDC::GetClipBox(LPRECT lpRect) const
- {
- ASSERT(m_hAttribDC != NULL);
- ASSERT(lpRect != NULL);
- ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT)));
- return ::GetClipBox(m_hAttribDC, lpRect);
- }
- BOOL CMetaFileDC::PtVisible(int x, int y) const
- {
- ASSERT(m_hAttribDC != NULL);
- return ::PtVisible(m_hAttribDC, x, y);
- }
- BOOL CMetaFileDC::RectVisible(LPCRECT) const
- {
- ASSERT(m_hAttribDC != NULL);
- return TRUE; // rect is always visible for metafiles
- }
- // Text Functions
- BOOL CMetaFileDC::TextOut(int x, int y, LPCTSTR lpszString, int nCount)
- {
- ASSERT(m_hDC != NULL);
- ASSERT(m_hDC != m_hAttribDC);
- ASSERT(lpszString != NULL);
- ASSERT(AfxIsValidAddress(lpszString, nCount, FALSE));
- BOOL bSuccess = ::TextOut(m_hDC, x, y, lpszString, nCount);
- if (bSuccess && m_hAttribDC != NULL && (GetTextAlign() & TA_UPDATECP))
- {
- CSize size = GetTextExtent(lpszString, nCount);
- TEXTMETRIC tm;
- GetTextMetrics(&tm);
- AdjustCP(size.cx - tm.tmOverhang);
- }
- return bSuccess;
- }
- BOOL CMetaFileDC::ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect,
- LPCTSTR lpszString, UINT nCount, LPINT lpDxWidths)
- {
- ASSERT(m_hDC != NULL);
- ASSERT(m_hDC != m_hAttribDC);
- ASSERT(lpszString != NULL);
- ASSERT(lpDxWidths == NULL ||
- AfxIsValidAddress(lpDxWidths, sizeof(int) * nCount, FALSE));
- ASSERT(AfxIsValidAddress(lpszString, nCount, FALSE));
- BOOL bSuccess = ::ExtTextOut(m_hDC, x, y, nOptions, lpRect,
- lpszString, nCount, lpDxWidths);
- if (bSuccess && m_hAttribDC != NULL && (GetTextAlign() & TA_UPDATECP))
- {
- int nWidth = 0;
- for (UINT i = 0; i < nCount; i++)
- nWidth += *lpDxWidths++;
- AdjustCP(nWidth);
- }
- return bSuccess;
- }
- CSize CMetaFileDC::TabbedTextOut(int x, int y, LPCTSTR lpszString,
- int nCount, int nTabPositions, LPINT lpnTabStopPositions, int nTabOrigin)
- {
- ASSERT(m_hDC != NULL);
- ASSERT(m_hAttribDC != NULL);
- ASSERT(m_hDC != m_hAttribDC);
- ASSERT(lpszString != NULL);
- ASSERT(AfxIsValidAddress(lpszString, nCount, FALSE));
- int xStart = x;
- CSize size;
- int cxTabStop = 0;
- int cxDefaultTab = (int)LOWORD(
- ::GetTabbedTextExtentA(m_hAttribDC, "\t", 1, 0, NULL));
- if (!lpnTabStopPositions)
- {
- // no tab stops given, use default tab stop
- cxTabStop = cxDefaultTab;
- }
- else if (nTabPositions == 1)
- {
- // one tab stop given, use it instead of default tab stop
- cxTabStop = lpnTabStopPositions[0];
- if (cxTabStop == 0)
- cxTabStop = 1;
- }
- // write the string out in tab delimited runs
- while (nCount != 0)
- {
- // find next tab character
- LPCTSTR lpszTab = lpszString;
- while (nCount != 0 && *lpszTab != '\t')
- {
- if (_istlead(*lpszTab))
- ++lpszTab, --nCount;
- ++lpszTab;
- --nCount;
- }
- // write the string
- int nChars = lpszTab - lpszString;
- ::TextOut(m_hDC, x, y, lpszString, nChars);
- // advance by its extent
- CSize size;
- ::GetTextExtentPoint32(m_hAttribDC, lpszString, nChars, &size);
- x += size.cx;
- // advance current x co-ordinate based on tab stops
- if (nCount != 0)
- {
- ASSERT(*lpszTab == '\t');
- lpszString = lpszTab + 1; // skip over the tab
- --nCount;
- // calculate next x position based on tab stops
- if (cxTabStop == 0)
- {
- for (int i = 0; i < nTabPositions; i++)
- {
- if (x < lpnTabStopPositions[i]+nTabOrigin)
- {
- x = lpnTabStopPositions[i]+nTabOrigin;
- break;
- }
- }
- if (i == nTabPositions)
- {
- // when all out of tab stops, go back to default tab stops
- cxTabStop = cxDefaultTab;
- }
- }
- if (cxTabStop != 0)
- {
- // advance based on single tab stop
- x = ((x - nTabOrigin) / cxTabStop) * cxTabStop +
- cxTabStop + nTabOrigin;
- }
- }
- }
- // adjust the current position
- if (m_hAttribDC != NULL && (GetTextAlign() & TA_UPDATECP))
- {
- TEXTMETRIC tm;
- GetTextMetrics(&tm);
- AdjustCP(x - xStart - tm.tmOverhang);
- }
- // return the extent
- size.cx = x - xStart;
- return size;
- }
- void CMetaFileDC::AdjustCP(int cx)
- {
- if (m_hAttribDC == NULL)
- return; // do nothing
- UINT nAlign = GetTextAlign() & (TA_LEFT|TA_CENTER|TA_RIGHT);
- if (nAlign == TA_CENTER)
- return; // Center Alignment does not affect CP
- if (nAlign == TA_RIGHT)
- cx = -cx;
- CPoint point = GetCurrentPosition();
- point.x += cx;
- ::MoveToEx(m_hAttribDC, point.x, point.y, NULL);
- }
- int CMetaFileDC::DrawText(LPCTSTR lpszString, int nCount, LPRECT lpRect,
- UINT nFormat)
- {
- ASSERT(m_hDC != NULL);
- ASSERT(m_hDC != m_hAttribDC);
- ASSERT(lpszString != NULL);
- ASSERT(lpRect != NULL);
- ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT)));
- ASSERT(nCount == -1 || AfxIsValidAddress(lpszString, nCount, FALSE));
- int nHeight = ::DrawText(m_hDC, lpszString, nCount, lpRect, nFormat);
- // If adjusting CP:
- if (m_hAttribDC != NULL &&
- (GetTextAlign() & TA_UPDATECP) && ((nFormat & DT_CALCRECT) == 0))
- {
- CRect rect(lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
- nHeight = ::DrawText(m_hAttribDC, lpszString, nCount, &rect,
- nFormat | DT_CALCRECT | DT_SINGLELINE);
- AdjustCP(rect.Width());
- }
- return nHeight;
- }
- // Printer Escape Functions
- int CMetaFileDC::Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData)
- {
- ASSERT(m_hDC != NULL);
- ASSERT(m_hDC != m_hAttribDC);
- int nRet = ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData);
- if (m_hAttribDC == NULL)
- return nRet;
- // The tact here is to NOT allow any of the document control escapes
- // to be passed through. Elimination of StartDoc and EndDoc should
- // eliminate anything actually going to the printer. Also anything
- // that actually draws something will be filtered.
- //
- switch (nEscape)
- {
- case NEXTBAND:
- case SETCOLORTABLE:
- case GETCOLORTABLE:
- case FLUSHOUTPUT:
- case DRAFTMODE:
- case QUERYESCSUPPORT:
- case GETPHYSPAGESIZE:
- case GETPRINTINGOFFSET:
- case GETSCALINGFACTOR:
- case GETPENWIDTH:
- case SETCOPYCOUNT:
- case SELECTPAPERSOURCE:
- case GETTECHNOLOGY:
- case SETLINECAP:
- case SETLINEJOIN:
- case SETMITERLIMIT:
- case BANDINFO:
- case GETVECTORPENSIZE:
- case GETVECTORBRUSHSIZE:
- case ENABLEDUPLEX:
- case GETSETPAPERBINS:
- case GETSETPRINTORIENT:
- case ENUMPAPERBINS:
- case SETDIBSCALING:
- case ENUMPAPERMETRICS:
- case GETSETPAPERMETRICS:
- case GETEXTENDEDTEXTMETRICS:
- case GETEXTENTTABLE:
- case GETPAIRKERNTABLE:
- case GETTRACKKERNTABLE:
- case ENABLERELATIVEWIDTHS:
- case ENABLEPAIRKERNING:
- case SETKERNTRACK:
- case SETALLJUSTVALUES:
- case SETCHARSET:
- case SET_BACKGROUND_COLOR:
- case SET_SCREEN_ANGLE:
- case SET_SPREAD:
- return ::Escape(m_hAttribDC, nEscape, nCount, lpszInData, lpOutData);
- default:
- break; // return output DC return value
- }
- return nRet;
- }
- // Viewport origin and Viewport extent overrides
- // (usually, don't modify viewport orgin and extent on the output dc)
- CPoint CMetaFileDC::SetViewportOrg(int x, int y)
- {
- ASSERT(m_hDC != NULL);
- CPoint point;
- if (m_hAttribDC == NULL)
- ::SetViewportOrgEx(m_hDC, x, y, &point);
- else
- ::SetViewportOrgEx(m_hAttribDC, x, y, &point);
- return point;
- }
- CPoint CMetaFileDC::OffsetViewportOrg(int nWidth, int nHeight)
- {
- ASSERT(m_hDC != NULL);
- CPoint point;
- if (m_hAttribDC == NULL)
- ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, &point);
- else
- ::OffsetViewportOrgEx(m_hAttribDC, nWidth, nHeight, &point);
- return point;
- }
- CSize CMetaFileDC::SetViewportExt(int x, int y)
- {
- ASSERT(m_hDC != NULL);
- CSize size;
- if (m_hAttribDC == NULL)
- ::SetViewportExtEx(m_hDC, x, y, &size);
- else
- ::SetViewportExtEx(m_hAttribDC, x, y, &size);
- return size;
- }
- CSize CMetaFileDC::ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom)
- {
- ASSERT(m_hDC != NULL);
- CSize size;
- if (m_hAttribDC == NULL)
- ::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, &size);
- else
- ::ScaleViewportExtEx(m_hAttribDC, xNum, xDenom, yNum, yDenom, &size);
- return size;
- }
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
- IMPLEMENT_DYNAMIC(CMetaFileDC, CDC)
- /////////////////////////////////////////////////////////////////////////////
|