summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2009-09-17 10:29:02 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2009-09-17 10:29:02 +0000
commit762181f6f1168e0eb54009990222d7cb4cebebd5 (patch)
treeeae0197fb4e9ee2549d31e358f01386145cff5a9 /drawinglayer
parent4e5d76b3cef5a863d5961e33a0c08c26b0b6dc2d (diff)
CWS-TOOLING: integrate CWS aw077
2009-09-17 Armin Le Grand #resolved conflicts for integration 2009-09-07 Armin Le Grand #i103058# re-added handling of StatusBar texts for DrawObject creation, added FullDrag for circle-similar shapes (all in the ellipse toolbar) 2009-09-03 Armin Le Grand #i100514# extended TextAttributes and handling, adapted for super/subscript, adapted WordBreaking (again) 2009-09-02 Armin Le Grand #i104432# secured TextLayouterDevice::getTextBoundRect implementation and usage 2009-09-02 Armin Le Grand #i104232#, #i100514# Mainly solved 1st one, no more local SpellCheck remembering, but adding to compare op's where needed 2009-08-19 Armin Le Grand #i100514# commited in-between version due to 2week holiday 2009-08-13 Armin Le Grand #i99157# applied changes to BitmapEx and SdrHdlBitmapSet 2009-08-06 Armin Le Grand #i100357# added clipping for too big MetaFiles
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx42
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx8
-rw-r--r--drawinglayer/source/primitive2d/graphicprimitive2d.cxx33
-rw-r--r--drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx118
-rw-r--r--drawinglayer/source/primitive2d/textlayoutdevice.cxx200
-rw-r--r--drawinglayer/source/primitive2d/textprimitive2d.cxx167
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.cxx75
7 files changed, 353 insertions, 290 deletions
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
index b9639aeacc50..df09718a7582 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/textlayoutdevice.hxx
@@ -76,8 +76,11 @@ namespace drawinglayer
~TextLayouterDevice();
void setFont(const Font& rFont);
- void setFontAttributes(const FontAttributes& rFontAttributes, const basegfx::B2DHomMatrix& rTransform, const ::com::sun::star::lang::Locale & rLocale);
- void setFontAttributes(const FontAttributes& rFontAttributes, double fFontScaleX, double fFontScaleY, const ::com::sun::star::lang::Locale & rLocale);
+ void setFontAttributes(
+ const FontAttributes& rFontAttributes,
+ double fFontScaleX,
+ double fFontScaleY,
+ const ::com::sun::star::lang::Locale & rLocale);
double getTextHeight() const;
double getOverlineHeight() const;
@@ -85,9 +88,6 @@ namespace drawinglayer
double getUnderlineHeight() const;
double getUnderlineOffset() const;
double getStrikeoutOffset() const;
-#ifdef WIN32
- double getCurrentFontRelation() const;
-#endif
double getTextWidth(
const String& rText,
@@ -99,9 +99,7 @@ namespace drawinglayer
const String& rText,
xub_StrLen nIndex,
xub_StrLen nLength,
- // #i89784# added suppirt for DXArray for justified text
- const ::std::vector< double >& rDXArray,
- double fFontScaleWidth);
+ const ::std::vector< double >& rDXArray);
basegfx::B2DRange getTextBoundRect(
const String& rText,
@@ -112,27 +110,33 @@ namespace drawinglayer
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
+// helper methods for vcl font handling
namespace drawinglayer
{
namespace primitive2d
{
- // helper methods for vcl font handling
+ // Create a VCL-Font based on the definitions in FontAttributes
+ // and the given FontScaling. The FontScaling defines the FontHeight
+ // (fFontScaleY) and the FontWidth (fFontScaleX). The combination of
+ // both defines FontStretching, where no stretching happens at
+ // fFontScaleY == fFontScaleX
Font getVclFontFromFontAttributes(
const FontAttributes& rFontAttributes,
double fFontScaleX,
double fFontScaleY,
double fFontRotation,
- const ::com::sun::star::lang::Locale & rLocale,
- const OutputDevice& rOutDev);
-
- Font getVclFontFromFontAttributes(
- const FontAttributes& rFontAttributes,
- const basegfx::B2DHomMatrix& rTransform,
- const ::com::sun::star::lang::Locale & rLocale,
- const OutputDevice& rOutDev);
-
- FontAttributes getFontAttributesFromVclFont(basegfx::B2DVector& rSize, const Font& rFont, bool bRTL, bool bBiDiStrong);
+ const ::com::sun::star::lang::Locale & rLocale);
+
+ // Generate FontAttributes DataSet derived from the given VCL-Font.
+ // The FontScaling with fFontScaleY, fFontScaleX relationship (see
+ // above) will be set in return parameter o_rSize to allow further
+ // processing
+ FontAttributes getFontAttributesFromVclFont(
+ basegfx::B2DVector& o_rSize,
+ const Font& rFont,
+ bool bRTL,
+ bool bBiDiStrong);
} // end of namespace primitive2d
} // end of namespace drawinglayer
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
index 9515fcc22ee8..d7f9bdb1e89a 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/textprimitive2d.hxx
@@ -158,14 +158,6 @@ namespace drawinglayer
// the necessary VCL outline extractins, scaling adaptions and other stuff.
void getTextOutlinesAndTransformation(basegfx::B2DPolyPolygonVector& rTarget, basegfx::B2DHomMatrix& rTransformation) const;
- // adapts fontScale for usage with TextLayouter. Input is rScale which is the extracted
- // scale from a text transformation. A copy goes to rFontScale and is modified so that
- // it contains only positive scalings and XY-equal scalings to allow to get a non-X-scaled
- // Vcl-Font for TextLayouter. rScale is adapted accordingly to contain the corrected scale
- // which would need to be applied to e.g. outlines received from TextLayouter under
- // usage of fontScale. This includes Y-Scale, X-Scale-correction and mirrorings.
- void getCorrectedScaleAndFontScale(basegfx::B2DVector& rScale, basegfx::B2DVector& rFontScale) const;
-
// get data
const basegfx::B2DHomMatrix& getTextTransform() const { return maTextTransform; }
const String& getText() const { return maText; }
diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
index ffceaf8ce04a..1ed826dab562 100644
--- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
@@ -266,7 +266,38 @@ namespace drawinglayer
case GRAPHIC_GDIMETAFILE :
{
- xPrimitive = Primitive2DReference(new MetafilePrimitive2D(getTransform(), aTransformedGraphic.GetGDIMetaFile()));
+ // create MetafilePrimitive2D
+ const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile();
+
+ xPrimitive = Primitive2DReference(
+ new MetafilePrimitive2D(
+ getTransform(),
+ rMetafile));
+
+ // #i100357# find out if clipping is needed for this primitive. Unfortunately,
+ // there exist Metafiles who's content is bigger than the proposed PrefSize set
+ // at them. This is an error, but we need to work around this
+ const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
+ const Size aMetaFileRealSize(
+ const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
+ *Application::GetDefaultDevice()).GetSize());
+
+ if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
+ || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
+ {
+ // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
+ const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1);
+ basegfx::B2DPolygon aMaskPolygon(
+ basegfx::tools::createPolygonFromRect(
+ basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
+ aMaskPolygon.transform(getTransform());
+
+ xPrimitive = Primitive2DReference(
+ new MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(aMaskPolygon),
+ aChildContent));
+ }
+
break;
}
diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
index 94e92a149e50..d337950c6c6b 100644
--- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -277,15 +277,16 @@ namespace drawinglayer
const FontAttributes& rFontAttributes) const
{
// create the SimpleTextPrimitive needed in any case
- rTarget.push_back(Primitive2DReference(new TextSimplePortionPrimitive2D(
- rDecTrans.getB2DHomMatrix(),
- rText,
- aTextPosition,
- aTextLength,
- rDXArray,
- rFontAttributes,
- getLocale(),
- getFontColor())));
+ rTarget.push_back(Primitive2DReference(
+ new TextSimplePortionPrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ rText,
+ aTextPosition,
+ aTextLength,
+ rDXArray,
+ rFontAttributes,
+ getLocale(),
+ getFontColor())));
// see if something else needs to be done
const bool bOverlineUsed(FONT_UNDERLINE_NONE != getFontOverline());
@@ -305,7 +306,11 @@ namespace drawinglayer
// TextLayouterDevice is needed to get metrics for text decorations like
// underline/strikeout/emphasis marks from it. For setup, the font size is needed
- aTextLayouter.setFontAttributes(getFontAttributes(), rDecTrans.getScale().getX(), rDecTrans.getScale().getY(), getLocale());
+ aTextLayouter.setFontAttributes(
+ getFontAttributes(),
+ rDecTrans.getScale().getX(),
+ rDecTrans.getScale().getY(),
+ getLocale());
// get text width
double fTextWidth(0.0);
@@ -317,6 +322,14 @@ namespace drawinglayer
else
{
fTextWidth = rDXArray.back() * rDecTrans.getScale().getX();
+ const double fFontScaleX(rDecTrans.getScale().getX());
+
+ if(!basegfx::fTools::equal(fFontScaleX, 1.0)
+ && !basegfx::fTools::equalZero(fFontScaleX))
+ {
+ // need to take FontScaling out of the DXArray
+ fTextWidth /= fFontScaleX;
+ }
}
if(bOverlineUsed)
@@ -343,28 +356,26 @@ namespace drawinglayer
const String aSingleCharString(aStrikeoutChar);
const double fStrikeCharWidth(aTextLayouter.getTextWidth(aSingleCharString, 0, 1));
const double fStrikeCharCount(fabs(fTextWidth/fStrikeCharWidth));
- const sal_uInt32 nStrikeCharCount(static_cast< sal_uInt32 >(fStrikeCharCount + 0.9));
- const double fScaleX(rDecTrans.getScale().getX());
- const double fStrikeCharWidthUnscaled(basegfx::fTools::equalZero(fScaleX) ? fStrikeCharWidth : fStrikeCharWidth/fScaleX);
-
+ const sal_uInt32 nStrikeCharCount(static_cast< sal_uInt32 >(fStrikeCharCount + 0.5));
std::vector<double> aDXArray(nStrikeCharCount);
String aStrikeoutString;
for(sal_uInt32 a(0); a < nStrikeCharCount; a++)
{
aStrikeoutString += aSingleCharString;
- aDXArray[a] = (a + 1) * fStrikeCharWidthUnscaled;
+ aDXArray[a] = (a + 1) * fStrikeCharWidth;
}
- rTarget.push_back(Primitive2DReference(new TextSimplePortionPrimitive2D(
- rDecTrans.getB2DHomMatrix(),
- aStrikeoutString,
- 0,
- aStrikeoutString.Len(),
- aDXArray,
- rFontAttributes,
- getLocale(),
- getFontColor())));
+ rTarget.push_back(Primitive2DReference(
+ new TextSimplePortionPrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ aStrikeoutString,
+ 0,
+ aStrikeoutString.Len(),
+ aDXArray,
+ rFontAttributes,
+ getLocale(),
+ getFontColor())));
}
else
{
@@ -483,17 +494,15 @@ namespace drawinglayer
xLocalBreakIterator.set(xMSF->createInstance(rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator")), ::com::sun::star::uno::UNO_QUERY);
}
- if(xLocalBreakIterator.is())
+ if(xLocalBreakIterator.is() && getTextLength())
{
// init word iterator, get first word and truncate to possibilities
::com::sun::star::i18n::Boundary aNextWordBoundary(xLocalBreakIterator->getWordBoundary(
getText(), getTextPosition(), getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True));
- if(aNextWordBoundary.endPos == getTextPosition() && getTextLength() > 0)
+ if(aNextWordBoundary.endPos == getTextPosition())
{
- // #i96474#
- // a word before was found (this can happen when search starts on a whitespace and a word
- // in front of it exists), force to look one position further
+ // backward hit, force next word
aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
getText(), getTextPosition() + 1, getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
}
@@ -526,7 +535,11 @@ namespace drawinglayer
if(bNoDXArray)
{
// ..but only completely when no DXArray
- aTextLayouter.setFontAttributes(getFontAttributes(), rDecTrans.getScale().getX(), rDecTrans.getScale().getY(),getLocale());
+ aTextLayouter.setFontAttributes(
+ getFontAttributes(),
+ rDecTrans.getScale().getX(),
+ rDecTrans.getScale().getY(),
+ getLocale());
}
// do iterate over single words
@@ -566,12 +579,25 @@ namespace drawinglayer
fOffset = getDXArray()[nIndex - 1];
}
+ // need offset without FontScale for building the new transformation. The
+ // new transformation will be multiplied with the current text transformation
+ // so FontScale would be double
+ double fOffsetNoScale(fOffset);
+ const double fFontScaleX(rDecTrans.getScale().getX());
+
+ if(!basegfx::fTools::equal(fFontScaleX, 1.0)
+ && !basegfx::fTools::equalZero(fFontScaleX))
+ {
+ fOffsetNoScale /= fFontScaleX;
+ }
+
// apply needed offset to transformation
- aNewTransform.translate(fOffset, 0.0);
+ aNewTransform.translate(fOffsetNoScale, 0.0);
if(!bNoDXArray)
{
- // DXArray values need to be corrected with the offset, too
+ // DXArray values need to be corrected with the offset, too. Here,
+ // take the scaled offset since the DXArray is scaled
const sal_uInt32 nArraySize(aNewDXArray.size());
for(sal_uInt32 a(0); a < nArraySize; a++)
@@ -591,12 +617,30 @@ namespace drawinglayer
impCreateGeometryContent(rTarget, aDecTrans, getText(), nNewTextStart,
nNewTextEnd - nNewTextStart, aNewDXArray, aNewFontAttributes);
- // prepare next word and truncate to possibilities
- aNextWordBoundary = xLocalBreakIterator->nextWord(
- getText(), aNextWordBoundary.endPos, getLocale(),
- ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES);
+ if(aNextWordBoundary.endPos >= getTextPosition() + getTextLength())
+ {
+ // end reached
+ aNextWordBoundary.startPos = aNextWordBoundary.endPos;
+ }
+ else
+ {
+ // get new word portion
+ const sal_Int32 nLastEndPos(aNextWordBoundary.endPos);
+
+ aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
+ getText(), aNextWordBoundary.endPos, getLocale(),
+ ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
- impCorrectTextBoundary(aNextWordBoundary);
+ if(nLastEndPos == aNextWordBoundary.endPos)
+ {
+ // backward hit, force next word
+ aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
+ getText(), nLastEndPos + 1, getLocale(),
+ ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
+ }
+
+ impCorrectTextBoundary(aNextWordBoundary);
+ }
}
}
}
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 0055af3ea4bd..e321783c8406 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -43,6 +43,7 @@
#include <vcl/metric.hxx>
#include <i18npool/mslangid.hxx>
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <vcl/svapp.hxx>
//////////////////////////////////////////////////////////////////////////////
// VDev RevDevice provider
@@ -166,14 +167,18 @@ namespace drawinglayer
mrDevice.SetFont( rFont );
}
- void TextLayouterDevice::setFontAttributes(const FontAttributes& rFontAttributes, const basegfx::B2DHomMatrix& rTransform, const ::com::sun::star::lang::Locale & rLocale)
- {
- setFont(getVclFontFromFontAttributes(rFontAttributes, rTransform, rLocale, mrDevice));
- }
-
- void TextLayouterDevice::setFontAttributes(const FontAttributes& rFontAttributes, double fFontScaleX, double fFontScaleY, const ::com::sun::star::lang::Locale & rLocale)
+ void TextLayouterDevice::setFontAttributes(
+ const FontAttributes& rFontAttributes,
+ double fFontScaleX,
+ double fFontScaleY,
+ const ::com::sun::star::lang::Locale& rLocale)
{
- setFont(getVclFontFromFontAttributes(rFontAttributes, fFontScaleX, fFontScaleY, 0.0, rLocale, mrDevice));
+ setFont(getVclFontFromFontAttributes(
+ rFontAttributes,
+ fFontScaleX,
+ fFontScaleY,
+ 0.0,
+ rLocale));
}
double TextLayouterDevice::getOverlineOffset() const
@@ -197,18 +202,6 @@ namespace drawinglayer
return fRet;
}
-#ifdef WIN32
- double TextLayouterDevice::getCurrentFontRelation() const
- {
- const Font aFont(mrDevice.GetFont());
- const FontMetric aFontMetric(mrDevice.GetFontMetric(aFont));
- const double fWidth(aFontMetric.GetWidth());
- const double fHeight(aFont.GetHeight());
-
- return basegfx::fTools::equalZero(fWidth) ? 1.0 : fHeight / fWidth;
- }
-#endif
-
double TextLayouterDevice::getOverlineHeight() const
{
const ::FontMetric& rMetric = mrDevice.GetFontMetric();
@@ -241,33 +234,42 @@ namespace drawinglayer
const String& rText,
xub_StrLen nIndex,
xub_StrLen nLength,
- // #i89784# added suppirt for DXArray for justified text
- const ::std::vector< double >& rDXArray,
- double fFontScaleWidth)
+ const ::std::vector< double >& rDXArray)
{
- std::vector< sal_Int32 > aTransformedDXArray;
- const sal_uInt32 nDXArraySize(rDXArray.size());
+ const sal_uInt32 nDXArrayCount(rDXArray.size());
- if(nDXArraySize && basegfx::fTools::more(fFontScaleWidth, 0.0))
+ if(nDXArrayCount)
{
- OSL_ENSURE(nDXArraySize == nLength, "DXArray size does not correspond to text portion size (!)");
- aTransformedDXArray.reserve(nDXArraySize);
+ OSL_ENSURE(nDXArrayCount == nLength, "DXArray size does not correspond to text portion size (!)");
+ std::vector< sal_Int32 > aIntegerDXArray(nDXArrayCount);
- for(std::vector< double >::const_iterator aStart(rDXArray.begin()); aStart != rDXArray.end(); aStart++)
+ for(sal_uInt32 a(0); a < nDXArrayCount; a++)
{
- aTransformedDXArray.push_back(basegfx::fround((*aStart) * fFontScaleWidth));
+ aIntegerDXArray[a] = basegfx::fround(rDXArray[a]);
}
- }
- return mrDevice.GetTextOutlines(
- rB2DPolyPolyVector,
- rText,
- nIndex,
- nIndex,
- nLength,
- true,
- 0,
- nDXArraySize ? &(aTransformedDXArray[0]) : 0);
+ return mrDevice.GetTextOutlines(
+ rB2DPolyPolyVector,
+ rText,
+ nIndex,
+ nIndex,
+ nLength,
+ true,
+ 0,
+ &(aIntegerDXArray[0]));
+ }
+ else
+ {
+ return mrDevice.GetTextOutlines(
+ rB2DPolyPolyVector,
+ rText,
+ nIndex,
+ nIndex,
+ nLength,
+ true,
+ 0,
+ 0);
+ }
}
basegfx::B2DRange TextLayouterDevice::getTextBoundRect(
@@ -286,7 +288,7 @@ namespace drawinglayer
nIndex,
nLength);
- // #i102556# take empty results into account
+ // #i104432#, #i102556# take empty results into account
if(!aRect.IsEmpty())
{
return basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
@@ -307,38 +309,36 @@ namespace drawinglayer
{
Font getVclFontFromFontAttributes(
const FontAttributes& rFontAttributes,
- const basegfx::B2DHomMatrix& rTransform,
- const ::com::sun::star::lang::Locale & rLocale,
- const OutputDevice& rOutDev)
- {
- // decompose matrix to have position and size of text
- basegfx::B2DVector aScale, aTranslate;
- double fRotate, fShearX;
-
- rTransform.decompose(aScale, aTranslate, fRotate, fShearX);
-
- return getVclFontFromFontAttributes(rFontAttributes, aScale.getX(), aScale.getY(), fRotate, rLocale, rOutDev);
- }
-
- Font getVclFontFromFontAttributes(
- const FontAttributes& rFontAttributes,
double fFontScaleX,
double fFontScaleY,
double fFontRotation,
- const ::com::sun::star::lang::Locale & rLocale,
- const OutputDevice& /*rOutDev*/)
+ const ::com::sun::star::lang::Locale& rLocale)
{
- sal_uInt32 nWidth(basegfx::fround(fabs(fFontScaleX)));
- sal_uInt32 nHeight(basegfx::fround(fabs(fFontScaleY)));
+ // detect FontScaling
+ const sal_uInt32 nHeight(basegfx::fround(fabs(fFontScaleY)));
+ const sal_uInt32 nWidth(basegfx::fround(fabs(fFontScaleX)));
+ const bool bFontIsScaled(nHeight != nWidth);
+
+#ifdef WIN32
+ // for WIN32 systems, start with creating an unscaled font. If FontScaling
+ // is wanted, that width needs to be adapted using FontMetric again to get a
+ // width of the unscaled font
Font aRetval(
rFontAttributes.getFamilyName(),
rFontAttributes.getStyleName(),
-#ifdef WIN32
Size(0, nHeight));
#else
- Size(nWidth, nHeight));
+ // for non-WIN32 systems things are easier since these accept a Font creation
+ // with initially nWidth != nHeight for FontScaling. Despite that, use zero for
+ // FontWidth when no scaling is used to explicitely have that zero when e.g. the
+ // Font would be recorded in a MetaFile (The MetaFile FontAction WILL record a
+ // set FontWidth; import that in a WIN32 system, and trouble is there)
+ Font aRetval(
+ rFontAttributes.getFamilyName(),
+ rFontAttributes.getStyleName(),
+ Size(bFontIsScaled ? nWidth : 0, nHeight));
#endif
-
+ // define various other FontAttributes
aRetval.SetAlign(ALIGN_BASELINE);
aRetval.SetCharSet(rFontAttributes.getSymbol() ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE);
aRetval.SetVertical(rFontAttributes.getVertical() ? TRUE : FALSE);
@@ -348,32 +348,20 @@ namespace drawinglayer
aRetval.SetLanguage(MsLangId::convertLocaleToLanguage(rLocale));
#ifdef WIN32
- // #100424# use higher precision
- if(!basegfx::fTools::equal(fFontScaleX, fFontScaleY))
+ // for WIN32 systems, correct the FontWidth if FontScaling is used
+ if(bFontIsScaled && nHeight > 0)
{
- // #i92757#
- // Removed the relative calculation with GetFontMetric() usage again. On
- // the one hand it was wrong (integer division always created zero), OTOH
- // calculating a scale factor from current to target width and then using
- // it to actually scale the current width does nothing but set the target
- // value directly. Maybe more is needed here with WIN version of font
- // width/height handling, but currently, this works the simple way.
- //
- // As can be seen, when this can stay the simple way, the OutputDevice
- // can be removed from the whole getVclFontFromFontAttributes implementations
- // again and make it more VCL-independent.
- //
- // Adapted nWidth usage to nWidth-1 to be completely compatible with
- // non-primitive version.
- //
- // previous stuff:
- // const FontMetric aFontMetric(rOutDev.GetFontMetric(aRetval));
- // const double fCurrentWidth(aFontMetric.GetWidth());
- // aRetval.SetWidth(basegfx::fround(fCurrentWidth * ((double)nWidth/(double)nHeight)));
- aRetval.SetWidth(nWidth ? nWidth - 1 : 0);
+ const FontMetric aUnscaledFontMetric(Application::GetDefaultDevice()->GetFontMetric(aRetval));
+
+ if(aUnscaledFontMetric.GetWidth() > 0)
+ {
+ const double fScaleFactor((double)nWidth / (double)nHeight);
+ const sal_uInt32 nScaledWidth(basegfx::fround((double)aUnscaledFontMetric.GetWidth() * fScaleFactor));
+ aRetval.SetWidth(nScaledWidth);
+ }
}
#endif
-
+ // handle FontRotation (if defined)
if(!basegfx::fTools::equalZero(fFontRotation))
{
sal_Int16 aRotate10th((sal_Int16)(fFontRotation * (-1800.0/F_PI)));
@@ -383,9 +371,13 @@ namespace drawinglayer
return aRetval;
}
- FontAttributes getFontAttributesFromVclFont(basegfx::B2DVector& rSize, const Font& rFont, bool bRTL, bool bBiDiStrong)
+ FontAttributes getFontAttributesFromVclFont(
+ basegfx::B2DVector& o_rSize,
+ const Font& rFont,
+ bool bRTL,
+ bool bBiDiStrong)
{
- FontAttributes aRetval(
+ const FontAttributes aRetval(
rFont.GetName(),
rFont.GetStyleName(),
static_cast<sal_uInt16>(rFont.GetWeight()),
@@ -397,12 +389,38 @@ namespace drawinglayer
bBiDiStrong);
// TODO: eKerning
- const sal_Int32 nWidth(rFont.GetSize().getWidth());
- const sal_Int32 nHeight(rFont.GetSize().getHeight());
+ // set FontHeight and init to no FontScaling
+ o_rSize.setY(rFont.GetSize().getHeight() > 0 ? rFont.GetSize().getHeight() : 0);
+ o_rSize.setX(o_rSize.getY());
- rSize.setX(nWidth ? nWidth : nHeight);
- rSize.setY(nHeight);
+#ifdef WIN32
+ // for WIN32 systems, the FontScaling at the Font is detected by
+ // checking that FontWidth != 0. When FontScaling is used, WIN32
+ // needs to do extra stuff to detect the correct width (since it's
+ // zero and not equal the font height) and it's relationship to
+ // the height
+ if(rFont.GetSize().getWidth() > 0)
+ {
+ Font aUnscaledFont(rFont);
+ aUnscaledFont.SetWidth(0);
+ const FontMetric aUnscaledFontMetric(Application::GetDefaultDevice()->GetFontMetric(aUnscaledFont));
+ if(aUnscaledFontMetric.GetWidth() > 0)
+ {
+ const double fScaleFactor((double)rFont.GetSize().getWidth() / (double)aUnscaledFontMetric.GetWidth());
+ o_rSize.setX(fScaleFactor * o_rSize.getY());
+ }
+ }
+#else
+ // For non-WIN32 systems the detection is the same, but the value
+ // is easier achieved since width == height is interpreted as no
+ // scaling. Ergo, Width == 0 means width == height, and width != 0
+ // means the scaling is in the direct relation of width to height
+ if(rFont.GetSize().getWidth() > 0)
+ {
+ o_rSize.setX((double)rFont.GetSize().getWidth());
+ }
+#endif
return aRetval;
}
} // end of namespace primitive2d
diff --git a/drawinglayer/source/primitive2d/textprimitive2d.cxx b/drawinglayer/source/primitive2d/textprimitive2d.cxx
index 7c62c235c21d..f8e413da0e8c 100644
--- a/drawinglayer/source/primitive2d/textprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textprimitive2d.cxx
@@ -70,49 +70,63 @@ namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
-namespace drawinglayer
+namespace
{
- namespace primitive2d
+ // adapts fontScale for usage with TextLayouter. Input is rScale which is the extracted
+ // scale from a text transformation. A copy is modified so that it contains only positive
+ // scalings and XY-equal scalings to allow to get a non-X-scaled Vcl-Font for TextLayouter.
+ // rScale is adapted accordingly to contain the corrected scale which would need to be
+ // applied to e.g. outlines received from TextLayouter under usage of fontScale. This
+ // includes Y-Scale, X-Scale-correction and mirrorings.
+ basegfx::B2DVector getCorrectedScaleAndFontScale(basegfx::B2DVector& rScale)
{
- void TextSimplePortionPrimitive2D::getCorrectedScaleAndFontScale(basegfx::B2DVector& rScale, basegfx::B2DVector& rFontScale) const
- {
- // copy input value
- rFontScale = rScale;
+ // copy input value
+ basegfx::B2DVector aFontScale(rScale);
- if(basegfx::fTools::equalZero(rFontScale.getY()))
- {
- // no font height; choose one and adapt scale to get back to original scaling
- static double fDefaultFontScale(100.0);
- rScale.setY(1.0 / fDefaultFontScale);
- rFontScale.setY(fDefaultFontScale);
- }
- else if(basegfx::fTools::less(rFontScale.getY(), 0.0))
- {
- // negative font height; invert and adapt scale to get back to original scaling
- rFontScale.setY(-rFontScale.getY());
- rScale.setY(-1.0);
- }
- else
- {
- // positive font height; adapt scale; scaling will be part of the polygons
- rScale.setY(1.0);
- }
+ // correct FontHeight settings
+ if(basegfx::fTools::equalZero(aFontScale.getY()))
+ {
+ // no font height; choose one and adapt scale to get back to original scaling
+ static double fDefaultFontScale(100.0);
+ rScale.setY(1.0 / fDefaultFontScale);
+ aFontScale.setY(fDefaultFontScale);
+ }
+ else if(basegfx::fTools::less(aFontScale.getY(), 0.0))
+ {
+ // negative font height; invert and adapt scale to get back to original scaling
+ aFontScale.setY(-aFontScale.getY());
+ rScale.setY(-1.0);
+ }
+ else
+ {
+ // positive font height; adapt scale; scaling will be part of the polygons
+ rScale.setY(1.0);
+ }
- if(basegfx::fTools::equal(rFontScale.getX(), rFontScale.getY()))
- {
- // adapt scale in X
- rScale.setX(1.0);
- }
- else
- {
- // If font scale is different in X and Y, force font scale to equal
- // in X and Y to get a non-scaled VCL font.
- // Adapt scaling in X accordingly. FontScaleY cannot be zero here.
- rScale.setX(rFontScale.getX()/rFontScale.getY());
- rFontScale.setX(rFontScale.getY());
- }
+ // correct FontWidth settings
+ if(basegfx::fTools::equal(aFontScale.getX(), aFontScale.getY()))
+ {
+ // no FontScale, adapt scale
+ rScale.setX(1.0);
}
+ else
+ {
+ // If FontScale is used, force to no FontScale to get a non-scaled VCL font.
+ // Adapt scaling in X accordingly.
+ rScale.setX(aFontScale.getX() / aFontScale.getY());
+ aFontScale.setX(aFontScale.getY());
+ }
+
+ return aFontScale;
+ }
+} // end of anonymous namespace
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
void TextSimplePortionPrimitive2D::getTextOutlinesAndTransformation(basegfx::B2DPolyPolygonVector& rTarget, basegfx::B2DHomMatrix& rTransformation) const
{
if(getTextLength())
@@ -137,33 +151,47 @@ namespace drawinglayer
// the font size. Since we want to extract polygons here, it is okay to
// work just with scaling and to ignore shear, rotation and translation,
// all that can be applied to the polygons later
-#ifdef WIN32
- const bool bCorrectScale(!basegfx::fTools::equal(fabs(aScale.getX()), fabs(aScale.getY())));
-#endif
- basegfx::B2DVector aFontScale;
- getCorrectedScaleAndFontScale(aScale, aFontScale);
+ const basegfx::B2DVector aFontScale(getCorrectedScaleAndFontScale(aScale));
// prepare textlayoutdevice
TextLayouterDevice aTextLayouter;
- aTextLayouter.setFontAttributes(getFontAttributes(), aFontScale.getX(), aFontScale.getY(), getLocale());
-#ifdef WIN32
- // when under Windows and the font is unequally scaled, need to correct font X-Scaling factor
- if(bCorrectScale)
+ aTextLayouter.setFontAttributes(
+ getFontAttributes(),
+ aFontScale.getX(),
+ aFontScale.getY(),
+ getLocale());
+
+ // When getting outlines from stretched text (aScale.getX() != 1.0) it
+ // is necessary to inverse-scale the DXArray (if used) to not get the
+ // outlines already aligned to given, but wrong DXArray
+ if(getDXArray().size() && !basegfx::fTools::equal(aScale.getX(), 1.0))
+ {
+ ::std::vector< double > aScaledDXArray = getDXArray();
+ const double fDXArrayScale(1.0 / aScale.getX());
+
+ for(sal_uInt32 a(0); a < aScaledDXArray.size(); a++)
+ {
+ aScaledDXArray[a] *= fDXArrayScale;
+ }
+
+ // get the text outlines
+ aTextLayouter.getTextOutlines(
+ rTarget,
+ getText(),
+ getTextPosition(),
+ getTextLength(),
+ aScaledDXArray);
+ }
+ else
{
- const double fFontRelation(aTextLayouter.getCurrentFontRelation());
- aScale.setX(aScale.getX() * fFontRelation);
- aFontScale.setX(aFontScale.getX() / fFontRelation);
+ // get the text outlines
+ aTextLayouter.getTextOutlines(
+ rTarget,
+ getText(),
+ getTextPosition(),
+ getTextLength(),
+ getDXArray());
}
-#endif
- // get the text outlines. No DXArray is given (would contain integers equal to unit vector
- // transformed by object's transformation), let VCL do the job
- aTextLayouter.getTextOutlines(
- rTarget, getText(),
- getTextPosition(),
- getTextLength(),
- // #i89784# added support for DXArray for justified text
- getDXArray(),
- aFontScale.getX());
// create primitives for the outlines
const sal_uInt32 nCount(rTarget.size());
@@ -300,29 +328,22 @@ namespace drawinglayer
// the font size. Since we want to extract polygons here, it is okay to
// work just with scaling and to ignore shear, rotation and translation,
// all that can be applied to the polygons later
-#ifdef WIN32
- const bool bCorrectScale(!basegfx::fTools::equal(fabs(aScale.getX()), fabs(aScale.getY())));
-#endif
- basegfx::B2DVector aFontScale;
- getCorrectedScaleAndFontScale(aScale, aFontScale);
+ const basegfx::B2DVector aFontScale(getCorrectedScaleAndFontScale(aScale));
// prepare textlayoutdevice
TextLayouterDevice aTextLayouter;
- aTextLayouter.setFontAttributes(getFontAttributes(), aFontScale.getX(), aFontScale.getY(), getLocale());
+ aTextLayouter.setFontAttributes(
+ getFontAttributes(),
+ aFontScale.getX(),
+ aFontScale.getY(),
+ getLocale());
// get basic text range
basegfx::B2DRange aNewRange(aTextLayouter.getTextBoundRect(getText(), getTextPosition(), getTextLength()));
- // #i102556# take empty results into account
+ // #i104432#, #i102556# take empty results into account
if(!aNewRange.isEmpty())
{
-#ifdef WIN32
- // when under Windows and the font is unequally scaled, need to correct font X-Scaling factor
- if(bCorrectScale)
- {
- aScale.setX(aScale.getX() * aTextLayouter.getCurrentFontRelation());
- }
-#endif
// prepare object transformation for range
basegfx::B2DHomMatrix aRangeTransformation;
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index daf8ce5d525f..e5a88812dd10 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -138,79 +138,31 @@ namespace drawinglayer
{
// decompose matrix to have position and size of text
basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rTextCandidate.getTextTransform());
- basegfx::B2DVector aScale, aTranslate;
+ basegfx::B2DVector aFontScaling, aTranslate;
double fRotate, fShearX;
- aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
+ aLocalTransform.decompose(aFontScaling, aTranslate, fRotate, fShearX);
bool bPrimitiveAccepted(false);
if(basegfx::fTools::equalZero(fShearX))
{
- if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
+ if(basegfx::fTools::less(aFontScaling.getX(), 0.0) && basegfx::fTools::less(aFontScaling.getY(), 0.0))
{
// handle special case: If scale is negative in (x,y) (3rd quadrant), it can
- // be expressed as rotation by PI
- aScale = basegfx::absolute(aScale);
+ // be expressed as rotation by PI. Use this since the Font rendering will not
+ // apply the negative scales in any form
+ aFontScaling = basegfx::absolute(aFontScaling);
fRotate += F_PI;
}
- if(basegfx::fTools::more(aScale.getX(), 0.0) && basegfx::fTools::more(aScale.getY(), 0.0))
+ if(basegfx::fTools::more(aFontScaling.getX(), 0.0) && basegfx::fTools::more(aFontScaling.getY(), 0.0))
{
- // #i96581# Get the font forced without FontStretching (use FontHeight as FontWidth)
+ // Get the VCL font (use FontHeight as FontWidth)
Font aFont(primitive2d::getVclFontFromFontAttributes(
rTextCandidate.getFontAttributes(),
-
- // #i100373# FontScaling
- //
- // There are two different definitions for unscaled fonts, (1) 0==width and
- // (2) height==width where (2) is the more modern one supported on all non-WIN32
- // systems and (1) is the old one coming from WIN16-VCL definitions where
- // that ominous FontWidth (available over FontMetric) is involved. While
- // WIN32 only supports (1), all other systems support (2). When on WIN32, the
- // support for (1) is ensured inside getVclFontFromFontAttributes.
- //
- // The former usage of (2) leads to problems when it is used on non-WIN32 systems
- // and exported to MetaFile FontActions where the scale is taken over unseen. When
- // such a MetaFile is imported on a WIN32-System supporting (1), all fonts are
- // seen as scaled an look wrong.
- //
- // The simplest and fastest solution is to fallback to (1) independent from the
- // system we are running on.
- //
- // The best solution would be a system-independent Y-value just expressing the
- // font scaling, e.g. when (2) is used and width == height, use 1.0 as Y-Value,
- // which would also solve the involved ominous FontWidth value for WIN32-systems.
- // This is a region which needs redesign urgently.
- //
- 0, // aScale.getY(),
-
- aScale.getY(),
+ aFontScaling.getX(),
+ aFontScaling.getY(),
fRotate,
- rTextCandidate.getLocale(),
- *mpOutputDevice));
-
- if(!basegfx::fTools::equal(aScale.getX(), aScale.getY()))
- {
- // #100424# We have a hint on FontScaling here. To decide a look
- // at the pure font's scale is needed, since e.g. SC uses unequally scaled
- // MapModes (was: #i96581#, but use available full precision from primitive
- // now). aTranslate and fShearX can be reused since no longer needed.
- basegfx::B2DVector aFontScale;
- double fFontRotate;
- rTextCandidate.getTextTransform().decompose(aFontScale, aTranslate, fFontRotate, fShearX);
-
- if(!basegfx::fTools::equal(aFontScale.getX(), aFontScale.getY()))
- {
- // indeed a FontScaling. Set at Font. Use the combined scale
- // and rotate here
- aFont = primitive2d::getVclFontFromFontAttributes(
- rTextCandidate.getFontAttributes(),
- aScale.getX(),
- aScale.getY(),
- fRotate,
- rTextCandidate.getLocale(),
- *mpOutputDevice);
- }
- }
+ rTextCandidate.getLocale()));
// handle additional font attributes
const primitive2d::TextDecoratedPortionPrimitive2D* pTCPP =
@@ -314,10 +266,11 @@ namespace drawinglayer
if(rTextCandidate.getDXArray().size())
{
aTransformedDXArray.reserve(rTextCandidate.getDXArray().size());
- const basegfx::B2DVector aPixelVector(aLocalTransform * basegfx::B2DVector(1.0, 0.0));
+ const basegfx::B2DVector aPixelVector(maCurrentTransformation * basegfx::B2DVector(1.0, 0.0));
const double fPixelVectorFactor(aPixelVector.getLength());
- for(::std::vector< double >::const_iterator aStart(rTextCandidate.getDXArray().begin()); aStart != rTextCandidate.getDXArray().end(); aStart++)
+ for(::std::vector< double >::const_iterator aStart(rTextCandidate.getDXArray().begin());
+ aStart != rTextCandidate.getDXArray().end(); aStart++)
{
aTransformedDXArray.push_back(basegfx::fround((*aStart) * fPixelVectorFactor));
}