Code

emf import : recalculate text alignment for rotated text (Bug 341847)
[inkscape.git] / src / extension / internal / emf-win32-inout.cpp
index 9d25f3a7f17bba28443e4e6b7bd78b8eff7f8cc5..c817f6d4686cee5af2a6308c9749bc9f24a4fcef 100644 (file)
@@ -3,6 +3,8 @@
  */
 /* Authors:
  *   Ulf Erikson <ulferikson@users.sf.net>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2006-2008 Authors
  *
@@ -78,6 +80,7 @@ namespace Inkscape {
 namespace Extension {
 namespace Internal {
 
+static float device_scale = DEVICESCALE;
 
 EmfWin32::EmfWin32 (void) // The null constructor
 {
@@ -109,7 +112,7 @@ emf_print_document_to_file(SPDocument *doc, gchar const *filename)
     gchar *oldoutput;
     unsigned int ret;
 
-    sp_document_ensure_up_to_date(doc);
+    doc->ensureUpToDate();
 
     mod = Inkscape::Extension::get_print(PRINT_EMF_WIN32);
     oldconst = mod->get_param_string("destination");
@@ -120,20 +123,20 @@ emf_print_document_to_file(SPDocument *doc, gchar const *filename)
     context.module = mod;
     /* fixme: This has to go into module constructor somehow */
     /* Create new arena */
-    mod->base = SP_ITEM(sp_document_root(doc));
+    mod->base = SP_ITEM(doc->getRoot());
     mod->arena = NRArena::create();
-    mod->dkey = sp_item_display_key_new(1);
-    mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
+    mod->dkey = SPItem::display_key_new(1);
+    mod->root = mod->base->invoke_show(mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
     /* Print document */
     ret = mod->begin(doc);
     if (ret) {
         g_free(oldoutput);
         throw Inkscape::Extension::Output::save_failed();
     }
-    sp_item_invoke_print(mod->base, &context);
+    mod->base->invoke_print(&context);
     ret = mod->finish();
     /* Release arena */
-    sp_item_invoke_hide(mod->base, mod->dkey);
+    mod->base->invoke_hide(mod->dkey);
     mod->base = NULL;
     mod->root = NULL;
     nr_object_unref((NRObject *) mod->arena);
@@ -338,7 +341,7 @@ pix_to_x_point(PEMF_CALLBACK_DATA d, double px, double py)
     double ppy = _pix_y_to_point(d, py);
 
     double x = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21 + d->dc[d->level].worldTransform.eDx;
-    x *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : DEVICESCALE;
+    x *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : device_scale;
     
     return x;
 }
@@ -350,7 +353,7 @@ pix_to_y_point(PEMF_CALLBACK_DATA d, double px, double py)
     double ppy = _pix_y_to_point(d, py);
 
     double y = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22 + d->dc[d->level].worldTransform.eDy;
-    y *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : DEVICESCALE;
+    y *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : device_scale;
     
     return y;
 }
@@ -362,9 +365,9 @@ pix_to_size_point(PEMF_CALLBACK_DATA d, double px)
     double ppy = 0;
 
     double dx = ppx * d->dc[d->level].worldTransform.eM11 + ppy * d->dc[d->level].worldTransform.eM21;
-    dx *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : DEVICESCALE;
+    dx *= d->dc[d->level].ScaleOutX ? d->dc[d->level].ScaleOutX : device_scale;
     double dy = ppx * d->dc[d->level].worldTransform.eM12 + ppy * d->dc[d->level].worldTransform.eM22;
-    dy *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : DEVICESCALE;
+    dy *= d->dc[d->level].ScaleOutY ? d->dc[d->level].ScaleOutY : device_scale;
 
     double tmp = sqrt(dx * dx + dy * dy);
     return tmp;
@@ -733,7 +736,7 @@ assert_empty_path(PEMF_CALLBACK_DATA d, const char * /*fun*/)
 
 
 static int CALLBACK
-myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD *lpEMFR, int /*nObj*/, LPARAM lpData)
+myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD const *lpEMFR, int /*nObj*/, LPARAM lpData)
 {
     PEMF_CALLBACK_DATA d;
     SVGOStringStream tmp_outsvg;
@@ -783,14 +786,18 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD *lpEMFR
             d->xDPI = 2540;
             d->yDPI = 2540;
 
-            d->dc[d->level].PixelsInX = pEmr->rclFrame.right - pEmr->rclFrame.left;
-            d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom - pEmr->rclFrame.top;
+            d->dc[d->level].PixelsInX = pEmr->rclFrame.right;  // - pEmr->rclFrame.left;
+            d->dc[d->level].PixelsInY = pEmr->rclFrame.bottom; // - pEmr->rclFrame.top;
 
             d->MMX = d->dc[d->level].PixelsInX / 100.0;
             d->MMY = d->dc[d->level].PixelsInY / 100.0;
 
             d->dc[d->level].PixelsOutX = d->MMX * PX_PER_MM;
             d->dc[d->level].PixelsOutY = d->MMY * PX_PER_MM;
+
+            // calculate ratio of Inkscape dpi/device dpi
+            if (pEmr->szlMillimeters.cx && pEmr->szlDevice.cx)
+                device_scale = PX_PER_MM*pEmr->szlMillimeters.cx/pEmr->szlDevice.cx;
             
             tmp_outsvg <<
                 "  width=\"" << d->MMX << "mm\"\n" <<
@@ -1069,8 +1076,8 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD *lpEMFR
                 d->dc[d->level].ScaleOutY = (double) d->dc[d->level].PixelsOutY / (double) d->dc[d->level].sizeView.cy;
             }
             else {
-                d->dc[d->level].ScaleOutX = DEVICESCALE;
-                d->dc[d->level].ScaleOutY = DEVICESCALE;
+                d->dc[d->level].ScaleOutX = device_scale;
+                d->dc[d->level].ScaleOutY = device_scale;
             }
 
             break;
@@ -1120,8 +1127,8 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD *lpEMFR
                 d->dc[d->level].ScaleOutY = (double) d->dc[d->level].PixelsOutY / (double) d->dc[d->level].sizeView.cy;
             }
             else {
-                d->dc[d->level].ScaleOutX = DEVICESCALE;
-                d->dc[d->level].ScaleOutY = DEVICESCALE;
+                d->dc[d->level].ScaleOutX = device_scale;
+                d->dc[d->level].ScaleOutY = device_scale;
             }
 
             break;
@@ -1770,8 +1777,13 @@ myEnhMetaFileProc(HDC /*hDC*/, HANDLETABLE * /*lpHTable*/, ENHMETARECORD *lpEMFR
             }
 
             if (!(d->dc[d->level].textAlign & TA_BOTTOM))
-                y1 += fabs(d->dc[d->level].style.font_size.computed);
-            
+                if (d->dc[d->level].style.text_transform.value) {
+                    x1 += std::sin(d->dc[d->level].style.text_transform.value*M_PI/180.0)*fabs(d->dc[d->level].style.font_size.computed);
+                    y1 += std::cos(d->dc[d->level].style.text_transform.value*M_PI/180.0)*fabs(d->dc[d->level].style.font_size.computed);
+                }
+                else
+                    y1 += fabs(d->dc[d->level].style.font_size.computed);
+
             double x = pix_to_x_point(d, x1, y1);
             double y = pix_to_y_point(d, x1, y1);
 
@@ -2353,7 +2365,8 @@ EmfWin32::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri )
                 d.pDesc[lstrlen(d.pDesc)] = '#';
         }
 
-        EnumEnhMetaFile(NULL, hemf, myEnhMetaFileProc, (LPVOID) &d, NULL);
+        // This ugly reinterpret_cast is to prevent old versions of gcc from whining about a mismatch in the const-ness of the arguments
+        EnumEnhMetaFile(NULL, hemf, reinterpret_cast<ENHMFENUMPROC>(myEnhMetaFileProc), (LPVOID) &d, NULL);
         DeleteEnhMetaFile(hemf);
     }
     else {
@@ -2366,7 +2379,7 @@ EmfWin32::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri )
 
 //    std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl;
 
-    SPDocument *doc = sp_document_new_from_mem(d.outsvg->c_str(), d.outsvg->length(), TRUE);
+    SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg->c_str(), d.outsvg->length(), TRUE);
 
     delete d.outsvg;
     delete d.path;
@@ -2453,4 +2466,4 @@ EmfWin32::init (void)
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :