summaryrefslogtreecommitdiff
path: root/svx/source/svdraw/svdtxhdl.cxx
diff options
context:
space:
mode:
authorArmin Weiss <aw@openoffice.org>2002-08-01 13:53:16 +0000
committerArmin Weiss <aw@openoffice.org>2002-08-01 13:53:16 +0000
commitfba95689b27cb05f28ca4cad3be3d250932eb3f9 (patch)
treeac9e9e13b9f84ba7340f3568519116eea4b05679 /svx/source/svdraw/svdtxhdl.cxx
parent1b9699807592f9cc0c61a5a372760c64d8333b58 (diff)
#101498# ImpTextPortionHandler::DrawTextToPath(...) adapted to BiDi. Big changes.
Diffstat (limited to 'svx/source/svdraw/svdtxhdl.cxx')
-rw-r--r--svx/source/svdraw/svdtxhdl.cxx305
1 files changed, 275 insertions, 30 deletions
diff --git a/svx/source/svdraw/svdtxhdl.cxx b/svx/source/svdraw/svdtxhdl.cxx
index d70cab3fc69e..59f5d1558fee 100644
--- a/svx/source/svdraw/svdtxhdl.cxx
+++ b/svx/source/svdraw/svdtxhdl.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: svdtxhdl.cxx,v $
*
- * $Revision: 1.12 $
+ * $Revision: 1.13 $
*
- * last change: $Author: aw $ $Date: 2002-07-31 16:02:22 $
+ * last change: $Author: aw $ $Date: 2002-08-01 14:53:16 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -132,7 +132,8 @@ using namespace ::com::sun::star::i18n;
ImpTextPortionHandler::ImpTextPortionHandler(SdrOutliner& rOutln, const SdrTextObj& rTxtObj):
rOutliner(rOutln),
rTextObj(rTxtObj),
- aPoly(0)
+ // #101498# aPoly(0)
+ mpRecordPortions(0L)
{
pModel=rTextObj.GetModel();
MapMode aMap=aVDev.GetMapMode();
@@ -203,20 +204,55 @@ void ImpTextPortionHandler::DrawTextToPath(ExtOutputDevice& rXOut, FASTBOOL bDra
if ( nCnt == 1 ) bToLastPoint = TRUE;
else bToLastPoint = FALSE;
- for (nParagraph = 0; nParagraph < nCnt; nParagraph++)
+ // #101498# completely different methodology needed here for making this BIDI-able
+ // iterate over paragraphs and Polygons, thus each paragraph will be put to
+ // one Polygon
+ const sal_uInt32 nSavedLayoutMode(rXOut.GetOutDev()->GetLayoutMode());
+ sal_uInt32 nLayoutMode(nSavedLayoutMode);
+
+ if(TRUE)
+ {
+ nLayoutMode &= ~(TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG);
+ }
+ else
{
- aPoly = XOutCreatePolygon(aXPP[USHORT(nParagraph)], rXOut.GetOutDev());
- nTextWidth = 0;
+ nLayoutMode &= ~(TEXT_LAYOUT_BIDI_RTL);
+ nLayoutMode |= ~(TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG);
+ }
- rOutliner.SetDrawPortionHdl(LINK(this,ImpTextPortionHandler,FormTextWidthHdl));
- rOutliner.StripPortions();
- rOutliner.SetDrawPortionHdl(LINK(this,ImpTextPortionHandler,FormTextDrawHdl));
+ rXOut.GetOutDev()->SetLayoutMode(nLayoutMode);
+
+ for(nParagraph = 0; nParagraph < nCnt; nParagraph++)
+ {
+ Polygon aPoly = XOutCreatePolygon(aXPP[sal_uInt16(nParagraph)], rXOut.GetOutDev());
+
+ rOutliner.SetDrawPortionHdl(LINK(this, ImpTextPortionHandler, FormTextRecordPortionHdl));
rOutliner.StripPortions();
- rOutliner.SetDrawPortionHdl(Link());
- const Rectangle& rFTBR=rXOut.GetFormTextBoundRect();
+ DrawFormTextRecordPortions(aPoly);
+ ClearFormTextRecordPortions();
+
+ const Rectangle& rFTBR = rXOut.GetFormTextBoundRect();
aFormTextBoundRect.Union(rFTBR);
}
+
+ rXOut.GetOutDev()->SetLayoutMode(nSavedLayoutMode);
+
+ //for (nParagraph = 0; nParagraph < nCnt; nParagraph++)
+ //{
+ // aPoly = XOutCreatePolygon(aXPP[USHORT(nParagraph)], rXOut.GetOutDev());
+ // nTextWidth = 0;
+ //
+ // rOutliner.SetDrawPortionHdl(LINK(this,ImpTextPortionHandler,FormTextWidthHdl));
+ // rOutliner.StripPortions();
+ // rOutliner.SetDrawPortionHdl(LINK(this,ImpTextPortionHandler,FormTextDrawHdl));
+ // rOutliner.StripPortions();
+ // rOutliner.SetDrawPortionHdl(Link());
+ //
+ // const Rectangle& rFTBR=rXOut.GetFormTextBoundRect();
+ // aFormTextBoundRect.Union(rFTBR);
+ //}
+
rXOut.GetOutDev()->SetFont(aFont);
rOutliner.Clear();
}
@@ -225,6 +261,207 @@ void ImpTextPortionHandler::DrawTextToPath(ExtOutputDevice& rXOut, FASTBOOL bDra
}
}
+// #101498# Record and sort all portions
+IMPL_LINK(ImpTextPortionHandler, FormTextRecordPortionHdl, DrawPortionInfo*, pInfo)
+{
+ if(pInfo->nPara == nParagraph)
+ {
+ SortedAddFormTextRecordPortion(pInfo);
+ }
+
+ return 0;
+}
+
+// #101498# Helper class to remember text portions in sorted manner
+class ImpRecordPortion
+{
+public:
+ Point maPosition;
+ String maText;
+ xub_StrLen mnTextStart;
+ xub_StrLen mnTextLength;
+ sal_uInt16 mnPara;
+ xub_StrLen mnIndex;
+ Font maFont;
+ sal_Int32* mpDXArray;
+ sal_uInt8 mnBiDiLevel;
+
+ ImpRecordPortion(DrawPortionInfo* pInfo);
+ ~ImpRecordPortion();
+
+ sal_uInt8 GetBiDiLevel() const { return mnBiDiLevel; }
+};
+
+ImpRecordPortion::ImpRecordPortion(DrawPortionInfo* pInfo)
+: maPosition(pInfo->rStartPos),
+ maText(pInfo->rText),
+ mnTextStart((xub_StrLen)pInfo->nTextStart),
+ mnTextLength((xub_StrLen)pInfo->nTextLen),
+ mnPara(pInfo->nPara),
+ mnIndex(pInfo->nIndex),
+ maFont(pInfo->rFont),
+ mpDXArray(NULL),
+ mnBiDiLevel(pInfo->GetBiDiLevel())
+{
+ if(pInfo->pDXArray)
+ {
+ mpDXArray = new sal_Int32[pInfo->nTextLen];
+
+ for(sal_uInt32 a(0L); a < pInfo->nTextLen; a++)
+ {
+ mpDXArray[a] = pInfo->pDXArray[a];
+ }
+ }
+}
+
+ImpRecordPortion::~ImpRecordPortion()
+{
+ if(mpDXArray)
+ {
+ delete[] mpDXArray;
+ }
+}
+
+// #101498# List classes for recording portions
+DECLARE_LIST(ImpRecordPortionList, ImpRecordPortion*);
+DECLARE_LIST(ImpRecordPortionListList, ImpRecordPortionList*);
+
+// #101498# Draw recorded formtext along Poly
+void ImpTextPortionHandler::DrawFormTextRecordPortions(Polygon aPoly)
+{
+ sal_Int32 nTextWidth = -((sal_Int32)GetFormTextPortionsLength(pXOut->GetOutDev()));
+
+ ImpRecordPortionListList* pListList = (ImpRecordPortionListList*)mpRecordPortions;
+ if(pListList)
+ {
+ for(sal_uInt32 a(0L); a < pListList->Count(); a++)
+ {
+ ImpRecordPortionList* pList = pListList->GetObject(a);
+
+ for(sal_uInt32 b(0L); b < pList->Count(); b++)
+ {
+ ImpRecordPortion* pPortion = pList->GetObject(b);
+
+ DrawPortionInfo aNewInfo(
+ pPortion->maPosition,
+ pPortion->maText,
+ pPortion->mnTextStart,
+ pPortion->mnTextLength,
+ pPortion->maFont,
+ pPortion->mnPara,
+ pPortion->mnIndex,
+ pPortion->mpDXArray,
+ pPortion->mnBiDiLevel);
+
+ nTextWidth = pXOut->DrawFormText(&aNewInfo, aPoly, nTextWidth, bToLastPoint, bDraw);
+ }
+ }
+ }
+}
+
+// #101498# Insert new portion sorted
+void ImpTextPortionHandler::SortedAddFormTextRecordPortion(DrawPortionInfo* pInfo)
+{
+ // get ListList and create on demand
+ ImpRecordPortionListList* pListList = (ImpRecordPortionListList*)mpRecordPortions;
+ if(!pListList)
+ {
+ mpRecordPortions = (void*)(new ImpRecordPortionListList(2, 2));
+ pListList = (ImpRecordPortionListList*)mpRecordPortions;
+ }
+
+ // create new portion
+ ImpRecordPortion* pNewPortion = new ImpRecordPortion(pInfo);
+
+ // look for the list where to insert new portion
+ ImpRecordPortionList* pList = 0L;
+
+ for(sal_uInt32 nListListIndex(0L); !pList && nListListIndex < pListList->Count(); nListListIndex++)
+ {
+ ImpRecordPortionList* pTmpList = pListList->GetObject(nListListIndex);
+
+ if(pTmpList->GetObject(0)->maPosition.Y() == pNewPortion->maPosition.Y())
+ pList = pTmpList;
+ }
+
+ if(!pList)
+ {
+ // no list for that Y-Coordinate yet, create a new one.
+ pList = new ImpRecordPortionList(8, 8);
+ pList->Insert(pNewPortion, LIST_APPEND);
+ pListList->Insert(pList, LIST_APPEND);
+ }
+ else
+ {
+ // found a list for that for that Y-Coordinate, sort in
+ sal_uInt32 nInsertInd(0L);
+
+ while(nInsertInd < pList->Count()
+ && pList->GetObject(nInsertInd)->maPosition.X() < pNewPortion->maPosition.X())
+ {
+ nInsertInd++;
+ }
+
+ if(nInsertInd == pList->Count())
+ nInsertInd = LIST_APPEND;
+
+ pList->Insert(pNewPortion, nInsertInd);
+ }
+}
+
+// #101498# Calculate complete length of FormTextPortions
+sal_uInt32 ImpTextPortionHandler::GetFormTextPortionsLength(OutputDevice* pOut)
+{
+ sal_uInt32 nRetval(0L);
+
+ ImpRecordPortionListList* pListList = (ImpRecordPortionListList*)mpRecordPortions;
+ if(pListList)
+ {
+ for(sal_uInt32 a(0L); a < pListList->Count(); a++)
+ {
+ ImpRecordPortionList* pList = pListList->GetObject(a);
+
+ for(sal_uInt32 b(0L); b < pList->Count(); b++)
+ {
+ ImpRecordPortion* pPortion = pList->GetObject(b);
+
+ if(pPortion->mpDXArray)
+ {
+ if(pPortion->maFont.IsVertical() && pOut)
+ nRetval += pOut->GetTextHeight() * pPortion->mnTextLength;
+ else
+ nRetval += pPortion->mpDXArray[pPortion->mnTextLength - 1];
+ }
+ }
+ }
+ }
+
+ return nRetval;
+}
+
+// #101498# Cleanup recorded portions
+void ImpTextPortionHandler::ClearFormTextRecordPortions()
+{
+ ImpRecordPortionListList* pListList = (ImpRecordPortionListList*)mpRecordPortions;
+ if(pListList)
+ {
+ for(sal_uInt32 a(0L); a < pListList->Count(); a++)
+ {
+ ImpRecordPortionList* pList = pListList->GetObject(a);
+
+ for(sal_uInt32 b(0L); b < pList->Count(); b++)
+ {
+ delete pList->GetObject(b);
+ }
+
+ delete pList;
+ }
+
+ delete pListList;
+ mpRecordPortions = (void*)0L;
+ }
+}
+
IMPL_LINK(ImpTextPortionHandler,ConvertHdl,DrawPortionInfo*,pInfo)
{
// aFormTextBoundRect enthaelt den Ausgabebereich des Textobjekts
@@ -301,7 +538,7 @@ IMPL_LINK(ImpTextPortionHandler,ConvertHdl,DrawPortionInfo*,pInfo)
//if(aVDev.GetTextOutline(aPolyPoly, pInfo->rText, pInfo->nTextStart, pInfo->nTextStart, pInfo->nTextLen)
// && aPolyPoly.Count())
//{
- // XPolyPolygon aXPP(aPolyPoly);
+ //XPolyPolygon aXPP(aPolyPoly);
//
// // rotate 270 degree if vertical since result is unrotated
// if(bIsVertical)
@@ -509,21 +746,29 @@ IMPL_LINK(ImpTextPortionHandler,FitTextDrawHdl,DrawPortionInfo*,pInfo)
return 0;
}
-IMPL_LINK(ImpTextPortionHandler,FormTextWidthHdl,DrawPortionInfo*,pInfo)
-{
- if(pInfo->nPara == nParagraph && pInfo->rText.Len())
- {
- // negative Gesamtlaenge fuer ersten Aufruf von DrawFormText
- nTextWidth -= pInfo->pDXArray[pInfo->rText.Len() - 1];
- }
- return 0;
-}
-
-IMPL_LINK(ImpTextPortionHandler,FormTextDrawHdl,DrawPortionInfo*,pInfo)
-{
- if (pInfo->nPara==nParagraph) {
- nTextWidth=pXOut->DrawFormText(pInfo->rText,aPoly,pInfo->rFont,
- nTextWidth,bToLastPoint,bDraw,pInfo->pDXArray);
- }
- return 0;
-}
+//IMPL_LINK(ImpTextPortionHandler, FormTextWidthHdl, DrawPortionInfo*, pInfo)
+//{
+// // #101498# change calculation of nTextWidth
+// if(pInfo->nPara == nParagraph && pInfo->nTextLen)
+// {
+// // negative value is used because of the interface of
+// // XOutputDevice::ImpDrawFormText(...), please look there
+// // for more info.
+// nTextWidth -= pInfo->pDXArray[pInfo->nTextLen - 1];
+// }
+//
+// return 0;
+//}
+
+//IMPL_LINK(ImpTextPortionHandler, FormTextDrawHdl, DrawPortionInfo*, pInfo)
+//{
+// // #101498# Implementation of DrawFormText needs to be updated, too.
+// if(pInfo->nPara == nParagraph)
+// {
+// nTextWidth = pXOut->DrawFormText(pInfo, aPoly, nTextWidth, bToLastPoint, bDraw);
+// //pInfo->rText, aPoly, pInfo->rFont, nTextWidth,
+// //bToLastPoint, bDraw, pInfo->pDXArray);
+// }
+//
+// return 0;
+//}