/*++ Copyright (c) 2001, Microsoft Corporation Module Name: polytext.cpp Abstract: This file implements the CPolyText Class. Author: Revision History: Notes: --*/ #include "private.h" #include "globals.h" #include "polytext.h" #include "fontlink.h" //+--------------------------------------------------------------------------- // // CPolyText::SplitPolyStringAndAttr // //+--------------------------------------------------------------------------- HRESULT CPolyText::SplitPolyStringAndAttr( IMCLock& imc, HDC hDC, POLYTEXTW poly_text, PBYTE pbAttrPtr, CCompClauseStore *compclause) { BYTE attr = *pbAttrPtr; PBYTE p = pbAttrPtr; UINT n = poly_text.n; UINT str_len = 0; // // Find different attribute // while (n) { if (compclause->IsAtFirstBoundary(str_len)) { Assert(str_len); break; } --n; ++p; ++str_len; } CCompClauseStore compclauseTmp; compclauseTmp.Copy(compclause); compclauseTmp.Shift(str_len); INT_PTR index = m_poly_text.GetSize(); if (n == 0) { if (poly_text.n) { SIZE size; FLGetTextExtentPoint32(hDC, poly_text.lpstr, poly_text.n, &size); if (!imc.UseVerticalCompWindow()) { poly_text.rcl.right = poly_text.rcl.left + size.cx; } else { RotateSize(&size); poly_text.rcl.bottom = poly_text.rcl.top + size.cy; } } m_poly_text.SetAtGrow(index, poly_text); TfGuidAtom atom = TF_INVALID_GUIDATOM; CtfImeGetGuidAtom((HIMC)imc, *pbAttrPtr, &atom); m_TfGuidAtom.SetAtGrow(index, atom); } else { POLYTEXTW merge_poly = poly_text; n = poly_text.n; poly_text.n = str_len; SIZE size; FLGetTextExtentPoint32(hDC, poly_text.lpstr, poly_text.n, &size); if (!imc.UseVerticalCompWindow()) { poly_text.rcl.right = poly_text.rcl.left + size.cx; } else { RotateSize(&size); poly_text.rcl.bottom = poly_text.rcl.top + size.cy; } m_poly_text.SetAtGrow(index, poly_text); TfGuidAtom atom = TF_INVALID_GUIDATOM; CtfImeGetGuidAtom((HIMC)imc, *pbAttrPtr, &atom); m_TfGuidAtom.SetAtGrow(index, atom); if (!imc.UseVerticalCompWindow()) { merge_poly.x += size.cx; merge_poly.rcl.left += size.cx; } else { merge_poly.y += size.cy; merge_poly.rcl.top += size.cy; } merge_poly.n = n - str_len; merge_poly.lpstr = poly_text.lpstr + str_len; return SplitPolyStringAndAttr(imc, hDC, merge_poly, p, &compclauseTmp); } return S_OK; } //+--------------------------------------------------------------------------- // // CPolyText::SplitPolyStringAndAttr // //+--------------------------------------------------------------------------- HRESULT CPolyText::SplitPolyStringAndAttr( IMCLock& imc, HDC hDC, POLYTEXTW poly_text) { INT_PTR index = m_poly_text.GetSize(); m_poly_text.SetAtGrow(index, poly_text); return S_OK; } //+--------------------------------------------------------------------------- // // CPolyText::RemoveLastLine // //+--------------------------------------------------------------------------- HRESULT CPolyText::RemoveLastLine(BOOL fVert) { INT_PTR n = m_poly_text.GetSize(); if (n == 0) { return S_FALSE; } POLYTEXTW last_poly = m_poly_text.GetAt(n-1); // // Find the same Y line. // for (int index = 0; index < n; index++) { POLYTEXTW poly = m_poly_text.GetAt(index); if (!fVert && (poly.y == last_poly.y)) break; else if (fVert && (poly.x == last_poly.x)) break; } if (index >= n) { return E_FAIL; } m_poly_text.RemoveAt(index, (int)(n - index)); m_TfGuidAtom.RemoveAt(index, (int)(n - index)); return S_OK; } //+--------------------------------------------------------------------------- // // CPolyText::ShiftPolyText // //+--------------------------------------------------------------------------- HRESULT CPolyText::ShiftPolyText(int dx, int dy) { INT_PTR n = m_poly_text.GetSize(); POLYTEXTW *ppoly_text = m_poly_text.GetData(); INT_PTR i; for (i = 0; i < n; i++) { ppoly_text[i].x += dx; ppoly_text[i].y += dy; ppoly_text[i].rcl.left += dx; ppoly_text[i].rcl.right += dx; ppoly_text[i].rcl.top += dy; ppoly_text[i].rcl.bottom += dy; } return S_OK; } //+--------------------------------------------------------------------------- // // CPolyText::GetPolyTextExtent // //+--------------------------------------------------------------------------- HRESULT CPolyText::GetPolyTextExtent(POINT pt, HDC hDC, BOOL fVert, ULONG *puEdge, ULONG *puQuadrant) { INT_PTR n = m_poly_text.GetSize(); POLYTEXTW *ppoly_text = m_poly_text.GetData(); INT_PTR i; ULONG j; DWORD dwCount = 0; for (i = 0; i < n; i++) { if (ppoly_text[i].n && PtInRect(&ppoly_text[i].rcl, pt)) { INT cxPoint; SIZE sizePrev = {0}; if (!fVert) cxPoint = pt.x - ppoly_text[i].rcl.left; else cxPoint = pt.y - ppoly_text[i].rcl.top; for (j = 1; j <= ppoly_text[i].n; j++) { SIZE size; FLGetTextExtentPoint32(hDC, ppoly_text[i].lpstr, j, &size); if (cxPoint < size.cx) { DWORD dwOneCharWidth = size.cx - sizePrev.cx; ULONG uOneCharDist = cxPoint - sizePrev.cx; // // Calc Edge. // *puEdge += dwCount; if (uOneCharDist * 2 > dwOneCharWidth) (*puEdge)++; // // Calc Quadrant. // if (uOneCharDist) uOneCharDist--; *puQuadrant = ((uOneCharDist * 4 / dwOneCharWidth) + 2) % 4; return S_OK; } sizePrev = size; dwCount++; } } dwCount += ppoly_text[i].n; } *puEdge += dwCount; return S_FALSE; } //+--------------------------------------------------------------------------- // // CPolyText::GetPolyTextExtentRect // //+--------------------------------------------------------------------------- HRESULT CPolyText::GetPolyTextExtentRect(DWORD &ach, HDC hDC, BOOL fVert, BOOL fGetLastPoint, RECT *prc) { INT_PTR n = m_poly_text.GetSize(); POLYTEXTW *ppoly_text = m_poly_text.GetData(); INT_PTR i; ULONG j; DWORD dwCount = 0; for (i = 0; i < n; i++) { BOOL fTry = FALSE; if (!fGetLastPoint) { if ((ach >= dwCount) && (ach < dwCount + ppoly_text[i].n)) fTry = TRUE; } else { if ((ach >= dwCount) && (ach <= dwCount + ppoly_text[i].n)) fTry = TRUE; } if (fTry) { SIZE size; if (ach - dwCount) { FLGetTextExtentPoint32(hDC, ppoly_text[i].lpstr, ach - dwCount, &size); } else { size.cx = 0; size.cy = 0; } if (!fVert) { prc->left = ppoly_text[i].rcl.left + size.cx; prc->right = ppoly_text[i].rcl.left + size.cx; prc->top = ppoly_text[i].rcl.top; prc->bottom = ppoly_text[i].rcl.bottom; } else { prc->left = ppoly_text[i].rcl.left; prc->right = ppoly_text[i].rcl.right; prc->top = ppoly_text[i].rcl.top + size.cx; prc->bottom = ppoly_text[i].rcl.top + size.cx; } return S_OK; } dwCount += ppoly_text[i].n; } ach -= dwCount; return S_FALSE; }