From 5a9e731d00de64dd906ffd4ebf77f7fc7f811f99 Mon Sep 17 00:00:00 2001 From: Patrick Jaap Date: Tue, 1 Aug 2017 14:21:29 +0200 Subject: new EMF+ Parser: Basic Text Primitives for EmfPlusRecordTypeDrawString Implementation of basic text primitives. It supports text, textstyle (bold, italic, font, font size, direction, color, locale. The positions are well-transformed. Also a few adjustments and supplements for EMFplus font and stringformat Change-Id: I2670b5d0f6b9ddcaa9ffc8262d8aee13ba224b77 Reviewed-on: https://gerrit.libreoffice.org/40635 Tested-by: Jenkins Reviewed-by: Armin Le Grand --- drawinglayer/source/tools/emfpfont.hxx | 5 +++ drawinglayer/source/tools/emfphelperdata.cxx | 62 ++++++++++++++++++++++++++ drawinglayer/source/tools/emfpstringformat.cxx | 3 ++ drawinglayer/source/tools/emfpstringformat.hxx | 12 +++++ 4 files changed, 82 insertions(+) (limited to 'drawinglayer/source') diff --git a/drawinglayer/source/tools/emfpfont.hxx b/drawinglayer/source/tools/emfpfont.hxx index 6c9f73fd4455..22263faf728a 100644 --- a/drawinglayer/source/tools/emfpfont.hxx +++ b/drawinglayer/source/tools/emfpfont.hxx @@ -32,6 +32,11 @@ namespace emfplushelper OUString family; void Read(SvMemoryStream &s); + + bool Bold() { return fontFlags & 0x1; } + bool Italic() { return fontFlags & 0x2; } + bool Underline(){ return fontFlags & 0x4; } + bool Strikaout(){ return fontFlags & 0x8; } }; } diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx index d7919234842f..d5249b1c5d39 100644 --- a/drawinglayer/source/tools/emfphelperdata.cxx +++ b/drawinglayer/source/tools/emfphelperdata.cxx @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -882,9 +884,69 @@ namespace emfplushelper if (flags & 0x8000) { + // read the layout rectangle float lx, ly, lw, lh; rMS.ReadFloat(lx).ReadFloat(ly).ReadFloat(lw).ReadFloat(lh); SAL_INFO("cppcanvas.emf", "EMF+ DrawString layoutRect: " << lx << "," << ly << " - " << lw << "x" << lh); + // parse the string + OUString text = read_uInt16s_ToOUString(rMS, stringLength); + SAL_INFO("cppcanvas.emf", "EMF+ DrawString string: " << text); + // get the stringFormat from the Object table + EMFPStringFormat *stringFormat = static_cast< EMFPStringFormat* >(maEMFPObjects[formatId & 0xff].get()); + // get the font from the flags + EMFPFont *font = static_cast< EMFPFont* >( maEMFPObjects[flags & 0xff].get() ); + if (!stringFormat || !font) + { + break; + } + // done reading + + // transform to TextSimplePortionPrimitive2D + + const OUString emptyString; + drawinglayer::attribute::FontAttribute fontAttribute( + font->family, // font family + emptyString, // (no) font style + font->Bold() ? 8u : 1u, // weight: 8 = bold + font->family.compareTo("SYMBOL") == 0, // symbol + stringFormat->DirectionVertical(), // vertical + font->Italic(), // italic + false, // monospaced + false, // outline = false, no such thing in MS-EMFPLUS + stringFormat->DirectionRightToLeft(), // right-to-left + false); // BiDiStrong + + LanguageTag aLanguageTag(static_cast< LanguageType >(stringFormat->language)); + css::lang::Locale locale = aLanguageTag.getLocale(); + + basegfx::B2DHomMatrix transformMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(MapSize(font->emSize,font->emSize),Map(lx,ly+font->emSize)); + + basegfx::BColor color; + if (flags & 0x8000) // we use a color + { + color = Color(0xff - (brushId >> 24), (brushId >> 16) & 0xff, (brushId >> 8) & 0xff, brushId & 0xff).getBColor(); + } + else // we use a pen + { + const EMFPPen* pen = static_cast(maEMFPObjects[brushId & 0xff].get()); + if (pen) + { + color = pen->GetColor().getBColor(); + } + } + + std::vector emptyVector; + mrTargetHolders.Current().append( + new drawinglayer::primitive2d::TextSimplePortionPrimitive2D( + transformMatrix, + text, + 0, // text always starts at 0 + stringLength, + emptyVector, // EMF-PLUS has no DX-array + fontAttribute, + locale, + color)); + // OUString text = read_uInt16s_ToOUString(rMS, stringLength); // EMFPStringFormat *stringFormat = static_cast< EMFPStringFormat* >(maEMFPObjects[formatId & 0xff].get()); // css::rendering::FontRequest aFontRequest; diff --git a/drawinglayer/source/tools/emfpstringformat.cxx b/drawinglayer/source/tools/emfpstringformat.cxx index 2256e8035726..3415365cbe0e 100644 --- a/drawinglayer/source/tools/emfpstringformat.cxx +++ b/drawinglayer/source/tools/emfpstringformat.cxx @@ -48,6 +48,9 @@ namespace emfplushelper s.ReadUInt32(stringAlignment).ReadUInt32(lineAlign).ReadUInt32(digitSubstitution).ReadUInt32(digitLanguage); s.ReadFloat(firstTabOffset).ReadInt32(hotkeyPrefix).ReadFloat(leadingMargin).ReadFloat(trailingMargin).ReadFloat(tracking); s.ReadInt32(trimming).ReadInt32(tabStopCount).ReadInt32(rangeCount); + // keep olny the last 16 Bits of language + language >>= 16; + digitLanguage >>= 16; SAL_WARN_IF((header >> 12) != 0xdbc01, "cppcanvas.emf", "Invalid header - not 0xdbc01"); SAL_INFO("cppcanvas.emf", "EMF+\t string format\nEMF+\theader: 0x" << std::hex << (header >> 12) << " version: 0x" << (header & 0x1fff) << " StringFormatFlags: " << std::dec << stringFormatFlags << " Language: " << language); SAL_INFO("cppcanvas.emf", "EMF+\t StringAlignment: " << stringAlignment << " LineAlign: " << lineAlign << " DigitSubstitution: " << digitSubstitution << " DigitLanguage: " << digitLanguage); diff --git a/drawinglayer/source/tools/emfpstringformat.hxx b/drawinglayer/source/tools/emfpstringformat.hxx index 58510850e880..39bc004dd01f 100644 --- a/drawinglayer/source/tools/emfpstringformat.hxx +++ b/drawinglayer/source/tools/emfpstringformat.hxx @@ -44,6 +44,18 @@ namespace emfplushelper EMFPStringFormat(); void Read(SvMemoryStream &s); + + // flags table from MS-EMFPLUS doc + bool DirectionRightToLeft() { return stringFormatFlags & 0x00000001;} + bool DirectionVertical() { return stringFormatFlags & 0x00000002;} + bool NoFitBlackBox() { return stringFormatFlags & 0x00000004;} + bool DisplayFormatControl() { return stringFormatFlags & 0x00000020;} + bool NoFontFallback() { return stringFormatFlags & 0x00000400;} + bool MeasureTrailingSpaces(){ return stringFormatFlags & 0x00000800;} + bool NoWrap() { return stringFormatFlags & 0x00001000;} + bool LineLimit() { return stringFormatFlags & 0x00002000;} + bool NoClip() { return stringFormatFlags & 0x00004000;} + bool BypassGDI() { return stringFormatFlags & 0x80000000;} }; } -- cgit