You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

549 lines
14 KiB
C++

#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<CItemText *>(pItem);
return pItemText;
}
static CItemSelect * getItemSelect(CSigmaView * pView)
{
CItem * pItem = pView->GetItem();
if (pItem == NULL)
return NULL;
CItemSelect * pItemSelect = dynamic_cast<CItemSelect *>(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);
}