Kaydet (Commit) ba662ea4 authored tarafından Bartosz Kosiorek's avatar Bartosz Kosiorek

tdf#106084 EMF+ Implement String aligment and Leading/Trailing Margin.

Many users noticing that EMF DrawString is shifted horizontally in same cases.
It is caused by missing implementation of:
 - StringAlignment:
      Near: Alignment is to the left side of the layout rectangle
      Center: Specifies that alignment is centered
              between the origin and extent of the layout rectangle.
      Far:  Alignment is to the right side of the layout rectangle
 - Leading Margin: specifies the length of the space to add
   to the starting position of a string
 - trailing Margin: Length of the space to leave following a string.

With this path this missing parameters are implemented.
It was tested with document:
https://bugs.documentfoundation.org/attachment.cgi?id=131334

In following document StringAlignmentCenter and LeadingMargin is not set:
https://bugs.documentfoundation.org/attachment.cgi?id=124180
I make sure that there is no regression (the image should be displayed
as without the patch.

Change-Id: I7909a1d02ffd558a3bf91bd41f6945830252724d
Reviewed-on: https://gerrit.libreoffice.org/52696Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarPatrick Jaap <patrick.jaap@tu-dresden.de>
Reviewed-by: 's avatarBartosz Kosiorek <gang65@poczta.onet.pl>
üst 3bd63cc5
......@@ -100,6 +100,13 @@ namespace emfplushelper
{
}
typedef enum
{
StringAlignmentNear = 0x00000000,
StringAlignmentCenter = 0x00000001,
StringAlignmentFar = 0x00000002
} StringAlignment;
void EmfPlusHelperData::processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_uInt32 dataSize, bool bUseWholeStream)
{
sal_uInt32 index;
......@@ -1244,12 +1251,12 @@ namespace emfplushelper
SAL_INFO("drawinglayer", "EMF+ DrawString layoutRect: " << lx << "," << ly << " - " << lw << "x" << lh);
// parse the string
OUString text = read_uInt16s_ToOUString(rMS, stringLength);
const OUString text = read_uInt16s_ToOUString(rMS, stringLength);
SAL_INFO("drawinglayer", "EMF+ DrawString string: " << text);
// get the stringFormat from the Object table ( this is OPTIONAL and may be nullptr )
EMFPStringFormat *stringFormat = static_cast< EMFPStringFormat* >(maEMFPObjects[formatId & 0xff].get());
const EMFPStringFormat *stringFormat = static_cast< EMFPStringFormat* >(maEMFPObjects[formatId & 0xff].get());
// get the font from the flags
EMFPFont *font = static_cast< EMFPFont* >( maEMFPObjects[flags & 0xff].get() );
const EMFPFont *font = static_cast< EMFPFont* >( maEMFPObjects[flags & 0xff].get() );
if (!font)
{
break;
......@@ -1275,8 +1282,24 @@ namespace emfplushelper
false); // BiDiStrong
css::lang::Locale locale;
double stringAlignmentHorizontalOffset = 0.0;
if (stringFormat)
{
SAL_WARN_IF(stringFormat && stringFormat->DirectionRightToLeft(), "drawinglayer", "EMF+ DrawString Alignment TODO For a right-to-left layout rectangle, the origin should be at the upper right.");
if (stringFormat->stringAlignment == StringAlignmentNear)
// Alignment is to the left side of the layout rectangle (lx, ly, lw, lh)
{
stringAlignmentHorizontalOffset = stringFormat->leadingMargin * font->emSize;
} else if (stringFormat->stringAlignment == StringAlignmentCenter)
// Alignment is centered between the origin and extent of the layout rectangle
{
stringAlignmentHorizontalOffset = 0.5 * lw + stringFormat->leadingMargin * font->emSize - 0.3 * font->emSize * stringLength;
} else if (stringFormat->stringAlignment == StringAlignmentFar)
// Alignment is to the right side of the layout rectangle
{
stringAlignmentHorizontalOffset = lw - stringFormat->trailingMargin * font->emSize - 0.6 * font->emSize * stringLength;
}
LanguageTag aLanguageTag(static_cast< LanguageType >(stringFormat->language));
locale = aLanguageTag.getLocale();
}
......@@ -1286,10 +1309,10 @@ namespace emfplushelper
locale = Application::GetSettings().GetLanguageTag().getLocale();
}
basegfx::B2DHomMatrix transformMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix(MapSize(font->emSize,font->emSize),Map(lx,ly+font->emSize));
const basegfx::B2DHomMatrix transformMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix(
MapSize(font->emSize, font->emSize), Map(lx + stringAlignmentHorizontalOffset, ly + font->emSize));
const Color color = EMFPGetBrushColorOrARGBColor(flags, brushId);
mrPropertyHolders.Current().setTextColor(color.getBColor());
mrPropertyHolders.Current().setTextColorActive(true);
......
......@@ -35,7 +35,7 @@ namespace emfplushelper
, hotkeyPrefix(0)
, leadingMargin(0.0)
, trailingMargin(0.0)
, tracking(0.0)
, tracking(1.0)
, trimming(0)
, tabStopCount(0)
, rangeCount(0)
......@@ -52,10 +52,22 @@ namespace emfplushelper
language >>= 16;
digitLanguage >>= 16;
SAL_WARN_IF((header >> 12) != 0xdbc01, "drawinglayer", "Invalid header - not 0xdbc01");
SAL_INFO("drawinglayer", "EMF+\t string format\nEMF+\theader: 0x" << std::hex << (header >> 12) << " version: 0x" << (header & 0x1fff) << " StringFormatFlags: " << std::dec << stringFormatFlags << " Language: " << language);
SAL_INFO("drawinglayer", "EMF+\t string format\nEMF+\theader: 0x" << std::hex << (header >> 12) << " version: 0x" << (header & 0x1fff) << " StringFormatFlags: 0x" << stringFormatFlags << std::dec << " Language: " << language);
SAL_INFO("drawinglayer", "EMF+\t StringAlignment: " << stringAlignment << " LineAlign: " << lineAlign << " DigitSubstitution: " << digitSubstitution << " DigitLanguage: " << digitLanguage);
SAL_INFO("drawinglayer", "EMF+\t FirstTabOffset: " << firstTabOffset << " HotkeyPrefix: " << hotkeyPrefix << " LeadingMargin: " << leadingMargin << " TrailingMargin: " << trailingMargin << " Tracking: " << tracking);
SAL_INFO("drawinglayer", "EMF+\t Trimming: " << trimming << " TabStopCount: " << tabStopCount << " RangeCount: " << rangeCount);
SAL_WARN_IF(stringAlignment, "drawinglayer", "EMF+\t TODO EMFPStringFormat:StringAlignment");
SAL_WARN_IF(lineAlign, "drawinglayer", "EMF+\t TODO EMFPStringFormat:lineAlign");
SAL_WARN_IF(digitSubstitution, "drawinglayer", "EMF+\t TODO EMFPStringFormat:digitSubstitution");
SAL_WARN_IF(firstTabOffset != 0.0, "drawinglayer", "EMF+\t TODO EMFPStringFormat:firstTabOffset");
SAL_WARN_IF(hotkeyPrefix, "drawinglayer", "EMF+\t TODO EMFPStringFormat:hotkeyPrefix");
SAL_WARN_IF(leadingMargin != 0.0, "drawinglayer", "EMF+\t TODO EMFPStringFormat:leadingMargin");
SAL_WARN_IF(trailingMargin != 0.0, "drawinglayer", "EMF+\t TODO EMFPStringFormat:trailingMargin");
SAL_WARN_IF(tracking != 1.0, "drawinglayer", "EMF+\t TODO EMFPStringFormat:tracking");
SAL_WARN_IF(trimming, "drawinglayer", "EMF+\t TODO EMFPStringFormat:trimming");
SAL_WARN_IF(tabStopCount, "drawinglayer", "EMF+\t TODO EMFPStringFormat:tabStopCount");
SAL_WARN_IF(rangeCount, "drawinglayer", "EMF+\t TODO EMFPStringFormat:StringFormatData");
}
}
......
......@@ -29,14 +29,14 @@ namespace emfplushelper
sal_uInt32 header;
sal_uInt32 stringFormatFlags;
sal_uInt32 language;
sal_uInt32 stringAlignment;
sal_uInt32 lineAlign;
sal_uInt32 stringAlignment; // Horizontal alignment
sal_uInt32 lineAlign; // Vertical alignment
sal_uInt32 digitSubstitution;
sal_uInt32 digitLanguage;
float firstTabOffset;
sal_Int32 hotkeyPrefix;
float leadingMargin;
float trailingMargin;
float leadingMargin; // Length of the space to add to the starting position of a string.
float trailingMargin; // Length of the space to leave following a string.
float tracking;
sal_Int32 trimming;
sal_Int32 tabStopCount;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment