Leaked source code of windows server 2003
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

/*++
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;
}