Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions Src/views/Test/TestVwTextBoxes.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,45 @@ namespace TestViews
IPicturePtr m_qPicture;
};

// View constructor that displays a single string inside a concordance paragraph.
// The keyword region (ichMin..ichLim) is aligned at dmpAlign.
// If textAlign is set to ktalRight, the paragraph gets right alignment so that
// DoSpecialAlignment uses the right edge of the keyword for positioning.
class ConcParaVc : public DummyBaseVc
{
public:
int m_ichMinItem;
int m_ichLimItem;
int m_dmpAlign;
int m_textAlign; // ktalLeft or ktalRight

ConcParaVc(int ichMin, int ichLim, int dmpAlign, int textAlign)
: m_ichMinItem(ichMin), m_ichLimItem(ichLim),
m_dmpAlign(dmpAlign), m_textAlign(textAlign)
{
}

STDMETHOD(Display)(IVwEnv * pvwenv, HVO hvo, int frag)
{
pvwenv->put_IntProperty(ktptAlign, ktpvEnum, m_textAlign);
pvwenv->OpenConcPara(m_ichMinItem, m_ichLimItem,
(VwConcParaOpts)kcpoDefault, m_dmpAlign);
pvwenv->AddStringProp(kflidStTxtPara_Contents, NULL);
pvwenv->CloseParagraph();
return S_OK;
}
STDMETHOD(EstimateHeight)(HVO hvo, int frag, int dxAvailWidth, int * pdyHeight)
{
*pdyHeight = 20;
return S_OK;
}
STDMETHOD(LoadDataFor)(IVwEnv * pvwenv, HVO * prghvo, int chvo, HVO hvoParent,
int tag, int frag, int ihvoMin)
{
return S_OK;
}
};

class TestVwParagraphBox : public unitpp::suite
{
// Maximum number of previous strings to add before testing strings
Expand Down Expand Up @@ -1207,6 +1246,68 @@ namespace TestViews
}
}

// Helper: lay out a single concordance paragraph and return the Left() of its first child box.
// The paragraph contains the given string with keyword at ichMin..ichLim aligned at dmpAlign.
int LayoutConcParaAndGetFirstBoxLeft(const OLECHAR * pszText, int cch,
int ichMin, int ichLim, int dmpAlign, int textAlign)
{
HVO hvoPara = 1;
ITsStringPtr qtss;
CheckHr(m_qtsf->MakeStringRgch(pszText, cch, g_wsEng, &qtss));
CheckHr(m_qcda->CacheStringProp(hvoPara, kflidStTxtPara_Contents, qtss));

IVwViewConstructorPtr qvc;
qvc.Attach(NewObj ConcParaVc(ichMin, ichLim, dmpAlign, textAlign));
m_qrootb->SetRootObject(hvoPara, qvc, 1, NULL);
HRESULT hr = m_qrootb->Layout(m_qvg32, 300);
unitpp::assert_true("ConcPara layout succeeded", hr == S_OK);

VwParagraphBox * ppbox = dynamic_cast<VwParagraphBox *>(m_qrootb->FirstBox());
unitpp::assert_true("Root contains a paragraph box", ppbox != NULL);
VwBox * pFirstChild = ppbox->FirstBox();
unitpp::assert_true("Paragraph has a child box", pFirstChild != NULL);

int result = pFirstChild->Left();

// Clean up so we can reuse the root box
m_qrootb->Close();
VwRootBox::CreateCom(NULL, IID_IVwRootBox, (void **) &m_qrootb);
m_qrootb->putref_DataAccess(m_qsda);
m_qrootb->putref_RenderEngineFactory(m_qref);
m_qrootb->putref_TsStrFactory(m_qtsf);
m_qrootb->SetSite(m_qdrs);

return result;
}

// Tests that DoSpecialAlignment uses the right edge of the keyword
// when the paragraph alignment is ktalRight, and the left edge when
// the alignment is ktalLeft. These should produce different box positions
// because the keyword has nonzero width.
void testConcParaAlignment_RightVsLeftEdge()
{
// Use a string where the keyword ("keyword") is in the middle.
// "Before keyword after end" - keyword at positions 7..14
const OLECHAR text[] = L"Before keyword after end";
int cch = (int)wcslen(text);
int ichMin = 7; // start of "keyword"
int ichLim = 14; // end of "keyword"
int dmpAlign = 36000; // 0.5 inch alignment point

int leftWithLeftAlign = LayoutConcParaAndGetFirstBoxLeft(
text, cch, ichMin, ichLim, dmpAlign, ktalLeft);
int leftWithRightAlign = LayoutConcParaAndGetFirstBoxLeft(
text, cch, ichMin, ichLim, dmpAlign, ktalRight);

// With left alignment, the left edge of "keyword" is placed at dmpAlign.
// With right alignment, the right edge of "keyword" is placed at dmpAlign.
// Since the keyword has nonzero width, the first child box should be
// shifted further left in the right-aligned case (by the width of the keyword).
unitpp::assert_true(
"Right-aligned conc para should shift boxes further left than left-aligned",
leftWithRightAlign < leftWithLeftAlign);
}

public:
TestVwParagraphBox();

Expand Down
6 changes: 5 additions & 1 deletion Src/views/VwTextBoxes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10055,7 +10055,11 @@ void VwConcParaBox::DoSpecialAlignment(IVwGraphics * pvg)
return; // ignore any problems here, just don't align.
}

int dxsAlign = rgxdLefts[0] + psbox->Left();
int dxsAlign;
if (Style()->ParaAlign() == ktalRight)
dxsAlign = rgxdRights[cxd - 1] + psbox->Left();
else
dxsAlign = rgxdLefts[0] + psbox->Left();
int dxsGoalAlign = MulDiv(m_dmpAlign, dxsInch, kdzmpInch);
int dxsAdjust = dxsGoalAlign - dxsAlign;
// Now adjust all the box lefts by this amount
Expand Down
Loading