summaryrefslogtreecommitdiff
path: root/cppcanvas
diff options
context:
space:
mode:
authorRadek Doulik <rodo@novell.com>2010-09-15 11:46:38 +0200
committerRadek Doulik <rodo@novell.com>2010-09-15 17:54:14 +0200
commit2191eefb0ccb75925b37a5dd1e9f7fd1cc0d2837 (patch)
treea4caa38f7ece050ee23b30944c6a6c4dded68cc3 /cppcanvas
parentf3b377d331a9666b9e59af7d573d993815b8eabf (diff)
emf+-driver-string.diff: emf+ import - extended string rendering\n\nn#519715
Diffstat (limited to 'cppcanvas')
-rw-r--r--cppcanvas/source/mtfrenderer/emfplus.cxx153
1 files changed, 143 insertions, 10 deletions
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 6a881b53d0d7..07f75c591ba4 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -39,6 +39,8 @@
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <vcl/canvastools.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/alloca.h>
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/rendering/TexturingMode.hpp>
@@ -48,6 +50,7 @@
#include <implrenderer.hxx>
#include <outdevstate.hxx>
#include <polypolyaction.hxx>
+#include <textaction.hxx>
#define EmfPlusRecordTypeHeader 16385
#define EmfPlusRecordTypeEndOfFile 16386
@@ -727,6 +730,39 @@ namespace cppcanvas
}
};
+ struct EMFPFont : public EMFPObject
+ {
+ sal_uInt32 version;
+ float emSize;
+ sal_uInt32 sizeUnit;
+ sal_Int32 fontFlags;
+ rtl::OUString family;
+
+ void Read (SvMemoryStream &s)
+ {
+ sal_uInt32 header;
+ sal_uInt32 reserved;
+ sal_uInt32 length;
+
+ s >> header >> emSize >> sizeUnit >> fontFlags >> reserved >> length;
+
+ OSL_ASSERT( ( header >> 12 ) == 0xdbc01 );
+
+ EMFP_DEBUG (printf ("EMF+\tfont\nEMF+\theader: 0x%08x version: 0x%08x size: %f unit: 0x%08x\n", header >> 12, header & 0x1fff, emSize, sizeUnit));
+ EMFP_DEBUG (printf ("EMF+\tflags: 0x%08x reserved: 0x%08x length: 0x%08x\n", fontFlags, reserved, length));
+
+ if( length > 0 && length < 0x4000 ) {
+ sal_Unicode *chars = (sal_Unicode *) alloca( sizeof( sal_Unicode ) * length );
+
+ for( int i = 0; i < length; i++ )
+ s >> chars[ i ];
+
+ family = ::rtl::OUString( chars, length );
+ EMFP_DEBUG (printf ("EMF+\tfamily: %s\n", rtl::OUStringToOString( family, RTL_TEXTENCODING_UTF8).getStr()));
+ }
+ }
+ };
+
void ImplRenderer::ReadRectangle (SvStream& s, float& x, float& y, float &width, float& height, sal_uInt32 flags)
{
if (flags & 0x4000) {
@@ -823,10 +859,22 @@ namespace cppcanvas
return ::basegfx::B2DRange (x, y, x + w, y + h);
}
+#define COLOR(x) \
+ ::vcl::unotools::colorToDoubleSequence( ::Color (0xff - (x >> 24), \
+ (x >> 16) & 0xff, \
+ (x >> 8) & 0xff, \
+ x & 0xff), \
+ rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace());
+#define SET_FILL_COLOR(x) \
+ rState.fillColor = COLOR(x);
+#define SET_LINE_COLOR(x) \
+ rState.lineColor = COLOR(x);
+#define SET_TEXT_COLOR(x) \
+ rState.textColor = COLOR(x);
+
void ImplRenderer::EMFPPlusFillPolygon (::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,
OutDevState& rState, const CanvasSharedPtr& rCanvas, bool isColor, sal_uInt32 brushIndexOrColor)
{
- sal_uInt8 transparency;
::basegfx::B2DPolyPolygon localPolygon (polygon);
EMFP_DEBUG (printf ("EMF+\tfill polygon\n"));
@@ -838,15 +886,9 @@ namespace cppcanvas
if (isColor) {
EMFP_DEBUG (printf ("EMF+\t\tcolor fill\n"));
- transparency = 0xff - (brushIndexOrColor >> 24);
-
rState.isFillColorSet = true;
rState.isLineColorSet = false;
- rState.fillColor = ::vcl::unotools::colorToDoubleSequence( ::Color (transparency,
- (brushIndexOrColor >> 16) & 0xff,
- (brushIndexOrColor >> 8) & 0xff,
- brushIndexOrColor & 0xff),
- rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace());
+ SET_FILL_COLOR(brushIndexOrColor);
pPolyAction = ActionSharedPtr ( internal::PolyPolyActionFactory::createPolyPolyAction( localPolygon, rParms.mrCanvas, rState ) );
@@ -1080,6 +1122,14 @@ namespace cppcanvas
break;
}
+ case EmfPlusObjectTypeFont:
+ {
+ EMFPFont *font;
+ aObjects [index] = font = new EMFPFont ();
+ font->Read (rObjectStream);
+
+ break;
+ }
default:
EMFP_DEBUG (printf ("EMF+\tObject unhandled flags: 0x%04x\n", flags & 0xff00));
break;
@@ -1438,10 +1488,93 @@ namespace cppcanvas
EMFP_DEBUG (printf ("EMF+\tTODO\n"));
break;
}
- case EmfPlusRecordTypeDrawDriverString:
+ case EmfPlusRecordTypeDrawDriverString: {
EMFP_DEBUG (printf ("EMF+ DrawDriverString, flags: 0x%04x\n", flags));
- EMFP_DEBUG (printf ("EMF+\tTODO\n"));
+ sal_uInt32 brushIndexOrColor;
+ sal_uInt32 optionFlags;
+ sal_uInt32 hasMatrix;
+ sal_uInt32 glyphsCount;
+
+ rMF >> brushIndexOrColor >> optionFlags >> hasMatrix >> glyphsCount;
+
+ EMFP_DEBUG (printf ("EMF+\t%s: 0x%08x\n", (flags & 0x8000) ? "color" : "brush index", brushIndexOrColor));
+ EMFP_DEBUG (printf ("EMF+\toption flags: 0x%08x\n", optionFlags));
+ EMFP_DEBUG (printf ("EMF+\thas matrix: %d\n", hasMatrix));
+ EMFP_DEBUG (printf ("EMF+\tglyphs: %d\n", glyphsCount));
+
+ if( ( optionFlags & 1 ) && glyphsCount > 0 ) {
+ sal_uInt16 *chars = new sal_uInt16[glyphsCount];
+ float *charsPosX = new float[glyphsCount];
+ float *charsPosY = new float[glyphsCount];
+
+ for( int i=0; i<glyphsCount; i++) {
+ rMF >> chars[i];
+ EMFP_DEBUG (printf ("EMF+\tglyph[%d]: 0x%04x\n",
+ i, chars[i]));
+ }
+ for( int i=0; i<glyphsCount; i++) {
+ rMF >> charsPosX[i] >> charsPosY[i];
+ EMFP_DEBUG (printf ("EMF+\tglyphPosition[%d]: %f, %f\n", i, charsPosX[i], charsPosY[i]));
+ }
+
+ XForm transform;
+ if( hasMatrix ) {
+ rMF >> transform;
+ EMFP_DEBUG (printf ("EMF+\tmatrix:: %f, %f, %f, %f, %f, %f\n", transform.eM11, transform.eM12, transform.eM21, transform.eM22, transform.eDx, transform.eDy));
+ }
+
+ // create and add the text action
+ XubString text( chars, glyphsCount );
+
+ EMFPFont *font = (EMFPFont*) aObjects[ flags & 0xff ];
+
+ rendering::FontRequest aFontRequest;
+ aFontRequest.FontDescription.FamilyName = font->family;
+ aFontRequest.CellSize = (rState.mapModeTransform*MapSize( font->emSize, 0 )).getX();
+ rState.xFont = rFactoryParms.mrCanvas->getUNOCanvas()->createFont( aFontRequest,
+ uno::Sequence< beans::PropertyValue >(),
+ geometry::Matrix2D() );
+ if( flags & 0x8000 )
+ SET_TEXT_COLOR(brushIndexOrColor);
+
+ ActionSharedPtr pTextAction(
+ TextActionFactory::createTextAction(
+ ::vcl::unotools::pointFromB2DPoint ( Map( charsPosX[0], charsPosY[0] ) ),
+ ::Size(),
+ ::Color(),
+ ::Size(),
+ ::Color(),
+ text,
+ 0,
+ glyphsCount,
+ NULL,
+ rFactoryParms.mrVDev,
+ rFactoryParms.mrCanvas,
+ rState,
+ rFactoryParms.mrParms,
+ false ) );
+
+ if( pTextAction )
+ {
+ EMFP_DEBUG (printf ("EMF+\t\tadd text action\n"));
+
+ maActions.push_back(
+ MtfAction(
+ pTextAction,
+ rFactoryParms.mrCurrActionIndex ) );
+
+ rFactoryParms.mrCurrActionIndex += pTextAction->getActionCount()-1;
+ }
+
+ delete[] chars;
+ delete[] charsPosX;
+ delete[] charsPosY;
+ } else {
+ EMFP_DEBUG (printf ("EMF+\tTODO: fonts (non-unicode glyphs chars)\n"));
+ }
+
break;
+ }
default:
EMFP_DEBUG (printf ("EMF+ unhandled record type: %d\n", type));
EMFP_DEBUG (printf ("EMF+\tTODO\n"));