#include "stdafx.h" #include "SigmaView.h" #include "SigmaDoc.h" #include "SectionDoc.h" #include "ItemText.h" #include "ItemSelect.h" #include "ActionModifiedItem.h" #include "DCHelp.h" #pragma pack(1) struct TextInformation { LPCTSTR text; double textHeight; double textWidth; double angle; int bUpDown; //是否按上下角标方式显示 int r; int g; int b; void * textArr; int lenOfTextArr; double x; double y; int textHeightOfDisplayed; //文字的显示高度 }; #pragma pack() #pragma pack(1) struct MYLOGFONT { LONG lfHeight; LONG lfWidth; LONG lfEscapement; LONG lfOrientation; LONG lfWeight; BYTE lfItalic; BYTE lfUnderline; BYTE lfStrikeOut; BYTE lfCharSet; BYTE lfOutPrecision; BYTE lfClipPrecision; BYTE lfQuality; BYTE lfPitchAndFamily; WCHAR lfFaceName[LF_FACESIZE]; }; #pragma pack() wchar_t * AsciiToUnicodeChar(const char * str); char * UnicodeToAscii(const WCHAR* str, char * buffer, int lenOfBuffer);; static CItemText * getItemText(CSigmaView * pView); static CItemSelect * getItemSelect(CSigmaView * pView); static CText * GetCText(CSigmaView * pView); static int SetTextInfoForCItemText(CSigmaView * pView, TextInformation * pInfo, HDC hdc); static int SetTextInfoForCText(CSigmaView * pView, TextInformation * pInfo, HDC hdc); static void FillTextInformationFromCText(TextInformation * pInfo, CText * pText, CSigmaView * pView); static int SetFontForCItemText(CSigmaView * pView, MYLOGFONT * myFont, HDC hdc); static int SetFontForCText(CSigmaView * pView, MYLOGFONT * myFont, HDC hdc); void DrawTextOnScreen(CXyDC* pXyDC, CDC* pScreenDC, CText * pText, CRect clientRect, CDC * pBackGroundDC); extern "C" __declspec(dllexport) int Text_CalculateScreenRect(CSigmaView * pView, BYTE* buffElement, int buffLen , double* left, double* top, double* right, double* bottom, double * fontWidth, double * fontHeight) { //CText* pText = new CText(); COne* pOne = new COne; pOne->SetType(DOUBLEFOX_TEXT); pOne->ReadMemory(buffElement, -1, buffLen, 3); CText* pText = (CText*)(pOne->value); pText->color = pOne->color; CXyDC* pXyDC = &(pView->m_pDoc->GetDC()); CDC* pBakDC = pXyDC->GetDC(); CRect BakRT = pXyDC->GetViewRect(); CMemoryDC *pImageDC = new CMemoryDC; CSize sizeOld; sizeOld.cx = BakRT.Width(); sizeOld.cy = BakRT.Height(); if (!pImageDC->Create(sizeOld)) { delete pImageDC; pImageDC = nullptr; return 0; } pXyDC->Create(pImageDC); // 获得范围 CPoint point; if (!pText->IsImmovableSize()) { CSize8 sz = pText->m_size; //Rotate(sz.cx, sz.cy, aa); sz = pXyDC->GetScreenSize8(sz); sz.cy *= -1; point.x = AfxGetPublicFunction()->FloatToLong(sz.cx); point.y = AfxGetPublicFunction()->FloatToLong(sz.cy); //if (point.x < 2 || point.y < 2) //{ // COLORREF bc = pDC->GetTextColor(); // SetPixel(text.x0, text.y0, pf.GetColor(bc)); // return; //} if (point.x > USHRT_MAX / 10 || point.y > USHRT_MAX / 10) { delete pImageDC; pImageDC = nullptr; return 0; } pText->m_logFont.lfWidth = point.x; if (pText->m_logFont.lfWidth < 1) pText->m_logFont.lfWidth = 1; pText->m_logFont.lfHeight = point.y; if (pText->m_logFont.lfHeight < 1) pText->m_logFont.lfHeight = 1; pText->m_logFont.lfEscapement = 0; //字体高度与磅值有如下的换算公式 //text.m_logFont.lfWidth = MulDiv(text.m_logFont.lfWidth, GetDeviceCaps(pDC->GetSafeHdc(), LOGPIXELSX), 72); //text.m_logFont.lfHeight = MulDiv(text.m_logFont.lfHeight, GetDeviceCaps(pDC->GetSafeHdc(), LOGPIXELSY), 72); } point.x = pXyDC->GetSX(pText->x0); point.y = pXyDC->GetSY(pText->y0); CRect rect(point, point); CFont font; font.CreateFontIndirect(&pText->m_logFont); pImageDC->SelectObject(&font); pImageDC->DrawText(pText->GetName(), rect, DT_CALCRECT); *fontWidth = pText->m_logFont.lfWidth; *fontHeight = pText->m_logFont.lfHeight; // 还原DC pXyDC->Create(pBakDC); CRect8 rt8Real = pXyDC->GetReal(rect); rt8Real.NormalizeRect(); pText->Aligns(rt8Real); CRect8 rt8 = pXyDC->GetScreen8(rt8Real); CRect8 posRect = pOne->GetRect(); TRACE("Old_m_posRect:%lf,%lf,%lf,%lf,%lf,%lf\r\n" , posRect.left, posRect.top, posRect.right, posRect.bottom, posRect.Width(), posRect.Height()); posRect.SetRect(rt8.left, rt8.top, rt8.right, rt8.bottom+1); TRACE("New_m_posRect:%lf,%lf,%lf,%lf%lf,%lf\r\n" , posRect.left, posRect.top, posRect.right, posRect.bottom, posRect.Width(), posRect.Height()); delete pImageDC; pImageDC = nullptr; delete pOne; pOne = nullptr; *left = posRect.left; *top = posRect.top; *right = posRect.right; *bottom = posRect.bottom; return 1; } extern "C" __declspec(dllexport) int Text_SetTextInfo(CSigmaView * pView, TextInformation * pInfo, HDC hdc) { int ret = SetTextInfoForCItemText(pView, pInfo, hdc); if (ret == -1) { ret = SetTextInfoForCText(pView, pInfo,hdc); if (ret == -1) return -1; return 1; } return 1; } extern "C" __declspec(dllexport) int Text_GetTextInfo(CSigmaView * pView, TextInformation * pInfo) { pInfo->textArr = 0; CText * pText = GetCText(pView); if (pText == 0) return -1; FillTextInformationFromCText(pInfo, pText, pView); return 1; } extern "C" __declspec(dllexport) int Text_SetFont(CSigmaView * pView, MYLOGFONT * myFont, HDC hdc) { int ret = SetFontForCItemText(pView, myFont, hdc); if (ret == -1) { return SetFontForCText(pView, myFont, hdc); } return 1; } extern "C" __declspec(dllexport) int Text_GetFont(CSigmaView * pView, MYLOGFONT * myFont) { CText * pText = GetCText(pView); if (pText == 0) return -1; memset(myFont, 0, sizeof(MYLOGFONT)); LOGFONT font = pText->m_logFont; size_t lenOfFontName = 0; if (font.lfFaceName != 0) lenOfFontName = strlen(font.lfFaceName); //TODO: 使用memcpy替代 myFont->lfHeight = font.lfHeight; myFont->lfWidth = font.lfWidth; myFont->lfEscapement = font.lfEscapement; myFont->lfOrientation = font.lfOrientation; myFont->lfWeight = font.lfWeight; myFont->lfItalic = font.lfItalic; myFont->lfUnderline = font.lfUnderline; myFont->lfStrikeOut = font.lfStrikeOut; myFont->lfCharSet = font.lfCharSet; myFont->lfOutPrecision = font.lfOutPrecision; myFont->lfClipPrecision = font.lfClipPrecision; myFont->lfQuality = font.lfQuality; myFont->lfPitchAndFamily = font.lfPitchAndFamily; if (lenOfFontName != 0) { wchar_t * pName = AsciiToUnicodeChar(font.lfFaceName); size_t len = wcslen(pName); if (len >= LF_FACESIZE) len = LF_FACESIZE - 1; memcpy(myFont->lfFaceName, pName, 2*len); } //memset(font.lfFaceName, 0, LF_FACESIZE); //ToChar(myFont->lfFaceName, font.lfFaceName, LF_FACESIZE); return 1; } //extern "C" __declspec(dllexport) //int Text_Create(CSigmaView * pView, HDC hdc) //{ // CItemText * pItem = getItemText(pView); // if (pItem == NULL) // return -1; // // pItem->Create(); // // if (hdc != nullptr) { // CDC *pDC = CDC::FromHandle(hdc); // pItem->m_client = pView->m_client; // pItem->SetBackGroundDC(pView->m_pImgDC); // pItem->OnDrawScreen(pItem->GetDC(), pDC); // } // // return 1; //} extern "C" __declspec(dllexport) int Text_Create(CSigmaView * pView, BYTE* buffElement, int buffLen) { CItemText * pItem = getItemText(pView); if (pItem == NULL) return -1; COne* pOne = new COne; pOne->SetType(DOUBLEFOX_TEXT); pOne->ReadMemory(buffElement, -1, buffLen, 3); CText* pText = (CText*)(pOne->value); pText->color = pOne->color; pItem->Create(pText, pOne->color); delete pOne; pOne = nullptr; return 1; } extern "C" __declspec(dllexport) int Sigma_CalculateTextSizeDisplayed(CSigmaView * pView, double * xInOut, double * yInOut) { CText * pText = GetCText(pView); if (pText == 0) return -1; CPoint pt1 = pView->m_pDoc->GetDC().GetScreen(pText->x0, pText->y0); CPoint pt2 = pView->m_pDoc->GetDC().GetScreen(pText->x0 + pText->m_size.cx, pText->y0 + pText->m_size.cy); *xInOut = abs(pt2.x - pt1.x)*0.7; *yInOut = abs(pt2.y - pt1.y)*0.7; return 0; } extern "C" __declspec(dllexport) void Sigma_ShowOrHideCurrentText(CSigmaView * pView, bool bShow) { CItemSelect * pItemSelect = getItemSelect(pView); if (pItemSelect == NULL) return ; if (pItemSelect->m_selection.IsEmpty()) return ; POSITION pos = pItemSelect->m_selection.GetHead(); if (pos == 0) return ; if (pView->m_pDoc == 0) return ; COne * pOne = pView->m_pDoc->GetDraw()->GetAt(pos); if (pOne == 0) return ; if (pOne->GetType() != DOUBLEFOX_TEXT) return ; if (bShow) { pOne->SetViewState(VIEW_STATE); // 设置为可见 } else { pOne->SetViewState(UNVIEW_STATE); // 设置为不可见 } pItemSelect->EnableTracker(bShow); } static CItemText * getItemText(CSigmaView * pView) { CItem * pItem = pView->GetItem(); if (pItem == NULL) return NULL; CItemText * pItemText = dynamic_cast(pItem); return pItemText; } static CItemSelect * getItemSelect(CSigmaView * pView) { CItem * pItem = pView->GetItem(); if (pItem == NULL) return NULL; CItemSelect * pItemSelect = dynamic_cast(pItem); return pItemSelect; } static CText * GetCText(CSigmaView * pView) { CItemSelect * pItemSelect = getItemSelect(pView); if (pItemSelect == NULL) return 0; if (pItemSelect->m_selection.IsEmpty()) return 0; POSITION pos = pItemSelect->m_selection.GetHead(); if (pos == 0) return 0; if (pView->m_pDoc == 0) return 0; COne * pOne = pView->m_pDoc->GetDraw()->GetAt(pos); if (pOne == 0) return 0; if (pOne->GetType() != DOUBLEFOX_TEXT) return 0; // //if (pOne->IsView()) // 判断是否可见 // pOne->SetViewState(UNVIEW_STATE); // 设置为不可见 //else // pOne->SetViewState(VIEW_STATE); // 设置为可见 // CText * pText = (CText *)pView->m_pDoc->GetDraw()->GetAtValue(pos); if (pText == 0) return 0; return pText; } static int SetTextInfoForCItemText(CSigmaView * pView, TextInformation * pInfo, HDC hdc) { CItemText * pItem = getItemText(pView); if (pItem == NULL) return -1; if (pInfo->text != NULL) { CString textStr(pInfo->text); pItem->SetTextInfo(textStr, pInfo->textHeight, pInfo->textWidth , pInfo->angle, nullptr, pInfo->r, pInfo->g, pInfo->b, TRUE); CPoint point; point.x = pInfo->x; point.y = pInfo->y; CPoint2D pt = pView->m_pDoc->GetDC().GetReal(point); pItem->SetPosition(pt.x0, pt.y0); //pItem ->x0 = pt.x0; //m_pText->y0 = pt.y0; //OnDrawScreen(GetDC(), pDC); } if (hdc != nullptr) { CDC *pDC = CDC::FromHandle(hdc); pItem->m_client = pView->m_client; pItem->SetBackGroundDC(pView->m_pImgDC); pItem->OnDrawScreen(pItem->GetDC(), pDC); } return 1; } static int SetTextInfoForCText(CSigmaView * pView, TextInformation * pInfo, HDC hdc) { CText * pText = GetCText(pView); // if (pText != NULL) { //GetCText内部调用过这三句代码 已验证调用成功 这里不用检查代码是否安全了 CItemSelect * pItemSelect = getItemSelect(pView); POSITION pos = pItemSelect->m_selection.GetHead(); COne * pOne = pView->m_pDoc->GetDraw()->GetAt(pos); CActionModifiedItem* pAction = new CActionModifiedItem(pView->m_pDoc, IDS_STRING_TOOLBAR_EDIT); pAction->BackupOldItem(pos, pOne); if (pInfo->text != 0) pText->SetName(pInfo->text); pText->m_size.cy = pInfo->textHeight; pText->m_size.cx = pInfo->textWidth; pText->angle = pInfo->angle; pText->color = RGB(pInfo->r, pInfo->g, pInfo->b); pText->m_bScript = TRUE; pOne->color = pText->color; pAction->BackupNewItem(); pView->m_pDoc->SetActionItem(pAction); } //if (hdc != 0) //{ // CDC * pDC = CDC::FromHandle(hdc); // DrawTextOnScreen(&pView->m_pDoc->GetDC(), pDC, pText, pView->m_client, pView->m_pImgDC); //} return 1; } static void FillTextInformationFromCText(TextInformation * pInfo, CText * pText, CSigmaView * pView) { if (pInfo == 0 || pText == 0) return; pInfo->r = GetRValue(pText->color); pInfo->g = GetGValue(pText->color); pInfo->b = GetBValue(pText->color); wchar_t buffer[50]; memset(buffer, 0, sizeof(buffer)); pInfo->textArr = AsciiToUnicodeChar(pText->GetName()); pInfo->lenOfTextArr = (int)wcslen((wchar_t*)pInfo->textArr); pInfo->textHeight = pText->m_size.cy; pInfo->textWidth = pText->m_size.cx; pInfo->bUpDown = pText->m_bScript; CPoint pt = pView->m_pDoc->GetDC().GetScreen(pText->x0, pText->y0); pInfo->x = pt.x; pInfo->y = pt.y; CPoint pt2 = pView->m_pDoc->GetDC().GetScreen(pText->x0, pText->y0 + pText->m_size.cy); pInfo->textHeightOfDisplayed = abs(pt2.y - pt.y); } static int SetFontForCItemText(CSigmaView * pView, MYLOGFONT * myFont, HDC hdc) { CItemText * pItem = getItemText(pView); if (pItem == NULL) return -1; LOGFONT font; memcpy(&font, myFont, sizeof(LOGFONT)); memset(font.lfFaceName, 0, LF_FACESIZE); UnicodeToAscii(myFont->lfFaceName, font.lfFaceName, LF_FACESIZE); pItem->SetFont(&font); if (hdc != nullptr) { CDC *pDC = CDC::FromHandle(hdc); pItem->m_client = pView->m_client; pItem->SetBackGroundDC(pView->m_pImgDC); pItem->OnDrawScreen(pItem->GetDC(), pDC); } return 1; } static int SetFontForCText(CSigmaView * pView, MYLOGFONT * myFont, HDC hdc) { CText * pText = GetCText(pView); if (pText == NULL) return -1; memcpy(&pText->m_logFont, myFont, sizeof(LOGFONT)); memset(pText->m_logFont.lfFaceName, 0, LF_FACESIZE); UnicodeToAscii(myFont->lfFaceName, pText->m_logFont.lfFaceName, LF_FACESIZE); //if (hdc != 0) { // CDC *pDC = CDC::FromHandle(hdc); // DrawTextOnScreen(&pView->m_pDoc->GetDC(), pDC, pText, pView->m_client, pView->m_pImgDC); //} return 1; } static void DrawTextOnScreen(CXyDC* pXyDC, CDC* pScreenDC, CText * pText, CRect clientRect, CDC * pBackGroundDC) { if (pText == NULL) return; DCHelp::ClearDC(pScreenDC, RGB(255,255,255)); pScreenDC->BitBlt(0, 0, clientRect.Width(), clientRect.Height(), pBackGroundDC, 0, 0, SRCCOPY); //CFont font; //font.Attach(&pText->m_logFont); //CFont * oldFont = pScreenDC->SelectObject(&font); pXyDC->Create(pScreenDC); //pXyDC->CreateSelectFontDraw(pText->m_logFont); pXyDC->Draw(*pText, pText->color); //pXyDC->RestoreFont(); //pScreenDC->SelectObject(oldFont); }