You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
361 lines
9.0 KiB
361 lines
9.0 KiB
/*++
|
|
|
|
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;
|
|
}
|