summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@Sun.COM>2010-02-02 12:16:54 +0100
committerArmin Le Grand <Armin.Le.Grand@Sun.COM>2010-02-02 12:16:54 +0100
commit2bb7512e2923c860fa6d6bb55dcb000737f3a7ec (patch)
tree30ec9e4b5df8b8cc7d3e3a8c80ab82ddebbdd528 /drawinglayer
parentdb91786a9326d275aeec1fa86c8e9c78a294ca53 (diff)
aw079 #i108440# Support MetaStretchTextAction in MetafilePrimitive2D decomposition
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx21
-rw-r--r--drawinglayer/source/primitive2d/metafileprimitive2d.cxx176
-rw-r--r--drawinglayer/source/primitive2d/textlayoutdevice.cxx69
3 files changed, 214 insertions, 52 deletions
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
index f3de43c22fd7..2d2f77f34fe5 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
@@ -101,20 +101,20 @@ namespace drawinglayer
double getTextWidth(
const String& rText,
- xub_StrLen nIndex,
- xub_StrLen nLength) const;
+ sal_uInt32 nIndex,
+ sal_uInt32 nLength) const;
bool getTextOutlines(
basegfx::B2DPolyPolygonVector&,
const String& rText,
- xub_StrLen nIndex,
- xub_StrLen nLength,
- const ::std::vector< double >& rDXArray);
+ sal_uInt32 nIndex,
+ sal_uInt32 nLength,
+ const ::std::vector< double >& rDXArray) const;
basegfx::B2DRange getTextBoundRect(
const String& rText,
- xub_StrLen nIndex,
- xub_StrLen nLength) const;
+ sal_uInt32 nIndex,
+ sal_uInt32 nLength) const;
double getFontAscent() const;
double getFontDescent() const;
@@ -123,7 +123,12 @@ namespace drawinglayer
const Rectangle& rRectangle,
const String& rText,
sal_uInt16 nStyle,
- GDIMetaFile& rGDIMetaFile);
+ GDIMetaFile& rGDIMetaFile) const;
+
+ ::std::vector< double > getTextArray(
+ const String& rText,
+ sal_uInt32 nIndex,
+ sal_uInt32 nLength) const;
};
} // end of namespace primitive2d
} // end of namespace drawinglayer
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
index 4bb123380ee6..e621bed175e8 100644
--- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -981,7 +981,42 @@ namespace
TargetHolders& rTargetHolders,
PropertyHolders& rPropertyHolders)
{
- // process evtl. created primitives which belong to the current region settings
+ const bool bNewActive(pRegion && !pRegion->IsEmpty());
+
+ // #i108636# The handlig of new ClipRegions was not done as good as possible
+ // in the first version of this interpreter; e.g. when a ClipRegion was set
+ // initially and then using a lot of push/pop actions, the pop always leads
+ // to setting a 'new' ClipRegion which indeed is the return to the ClipRegion
+ // of the properties next on the stack.
+ // This ClipRegion is identical to the current one, so there is no need to
+ // create a MaskPrimitive2D containing the up-to-now created primitives, but
+ // this was done before. While this does not lead to wrong primitive
+ // representations of the metafile data, it creates unneccesarily expensive
+ // representations. Just detecting when no really 'new' ClipRegion gets set
+ // solves the problem.
+
+ if(!rPropertyHolders.Current().getRegionActive() && !bNewActive)
+ {
+ // no active region exchanged by no new one, done
+ return;
+ }
+
+ if(rPropertyHolders.Current().getRegionActive() && bNewActive)
+ {
+ // active region and new active region
+ if(rPropertyHolders.Current().getRegion() == *pRegion)
+ {
+ // new region is the same as the old region, done
+ return;
+ }
+ }
+
+ // Here the old region and the new one are definitively different, maybe
+ // old one and/or new one is not active.
+
+ // Handle deletion of old region.The process evtl. created primitives which
+ // belong to this active region. These need to be embedded to a
+ // MaskPrimitive2D accordingly.
if(rPropertyHolders.Current().getRegionActive() && rTargetHolders.size() > 1)
{
drawinglayer::primitive2d::Primitive2DSequence aSubContent;
@@ -1001,8 +1036,8 @@ namespace
}
}
- // apply new settings
- const bool bNewActive(pRegion && !pRegion->IsEmpty());
+ // apply new settings to current properties by setting
+ // the new region now
rPropertyHolders.Current().setRegionActive(bNewActive);
if(bNewActive)
@@ -1259,13 +1294,12 @@ namespace
const XubString& rText,
sal_uInt16 nTextStart,
sal_uInt16 nTextLength,
- sal_Int32* pDXArray,
+ const ::std::vector< double >& rDXArray,
TargetHolder& rTarget,
PropertyHolder& rProperty)
{
drawinglayer::primitive2d::BasePrimitive2D* pResult = 0;
const Font& rFont = rProperty.getFont();
- std::vector< double > aDXArray;
basegfx::B2DVector aAlignmentOffset(0.0, 0.0);
if(nTextLength)
@@ -1283,17 +1317,6 @@ namespace
// add TextStartPosition
aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y());
- // preapare DXArray (if used)
- if(pDXArray && nTextLength)
- {
- aDXArray.reserve(nTextLength);
-
- for(xub_StrLen a(0); a < nTextLength; a++)
- {
- aDXArray.push_back((double)(*(pDXArray + a)));
- }
- }
-
// prepare FontColor and Locale
const basegfx::BColor aFontColor(rProperty.getTextColor());
const com::sun::star::lang::Locale aLocale(MsLangId::convertLanguageToLocale(rProperty.getLanguageType()));
@@ -1353,7 +1376,7 @@ namespace
rText,
nTextStart,
nTextLength,
- aDXArray,
+ rDXArray,
aFontAttribute,
aLocale,
aFontColor,
@@ -1380,7 +1403,7 @@ namespace
rText,
nTextStart,
nTextLength,
- aDXArray,
+ rDXArray,
aFontAttribute,
aLocale,
aFontColor);
@@ -1396,13 +1419,13 @@ namespace
// get text width
double fTextWidth(0.0);
- if(aDXArray.empty())
+ if(rDXArray.empty())
{
fTextWidth = aTextLayouterDevice.getTextWidth(rText, nTextStart, nTextLength);
}
else
{
- fTextWidth = aDXArray.back();
+ fTextWidth = rDXArray.back();
}
if(basegfx::fTools::more(fTextWidth, 0.0))
@@ -1957,15 +1980,24 @@ namespace
{
/** CHECKED, WORKS WELL */
const MetaTextAction* pA = (const MetaTextAction*)pAction;
+ sal_uInt32 nTextLength(pA->GetLen());
+ const sal_uInt32 nTextIndex(pA->GetIndex());
+ const sal_uInt32 nStringLength(pA->GetText().Len());
+
+ if(nTextLength + nTextIndex > nStringLength)
+ {
+ nTextLength = nStringLength - nTextIndex;
+ }
- if(pA->GetLen() && rPropertyHolders.Current().getTextColorActive())
+ if(nTextLength && rPropertyHolders.Current().getTextColorActive())
{
+ const std::vector< double > aDXArray;
proccessMetaTextAction(
pA->GetPoint(),
pA->GetText(),
- pA->GetIndex(),
- pA->GetLen(),
- 0,
+ nTextIndex,
+ nTextLength,
+ aDXArray,
rTargetHolders.Current(),
rPropertyHolders.Current());
}
@@ -1976,15 +2008,37 @@ namespace
{
/** CHECKED, WORKS WELL */
const MetaTextArrayAction* pA = (const MetaTextArrayAction*)pAction;
+ sal_uInt32 nTextLength(pA->GetLen());
+ const sal_uInt32 nTextIndex(pA->GetIndex());
+ const sal_uInt32 nStringLength(pA->GetText().Len());
- if(pA->GetLen() && rPropertyHolders.Current().getTextColorActive())
+ if(nTextLength + nTextIndex > nStringLength)
{
+ nTextLength = nStringLength - nTextIndex;
+ }
+
+ if(nTextLength && rPropertyHolders.Current().getTextColorActive())
+ {
+ // preapare DXArray (if used)
+ std::vector< double > aDXArray;
+ sal_Int32* pDXArray = pA->GetDXArray();
+
+ if(pDXArray)
+ {
+ aDXArray.reserve(nTextLength);
+
+ for(sal_uInt32 a(0); a < nTextLength; a++)
+ {
+ aDXArray.push_back((double)(*(pDXArray + a)));
+ }
+ }
+
proccessMetaTextAction(
pA->GetPoint(),
pA->GetText(),
- pA->GetIndex(),
- pA->GetLen(),
- pA->GetDXArray(),
+ nTextIndex,
+ nTextLength,
+ aDXArray,
rTargetHolders.Current(),
rPropertyHolders.Current());
}
@@ -1993,10 +2047,65 @@ namespace
}
case META_STRETCHTEXT_ACTION :
{
- /** NEEDS IMPLEMENTATION */
- OSL_ENSURE(false, "META_STRETCHTEXT_ACTION requested (!)");
- // use OutputDevice::GetTextArray() to map the...
- // const MetaStretchTextAction* pA = (const MetaStretchTextAction*)pAction;
+ // #i108440# StarMath uses MetaStretchTextAction, thus support is needed.
+ // It looks as if it pretty never really uses a width different from
+ // the default text-layout width, but it's not possible to be sure.
+ // Implemented getting the DXArray and checking for scale at all. If
+ // scale is more than 3.5% different, scale the DXArray before usage.
+ // New status:
+
+ /** CHECKED, WORKS WELL */
+ const MetaStretchTextAction* pA = (const MetaStretchTextAction*)pAction;
+ sal_uInt32 nTextLength(pA->GetLen());
+ const sal_uInt32 nTextIndex(pA->GetIndex());
+ const sal_uInt32 nStringLength(pA->GetText().Len());
+
+ if(nTextLength + nTextIndex > nStringLength)
+ {
+ nTextLength = nStringLength - nTextIndex;
+ }
+
+ if(nTextLength && rPropertyHolders.Current().getTextColorActive())
+ {
+ drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
+ aTextLayouterDevice.setFont(rPropertyHolders.Current().getFont());
+
+ ::std::vector< double > aTextArray(
+ aTextLayouterDevice.getTextArray(
+ pA->GetText(),
+ nTextIndex,
+ nTextLength));
+
+ if(!aTextArray.empty())
+ {
+ const double fTextLength(aTextArray.back());
+
+ if(0.0 != fTextLength && pA->GetWidth())
+ {
+ const double fRelative(pA->GetWidth() / fTextLength);
+
+ if(fabs(fRelative - 1.0) >= 0.035)
+ {
+ // when derivation is more than 3,5% from default text size,
+ // scale the DXArray
+ for(sal_uInt32 a(0); a < aTextArray.size(); a++)
+ {
+ aTextArray[a] *= fRelative;
+ }
+ }
+ }
+ }
+
+ proccessMetaTextAction(
+ pA->GetPoint(),
+ pA->GetText(),
+ nTextIndex,
+ nTextLength,
+ aTextArray,
+ rTargetHolders.Current(),
+ rPropertyHolders.Current());
+ }
+
break;
}
case META_TEXTRECT_ACTION :
@@ -2005,8 +2114,9 @@ namespace
// OSL_ENSURE(false, "META_TEXTRECT_ACTION requested (!)");
const MetaTextRectAction* pA = (const MetaTextRectAction*)pAction;
const Rectangle& rRectangle = pA->GetRect();
+ const sal_uInt32 nStringLength(pA->GetText().Len());
- if(!rRectangle.IsEmpty() && 0 != pA->GetText().Len())
+ if(!rRectangle.IsEmpty() && 0 != nStringLength)
{
// The problem with this action is that it describes unlayouted text
// and the layout capabilities are in EditEngine/Outliner in SVX. The
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 2950427d6b57..c7e2fcebb96f 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -223,8 +223,8 @@ namespace drawinglayer
double TextLayouterDevice::getTextWidth(
const String& rText,
- xub_StrLen nIndex,
- xub_StrLen nLength) const
+ sal_uInt32 nIndex,
+ sal_uInt32 nLength) const
{
return mrDevice.GetTextWidth(rText, nIndex, nLength);
}
@@ -232,15 +232,22 @@ namespace drawinglayer
bool TextLayouterDevice::getTextOutlines(
basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector,
const String& rText,
- xub_StrLen nIndex,
- xub_StrLen nLength,
- const ::std::vector< double >& rDXArray)
+ sal_uInt32 nIndex,
+ sal_uInt32 nLength,
+ const ::std::vector< double >& rDXArray) const
{
const sal_uInt32 nDXArrayCount(rDXArray.size());
+ sal_uInt32 nTextLength(nLength);
+ const sal_uInt32 nStringLength(rText.Len());
+
+ if(nTextLength + nIndex > nStringLength)
+ {
+ nTextLength = nStringLength - nIndex;
+ }
if(nDXArrayCount)
{
- OSL_ENSURE(nDXArrayCount == nLength, "DXArray size does not correspond to text portion size (!)");
+ OSL_ENSURE(nDXArrayCount == nTextLength, "DXArray size does not correspond to text portion size (!)");
std::vector< sal_Int32 > aIntegerDXArray(nDXArrayCount);
for(sal_uInt32 a(0); a < nDXArrayCount; a++)
@@ -274,10 +281,18 @@ namespace drawinglayer
basegfx::B2DRange TextLayouterDevice::getTextBoundRect(
const String& rText,
- xub_StrLen nIndex,
- xub_StrLen nLength) const
+ sal_uInt32 nIndex,
+ sal_uInt32 nLength) const
{
- if(nLength)
+ sal_uInt32 nTextLength(nLength);
+ const sal_uInt32 nStringLength(rText.Len());
+
+ if(nTextLength + nIndex > nStringLength)
+ {
+ nTextLength = nStringLength - nIndex;
+ }
+
+ if(nTextLength)
{
Rectangle aRect;
@@ -291,7 +306,9 @@ namespace drawinglayer
// #i104432#, #i102556# take empty results into account
if(!aRect.IsEmpty())
{
- return basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+ return basegfx::B2DRange(
+ aRect.Left(), aRect.Top(),
+ aRect.Right(), aRect.Bottom());
}
}
@@ -314,11 +331,41 @@ namespace drawinglayer
const Rectangle& rRectangle,
const String& rText,
sal_uInt16 nStyle,
- GDIMetaFile& rGDIMetaFile)
+ GDIMetaFile& rGDIMetaFile) const
{
mrDevice.AddTextRectActions(
rRectangle, rText, nStyle, rGDIMetaFile);
}
+
+ ::std::vector< double > TextLayouterDevice::getTextArray(
+ const String& rText,
+ sal_uInt32 nIndex,
+ sal_uInt32 nLength) const
+ {
+ ::std::vector< double > aRetval;
+ sal_uInt32 nTextLength(nLength);
+ const sal_uInt32 nStringLength(rText.Len());
+
+ if(nTextLength + nIndex > nStringLength)
+ {
+ nTextLength = nStringLength - nIndex;
+ }
+
+ if(nTextLength)
+ {
+ aRetval.reserve(nTextLength);
+ sal_Int32* pArray = new sal_Int32[nTextLength];
+ mrDevice.GetTextArray(rText, pArray, nIndex, nLength);
+
+ for(sal_uInt32 a(0); a < nTextLength; a++)
+ {
+ aRetval.push_back(pArray[a]);
+ }
+ }
+
+ return aRetval;
+ }
+
} // end of namespace primitive2d
} // end of namespace drawinglayer