summaryrefslogtreecommitdiffstats
path: root/filters/karbon/xaml
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /filters/karbon/xaml
downloadkoffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz
koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'filters/karbon/xaml')
-rw-r--r--filters/karbon/xaml/Makefile.am35
-rw-r--r--filters/karbon/xaml/color.h306
-rw-r--r--filters/karbon/xaml/karbon_xaml_export.desktop54
-rw-r--r--filters/karbon/xaml/karbon_xaml_import.desktop53
-rw-r--r--filters/karbon/xaml/xamlexport.cc371
-rw-r--r--filters/karbon/xaml/xamlexport.h76
-rw-r--r--filters/karbon/xaml/xamlgraphiccontext.h46
-rw-r--r--filters/karbon/xaml/xamlimport.cc1042
-rw-r--r--filters/karbon/xaml/xamlimport.h91
9 files changed, 2074 insertions, 0 deletions
diff --git a/filters/karbon/xaml/Makefile.am b/filters/karbon/xaml/Makefile.am
new file mode 100644
index 00000000..f7036ada
--- /dev/null
+++ b/filters/karbon/xaml/Makefile.am
@@ -0,0 +1,35 @@
+kde_module_LTLIBRARIES = libkarbonxamlexport.la libkarbonxamlimport.la
+
+libkarbonxamlexport_la_LDFLAGS = $(KDE_PLUGIN)
+libkarbonxamlexport_la_LIBADD = \
+ $(LIB_KOFFICEUI) \
+ ../../../karbon/libkarboncommon.la
+
+libkarbonxamlimport_la_LDFLAGS = $(KDE_PLUGIN)
+libkarbonxamlimport_la_LIBADD = \
+ $(LIB_KOFFICEUI) \
+ ../../../karbon/libkarboncommon.la
+
+INCLUDES = \
+ $(KOFFICE_INCLUDES) \
+ $(KOPAINTER_INCLUDES) \
+ -I$(top_srcdir)/karbon \
+ -I$(top_srcdir)/karbon/core \
+ -I$(top_srcdir)/karbon/visitors \
+ $(all_includes)
+
+service_DATA = karbon_xaml_export.desktop karbon_xaml_import.desktop
+servicedir = $(kde_servicesdir)
+
+noinst_HEADERS = \
+ xamlexport.h \
+ xamlimport.h
+
+libkarbonxamlexport_la_SOURCES = \
+ xamlexport.cc
+
+libkarbonxamlimport_la_SOURCES = \
+ xamlimport.cc
+
+METASOURCES = AUTO
+
diff --git a/filters/karbon/xaml/color.h b/filters/karbon/xaml/color.h
new file mode 100644
index 00000000..bfdc93c6
--- /dev/null
+++ b/filters/karbon/xaml/color.h
@@ -0,0 +1,306 @@
+
+#define TORGB( red, green, blue ) \
+{ \
+ r = red; \
+ b = blue; \
+ g = green; \
+}
+
+void keywordToRGB( QString rgbColor, int &r, int &g, int &b )
+{
+ if( rgbColor == "aliceblue" )
+ TORGB( 240, 248, 255)
+ else if( rgbColor == "antiquewhite" )
+ TORGB( 250, 235, 215)
+ else if( rgbColor == "aqua" )
+ TORGB( 0, 255, 255)
+ else if( rgbColor == "aquamarine" )
+ TORGB( 127, 255, 212 )
+ else if( rgbColor == "azure" )
+ TORGB( 240, 255, 255 )
+ else if( rgbColor == "beige" )
+ TORGB( 245, 245, 220 )
+ else if( rgbColor == "bisque" )
+ TORGB( 255, 228, 196 )
+ else if( rgbColor == "black" )
+ TORGB( 0, 0, 0 )
+ else if( rgbColor == "blanchedalmond" )
+ TORGB( 255, 235, 205 )
+ else if( rgbColor == "blue" )
+ TORGB( 0, 0, 255 )
+ else if( rgbColor == "blueviolet" )
+ TORGB( 138, 43, 226 )
+ else if( rgbColor == "brown" )
+ TORGB( 165, 42, 42 )
+ else if( rgbColor == "burlywood" )
+ TORGB( 222, 184, 135 )
+ else if( rgbColor == "cadetblue" )
+ TORGB( 95, 158, 160 )
+ else if( rgbColor == "chartreuse" )
+ TORGB( 127, 255, 0 )
+ else if( rgbColor == "chocolate" )
+ TORGB( 210, 105, 30 )
+ else if( rgbColor == "coral" )
+ TORGB( 255, 127, 80 )
+ else if( rgbColor == "cornflowerblue" )
+ TORGB( 100, 149, 237 )
+ else if( rgbColor == "cornsilk" )
+ TORGB( 255, 248, 220 )
+ else if( rgbColor == "crimson" )
+ TORGB( 220, 20, 60 )
+ else if( rgbColor == "cyan" )
+ TORGB( 0, 255, 255 )
+ else if( rgbColor == "darkblue" )
+ TORGB( 0, 0, 139 )
+ else if( rgbColor == "darkcyan" )
+ TORGB( 0, 139, 139 )
+ else if( rgbColor == "darkgoldenrod" )
+ TORGB( 184, 134, 11 )
+ else if( rgbColor == "darkgray" )
+ TORGB( 169, 169, 169 )
+ else if( rgbColor == "darkgrey" )
+ TORGB( 169, 169, 169 )
+ else if( rgbColor == "darkgreen" )
+ TORGB( 0, 100, 0 )
+ else if( rgbColor == "darkkhaki" )
+ TORGB( 189, 183, 107 )
+ else if( rgbColor == "darkmagenta" )
+ TORGB( 139, 0, 139 )
+ else if( rgbColor == "darkolivegreen" )
+ TORGB( 85, 107, 47 )
+ else if( rgbColor == "darkorange" )
+ TORGB( 255, 140, 0 )
+ else if( rgbColor == "darkorchid" )
+ TORGB( 153, 50, 204 )
+ else if( rgbColor == "darkred" )
+ TORGB( 139, 0, 0 )
+ else if( rgbColor == "darksalmon" )
+ TORGB( 233, 150, 122 )
+ else if( rgbColor == "darkseagreen" )
+ TORGB( 143, 188, 143 )
+ else if( rgbColor == "darkslateblue" )
+ TORGB( 72, 61, 139 )
+ else if( rgbColor == "darkslategray" )
+ TORGB( 47, 79, 79 )
+ else if( rgbColor == "darkslategrey" )
+ TORGB( 47, 79, 79 )
+ else if( rgbColor == "darkturquoise" )
+ TORGB( 0, 206, 209 )
+ else if( rgbColor == "darkviolet" )
+ TORGB( 148, 0, 211 )
+ else if( rgbColor == "deeppink" )
+ TORGB( 255, 20, 147 )
+ else if( rgbColor == "deepskyblue" )
+ TORGB( 0, 191, 255 )
+ else if( rgbColor == "dimgray" )
+ TORGB( 105, 105, 105 )
+ else if( rgbColor == "dimgrey" )
+ TORGB( 105, 105, 105 )
+ else if( rgbColor == "dodgerblue" )
+ TORGB( 30, 144, 255 )
+ else if( rgbColor == "firebrick" )
+ TORGB( 178, 34, 34 )
+ else if( rgbColor == "floralwhite" )
+ TORGB( 255, 250, 240 )
+ else if( rgbColor == "forestgreen" )
+ TORGB( 34, 139, 34 )
+ else if( rgbColor == "fuchsia" )
+ TORGB( 255, 0, 255 )
+ else if( rgbColor == "gainsboro" )
+ TORGB( 220, 220, 220 )
+ else if( rgbColor == "ghostwhite" )
+ TORGB( 248, 248, 255 )
+ else if( rgbColor == "gold" )
+ TORGB( 255, 215, 0 )
+ else if( rgbColor == "goldenrod" )
+ TORGB( 218, 165, 32 )
+ else if( rgbColor == "gray" )
+ TORGB( 128, 128, 128 )
+ else if( rgbColor == "grey" )
+ TORGB( 128, 128, 128 )
+ else if( rgbColor == "green" )
+ TORGB( 0, 128, 0 )
+ else if( rgbColor == "greenyellow" )
+ TORGB( 173, 255, 47 )
+ else if( rgbColor == "honeydew" )
+ TORGB( 240, 255, 240 )
+ else if( rgbColor == "hotpink" )
+ TORGB( 255, 105, 180 )
+ else if( rgbColor == "indianred" )
+ TORGB( 205, 92, 92 )
+ else if( rgbColor == "indigo" )
+ TORGB( 75, 0, 130 )
+ else if( rgbColor == "ivory" )
+ TORGB( 255, 255, 240 )
+ else if( rgbColor == "khaki" )
+ TORGB( 240, 230, 140 )
+ else if( rgbColor == "lavender" )
+ TORGB( 230, 230, 250 )
+ else if( rgbColor == "lavenderblush" )
+ TORGB( 255, 240, 245 )
+ else if( rgbColor == "lawngreen" )
+ TORGB( 124, 252, 0 )
+ else if( rgbColor == "lemonchiffon" )
+ TORGB( 255, 250, 205 )
+ else if( rgbColor == "lightblue" )
+ TORGB( 173, 216, 230 )
+ else if( rgbColor == "lightcoral" )
+ TORGB( 240, 128, 128 )
+ else if( rgbColor == "lightcyan" )
+ TORGB( 224, 255, 255 )
+ else if( rgbColor == "lightgoldenrodyellow" )
+ TORGB( 250, 250, 210 )
+ else if( rgbColor == "lightgray" )
+ TORGB( 211, 211, 211 )
+ else if( rgbColor == "lightgrey" )
+ TORGB( 211, 211, 211 )
+ else if( rgbColor == "lightgreen" )
+ TORGB( 144, 238, 144 )
+ else if( rgbColor == "lightpink" )
+ TORGB( 255, 182, 193 )
+ else if( rgbColor == "lightsalmon" )
+ TORGB( 255, 160, 122 )
+ else if( rgbColor == "lightseagreen" )
+ TORGB( 32, 178, 170 )
+ else if( rgbColor == "lightskyblue" )
+ TORGB( 135, 206, 250 )
+ else if( rgbColor == "lightslategray" )
+ TORGB( 119, 136, 153 )
+ else if( rgbColor == "lightslategrey" )
+ TORGB( 119, 136, 153 )
+ else if( rgbColor == "lightsteelblue" )
+ TORGB( 176, 196, 222 )
+ else if( rgbColor == "lightyellow" )
+ TORGB( 255, 255, 224 )
+ else if( rgbColor == "lime" )
+ TORGB( 0, 255, 0 )
+ else if( rgbColor == "limegreen" )
+ TORGB( 50, 205, 50 )
+ else if( rgbColor == "linen" )
+ TORGB( 250, 240, 230 )
+ else if( rgbColor == "magenta" )
+ TORGB( 255, 0, 255 )
+ else if( rgbColor == "maroon" )
+ TORGB( 128, 0, 0 )
+ else if( rgbColor == "mediumaquamarine" )
+ TORGB( 102, 205, 170 )
+ else if( rgbColor == "mediumblue" )
+ TORGB( 0, 0, 205 )
+ else if( rgbColor == "mediumorchid" )
+ TORGB( 186, 85, 211 )
+ else if( rgbColor == "mediumpurple" )
+ TORGB( 147, 112, 219 )
+ else if( rgbColor == "mediumseagreen" )
+ TORGB( 60, 179, 113 )
+ else if( rgbColor == "mediumslateblue" )
+ TORGB( 123, 104, 238 )
+ else if( rgbColor == "mediumspringgreen" )
+ TORGB( 0, 250, 154 )
+ else if( rgbColor == "mediumturquoise" )
+ TORGB( 72, 209, 204 )
+ else if( rgbColor == "mediumvioletred" )
+ TORGB( 199, 21, 133 )
+ else if( rgbColor == "midnightblue" )
+ TORGB( 25, 25, 112 )
+ else if( rgbColor == "mintcream" )
+ TORGB( 245, 255, 250 )
+ else if( rgbColor == "mistyrose" )
+ TORGB( 255, 228, 225 )
+ else if( rgbColor == "moccasin" )
+ TORGB( 255, 228, 181 )
+ else if( rgbColor == "navajowhite" )
+ TORGB( 255, 222, 173 )
+ else if( rgbColor == "navy" )
+ TORGB( 0, 0, 128 )
+ else if( rgbColor == "oldlace" )
+ TORGB( 253, 245, 230 )
+ else if( rgbColor == "olive" )
+ TORGB( 128, 128, 0 )
+ else if( rgbColor == "olivedrab" )
+ TORGB( 107, 142, 35 )
+ else if( rgbColor == "orange" )
+ TORGB( 255, 165, 0 )
+ else if( rgbColor == "orangered" )
+ TORGB( 255, 69, 0 )
+ else if( rgbColor == "orchid" )
+ TORGB( 218, 112, 214 )
+ else if( rgbColor == "palegoldenrod" )
+ TORGB( 238, 232, 170 )
+ else if( rgbColor == "palegreen" )
+ TORGB( 152, 251, 152 )
+ else if( rgbColor == "paleturquoise" )
+ TORGB( 175, 238, 238 )
+ else if( rgbColor == "palevioletred" )
+ TORGB( 219, 112, 147 )
+ else if( rgbColor == "papayawhip" )
+ TORGB( 255, 239, 213 )
+ else if( rgbColor == "peachpuff" )
+ TORGB( 255, 218, 185 )
+ else if( rgbColor == "peru" )
+ TORGB( 205, 133, 63 )
+ else if( rgbColor == "pink" )
+ TORGB( 255, 192, 203 )
+ else if( rgbColor == "plum" )
+ TORGB( 221, 160, 221 )
+ else if( rgbColor == "powderblue" )
+ TORGB( 176, 224, 230 )
+ else if( rgbColor == "purple" )
+ TORGB( 128, 0, 128 )
+ else if( rgbColor == "red" )
+ TORGB( 255, 0, 0 )
+ else if( rgbColor == "rosybrown" )
+ TORGB( 188, 143, 143 )
+ else if( rgbColor == "royalblue" )
+ TORGB( 65, 105, 225 )
+ else if( rgbColor == "saddlebrown" )
+ TORGB( 139, 69, 19 )
+ else if( rgbColor == "salmon" )
+ TORGB( 250, 128, 114 )
+ else if( rgbColor == "sandybrown" )
+ TORGB( 244, 164, 96 )
+ else if( rgbColor == "seagreen" )
+ TORGB( 46, 139, 87 )
+ else if( rgbColor == "seashell" )
+ TORGB( 255, 245, 238 )
+ else if( rgbColor == "sienna" )
+ TORGB( 160, 82, 45 )
+ else if( rgbColor == "silver" )
+ TORGB( 192, 192, 192 )
+ else if( rgbColor == "skyblue" )
+ TORGB( 135, 206, 235 )
+ else if( rgbColor == "slateblue" )
+ TORGB( 106, 90, 205 )
+ else if( rgbColor == "slategray" )
+ TORGB( 112, 128, 144 )
+ else if( rgbColor == "slategrey" )
+ TORGB( 112, 128, 144 )
+ else if( rgbColor == "snow" )
+ TORGB( 255, 250, 250 )
+ else if( rgbColor == "springgreen" )
+ TORGB( 0, 255, 127 )
+ else if( rgbColor == "steelblue" )
+ TORGB( 70, 130, 180 )
+ else if( rgbColor == "tan" )
+ TORGB( 210, 180, 140 )
+ else if( rgbColor == "teal" )
+ TORGB( 0, 128, 128 )
+ else if( rgbColor == "thistle" )
+ TORGB( 216, 191, 216 )
+ else if( rgbColor == "tomato" )
+ TORGB( 255, 99, 71 )
+ else if( rgbColor == "turquoise" )
+ TORGB( 64, 224, 208 )
+ else if( rgbColor == "violet" )
+ TORGB( 238, 130, 238 )
+ else if( rgbColor == "wheat" )
+ TORGB( 245, 222, 179 )
+ else if( rgbColor == "white" )
+ TORGB( 255, 255, 255 )
+ else if( rgbColor == "whitesmoke" )
+ TORGB( 245, 245, 245 )
+ else if( rgbColor == "yellow" )
+ TORGB( 255, 255, 0 )
+ else if( rgbColor == "yellowgreen" )
+ TORGB( 154, 205, 50 )
+}
+
diff --git a/filters/karbon/xaml/karbon_xaml_export.desktop b/filters/karbon/xaml/karbon_xaml_export.desktop
new file mode 100644
index 00000000..082c29e8
--- /dev/null
+++ b/filters/karbon/xaml/karbon_xaml_export.desktop
@@ -0,0 +1,54 @@
+[Desktop Entry]
+Icon=
+Name=Karbon14 WVG Export Filter
+Name[ar]=مِرْشَح تصدير WVG لدى Karbon14
+Name[bg]=Филтър за експортиране от Karbon14 в WVG
+Name[br]=Sil ezporzh WVG evit Karbon14
+Name[ca]=Filtre d'exportació WVG per a Karbon14
+Name[cy]=Hidlen Allforio WVG Karbon14
+Name[da]=Karbon14 WVG-eksportfilter
+Name[de]=Karbon14 WVG-Exportfilter
+Name[el]=Φίλτρο εξαγωγής SVG του Karbon14
+Name[eo]=Karbon14-WVG-eksportfiltrilo
+Name[es]=Filtro de exportación a WVG de Karbon14
+Name[et]=Karbon14 WVG ekspordifilter
+Name[fa]=پالایۀ صادرات Karbon14 WVG
+Name[fi]=Karbon14 WVG -vientisuodin
+Name[fr]=Filtre d'exportation WVG de Karbon 14
+Name[fy]=WVG-Eksportfilter foar Karbon14
+Name[ga]=Scagaire Easpórtála WVG Karbon14
+Name[gl]=Filtro de Exportación de WVG para Karbon14
+Name[he]=Karbon14 WVG מסנן יצוא
+Name[hr]=Karbon14 WVG filtar izvoza
+Name[hu]=Karbon14 WVG exportszűrő
+Name[is]=Karbon14 WVG útflutningssía
+Name[it]=Filtro di esportazione WVG per Karbon14
+Name[ja]=Karbon14 WVG エクスポートフィルタ
+Name[km]=តម្រង​នាំចេញ WVG សម្រាប់ Karbon14
+Name[lt]=Karbon14 WVG eksportavimo filtras
+Name[lv]=Karbon14 WVG eksporta filtrs
+Name[nb]=WVG-eksportfiler for Karbon14
+Name[nds]=WVG-Exportfilter för Karbon14
+Name[ne]=कार्बन१४ डब्लुभीजी निर्यात फिल्टर
+Name[nl]= WVG-exportfilter voor Karbon14
+Name[pl]=Filtr eksportu do formatu WVG z Karbon14
+Name[pt]=Filtro de Exportação de WVG para o Karbon14
+Name[pt_BR]=Filtro de Exportação de WVG para o Karbon14
+Name[ru]=Фильтр экспорта рисунков Karbon в WVG
+Name[se]=Karbon14:a WVG-olggosfievrridansilli
+Name[sk]=WVG filter pre export z Karbon14
+Name[sl]=Izvozni filter WVG za Karbon14
+Name[sr]=Karbon14-ов филтер за извоз у WVG
+Name[sr@Latn]=Karbon14-ov filter za izvoz u WVG
+Name[sv]=Karbon14 WVG-exportfilter
+Name[uk]=Фільтр експорту WVG для Karbon14
+Name[uz]=Karbon14 WVG eksport filteri
+Name[uz@cyrillic]=Karbon14 WVG экспорт филтери
+Name[zh_CN]=Karbon14 WVG 导出过滤器
+Name[zh_TW]=Karbon14 WVG 匯出過濾程式
+ServiceTypes=KOfficeFilter
+Type=Service
+X-KDE-Export=image/wvg+xml
+X-KDE-Import=application/x-karbon
+X-KDE-Library=libkarbonxamlexport
+X-KDE-Weight=1
diff --git a/filters/karbon/xaml/karbon_xaml_import.desktop b/filters/karbon/xaml/karbon_xaml_import.desktop
new file mode 100644
index 00000000..6acd1f1f
--- /dev/null
+++ b/filters/karbon/xaml/karbon_xaml_import.desktop
@@ -0,0 +1,53 @@
+[Desktop Entry]
+Type=Service
+Name=Karbon XAML Import Filter
+Name[ar]=مِرْشَح استيراد XAML لدى Karbon
+Name[bg]=Филтър за импортиране от XAML в Karbon
+Name[br]=Sil enporzh XAML evit Karbon
+Name[ca]=Filtre d'importació XAML per a Karbon
+Name[cy]=Hidlen Fewnforio XAML Karbon
+Name[da]=Karbon XAML-importfilter
+Name[de]=Karbon14 XAML-Importfilter
+Name[el]=Φίλτρο εισαγωγής XAML του Karbon
+Name[eo]=Karbon-XAML-importfiltrilo
+Name[es]=Filtro de importación a XAML de Karbon
+Name[et]=Karboni XAML-i impordifilter
+Name[fa]=پالایۀ واردات Karbon XAML
+Name[fi]=Karbon XAML -tuontisuodin
+Name[fr]=Filtre d'importation XAML de Karbon 14
+Name[fy]=XAML-tmportfilter foar Karbon
+Name[ga]=Scagaire Iompórtála Karbon XAML
+Name[gl]=Filtro de Importación de XAML para Karbon
+Name[he]=Karbon XAML מסנן יבוא
+Name[hr]=Karbon XAML filtar uvoza
+Name[hu]=Karbon XAML importszűrő
+Name[is]=Karbon XAML innflutningssía
+Name[it]=Filtro di importazione XAML per Karbon
+Name[ja]=Karbon XAML インポートフィルタ
+Name[km]=តម្រង​នាំចូល XAML សម្រាប់ Karbon
+Name[lt]=Karbon XAML importavimo filtras
+Name[lv]=Karbon XAML importa filtrs
+Name[nb]=XAML-importfilter for Karbon
+Name[nds]=XAML-Importfilter för Karbon
+Name[ne]=कार्बन एक्सएएमएल निर्यात फिल्टर
+Name[nl]=XAML-importfilter voor Karbon
+Name[pl]=Filtr importu formatu XAML do Karbon
+Name[pt]=Filtro de Importação de XAML para o Karbon
+Name[pt_BR]=Filtro de Importação de XAML para o Karbon
+Name[ru]=Фильтр импорта файлов XAML в Karbon
+Name[se]=Karbon:a XAML-sisafievrridansilli
+Name[sk]=XAML importný filter pre Karbon
+Name[sl]=Uvozni filter XAML za Karbon
+Name[sr]=Karbon-ов филтер за увоз из XAML-а
+Name[sr@Latn]=Karbon-ov filter za uvoz iz XAML-a
+Name[sv]=Karbon XAML-importfilter
+Name[uk]=Фільтр імпорту XAML для Karbon
+Name[uz]=Karbon XAML import filteri
+Name[uz@cyrillic]=Karbon XAML импорт филтери
+Name[zh_CN]=Karbon XAML 导入过滤器
+Name[zh_TW]=Karbon XAML 匯入過濾程式
+X-KDE-Export=application/x-karbon
+X-KDE-Import=image/wvg+xml
+X-KDE-Weight=1
+X-KDE-Library=libkarbonxamlimport
+ServiceTypes=KOfficeFilter
diff --git a/filters/karbon/xaml/xamlexport.cc b/filters/karbon/xaml/xamlexport.cc
new file mode 100644
index 00000000..c4ccb467
--- /dev/null
+++ b/filters/karbon/xaml/xamlexport.cc
@@ -0,0 +1,371 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, 2003 The Karbon Developers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+// based on the SVG exporter. Not intended for public release
+// Microsoft WVG renamed to XAML Graphics. Worry about that later.
+
+#include <qcstring.h>
+#include <qdom.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+
+#include <kgenericfactory.h>
+#include <KoFilter.h>
+#include <KoFilterChain.h>
+#include <KoStore.h>
+
+#include "xamlexport.h"
+#include "vcolor.h"
+#include "vcomposite.h"
+#include "vdashpattern.h"
+#include "vdocument.h"
+#include "vfill.h"
+#include "vgradient.h"
+#include "vgroup.h"
+#include "vlayer.h"
+#include "vpath.h"
+#include "vsegment.h"
+#include "vselection.h"
+#include "vstroke.h"
+//#include "vtext.h" // TODO Convert Text to Paths for basic export. Not our problem.
+// TODO inline Images?
+
+#include <kdebug.h>
+
+
+typedef KGenericFactory<XAMLExport, KoFilter> XAMLExportFactory;
+K_EXPORT_COMPONENT_FACTORY( libkarbonxamlexport, XAMLExportFactory( "kofficefilters" ) )
+
+
+XAMLExport::XAMLExport( KoFilter*, const char*, const QStringList& )
+ : KoFilter()
+{
+ m_gc.setAutoDelete( true );
+}
+
+KoFilter::ConversionStatus
+XAMLExport::convert( const QCString& from, const QCString& to )
+{
+ // TODO: ???
+ if ( to != "image/wvg+xml" || from != "application/x-karbon" )
+ {
+ return KoFilter::NotImplemented;
+ }
+
+ KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read );
+ if( !storeIn )
+ return KoFilter::StupidError;
+
+ QFile fileOut( m_chain->outputFile() );
+ if( !fileOut.open( IO_WriteOnly ) )
+ {
+ delete storeIn;
+ return KoFilter::StupidError;
+ }
+
+ QDomDocument domIn;
+ domIn.setContent( storeIn );
+ QDomElement docNode = domIn.documentElement();
+
+ m_stream = new QTextStream( &fileOut );
+ QString body;
+ m_body = new QTextStream( &body, IO_ReadWrite );
+ QString defs;
+ m_defs = new QTextStream( &defs, IO_ReadWrite );
+
+
+ // load the document and export it:
+ VDocument doc;
+ doc.load( docNode );
+ doc.accept( *this );
+
+ *m_stream << defs;
+ *m_stream << body;
+
+ fileOut.close();
+
+ delete m_stream;
+ delete m_defs;
+ delete m_body;
+
+ return KoFilter::OK;
+}
+
+void
+XAMLExport::visitVDocument( VDocument& document )
+{
+ // select all objects:
+ document.selection()->append();
+
+ // get the bounding box of the page
+ KoRect rect( 0, 0, document.width(), document.height() );
+
+ // standard header:
+ *m_defs <<
+ "<?xml version=\"1.0\" ?>\n" <<
+ /* "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" " <<* */
+ // "\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">"
+ /*<<*/ endl;
+
+ // Add one line comment to identify Content Creator,
+ // probably remove this later
+ // TODO: schemas
+ // http://schemas.microsoft.com/winfx/avalon/2005
+ // http://schemas.microsoft.com/2003/xaml
+ // need to mention defs too Defenitions namespace xmlns:def="Definition"
+ *m_defs <<
+ "<!-- Generator: Karbon14 WVG XAML Graphics export filter $VERSION/$DATE. -->" << endl;
+ *m_defs <<
+ "<Canvas xmlns=\"http://schemas.microsoft.com/winfx/avalon/2005\" Width=\"" << rect.width() <<
+ "Height=\"" << rect.height() << "\">" << endl;
+ *m_defs << "<Canvas.Resources>" << endl;
+
+ // bleuch: this is horrible, do something about it TODO
+ // Microsoft Acrylic has a transform group just like this
+ *m_body << "<Transform=\"scale(1, -1) Translate(0, -" << rect.height() << ")\">" << endl;
+
+ // we dont need the selection anymore:
+ document.selection()->clear();
+
+ // set up gc
+ XAMLGraphicsContext *gc = new XAMLGraphicsContext;
+ m_gc.push( gc );
+
+ // export layers:
+ VVisitor::visitVDocument( document );
+
+ // end tag:
+ *m_body << "</Canvas>" << endl;
+ *m_defs << "</Canvas.Resources>" << endl;
+ *m_body << "</Canvas>" << endl;
+}
+
+QString
+XAMLExport::getID( VObject *obj )
+{
+ if( obj && !obj->name().isEmpty() )
+ return QString( " Name=\"%1\"" ).arg( obj->name() );
+ return QString();
+}
+
+// which markup to use? Group or Canvas?
+// for now assume Group will work. TODO: Test properly!
+void
+XAMLExport::visitVGroup( VGroup& group )
+{
+ *m_body << "<Canvas" << getID( &group ) << ">" << endl;
+ VVisitor::visitVGroup( group );
+ *m_body << "</Canvas>" << endl;
+}
+
+void
+XAMLExport::visitVPath( VPath& composite )
+{
+ *m_body << "<Path" << getID( &composite );
+
+ VVisitor::visitVPath( composite );
+
+ getFill( *( composite.fill() ) );
+ getStroke( *( composite.stroke() ) );
+
+ QString d;
+ composite.saveSvgPath( d );
+ *m_body << " Data=\"" << d << "\" ";
+
+ if( composite.fillRule() != m_gc.current()->fillRule )
+ {
+ if( composite.fillRule() == evenOdd )
+ *m_body << " FillRule=\"EvenOdd\"";
+ else
+ *m_body << " FillRule=\"NonZero\"";
+ }
+
+ *m_body << " />" << endl;
+}
+
+void
+XAMLExport::visitVSubpath( VSubpath& )
+{
+}
+
+QString createUID()
+{
+ static unsigned int nr = 0;
+
+ return "defitem" + QString().setNum( nr++ );
+}
+
+void
+XAMLExport::getColorStops( const QPtrVector<VColorStop> &colorStops )
+{
+ for( unsigned int i = 0; i < colorStops.count() ; i++ )
+ {
+ *m_defs << "<GradientStop Color=\"";
+ getHexColor( m_defs, colorStops.at( i )->color );
+ *m_defs << "\" Offset=\"" << QString().setNum( colorStops.at( i )->rampPoint );
+ // XAML uses ARGB values and other methods such as masks for Transparency/Opacity # aa rrggbb
+ // *m_defs << "\" stop-opacity=\"" << colorStops.at( i )->color.opacity() << "\"" << " />" << endl;
+ // Maybe this only applies to gradients, need to check.
+ }
+}
+
+void
+XAMLExport::getGradient( const VGradient& grad )
+{
+ QString uid = createUID();
+ if( grad.type() == VGradient::linear )
+ {
+ // do linear grad
+ *m_defs << "<LinearGradientBrush id=\"" << uid << "\" ";
+ *m_defs << "GradientUnits=\"UserSpaceOnUse\" ";
+ *m_defs << "StartPoint=\"" << grad.origin().x() << ",";
+ *m_defs << grad.origin().y() << "\" ";
+ *m_defs << "EndPoint=\"" << grad.vector().x() << ",";
+ *m_defs << grad.vector().y() << "\" ";
+ if( grad.repeatMethod() == VGradient::reflect )
+ *m_defs << "SpreadMethod=\"Reflect\" ";
+ else if( grad.repeatMethod() == VGradient::repeat )
+ *m_defs << "SpreadMethod=\"Repeat\" ";
+ *m_defs << ">" << endl;
+
+ // color stops
+ getColorStops( grad.colorStops() );
+
+ *m_defs << "</LinearGradientBrush>" << endl;
+ *m_body << "url(#" << uid << ")";
+ }
+ else if( grad.type() == VGradient::radial )
+ {
+ // do radial grad
+ *m_defs << "<RadialGradientBrush Name=\"" << uid << "\" ";
+ // *m_defs << "gradientUnits=\"userSpaceOnUse\" "; // Absolute?
+ *m_defs << "Center=\"" << grad.origin().x() << ",";
+ *m_defs << grad.origin().y() << "\" ";
+ // Gradient Origin also known as Focus
+ *m_defs << "GradientOrigin=\"" << grad.focalPoint().x() << ",";
+ *m_defs << grad.focalPoint().y() << "\" ";
+ double r = sqrt( pow( grad.vector().x() - grad.origin().x(), 2 ) + pow( grad.vector().y() - grad.origin().y(), 2 ) );
+ *m_defs << "Radius=\"" << QString().setNum( r ) << "\" ";
+ if( grad.repeatMethod() == VGradient::reflect )
+ *m_defs << "SpreadMethod=\"Reflect\" ";
+ else if( grad.repeatMethod() == VGradient::repeat )
+ *m_defs << "SpreadMethod=\"Repeat\" ";
+ *m_defs << ">" << endl;
+
+ // color stops
+ getColorStops( grad.colorStops() );
+
+ *m_defs << "</RadialGradientBrush>" << endl;
+ *m_body << "url(#" << uid << ")";
+ }
+}
+
+void
+XAMLExport::getFill( const VFill& fill )
+{
+ *m_body << " Fill=\"";
+ if( fill.type() == VFill::none )
+ *m_body << "none";
+ else if( fill.type() == VFill::grad )
+ getGradient( fill.gradient() );
+ else
+ getHexColor( m_body, fill.color() );
+ *m_body << "\"";
+
+ if( fill.color().opacity() != m_gc.current()->fill.color().opacity() )
+ *m_body << " FillOpacity=\"" << fill.color().opacity() << "\"";
+}
+
+void
+XAMLExport::getStroke( const VStroke& stroke )
+{
+ if( stroke.type() != m_gc.current()->stroke.type() )
+ {
+ *m_body << " Stroke=\"";
+ if( stroke.type() == VStroke::none )
+ *m_body << "None";
+ else if( stroke.type() == VStroke::grad )
+ getGradient( stroke.gradient() );
+ else
+ getHexColor( m_body, stroke.color() );
+ *m_body << "\"";
+ }
+
+ if( stroke.color().opacity() != m_gc.current()->stroke.color().opacity() )
+ *m_body << " StrokeOpacity=\"" << stroke.color().opacity() << "\"";
+
+ if( stroke.lineWidth() != m_gc.current()->stroke.lineWidth() )
+ *m_body << " StrokeThickness=\"" << stroke.lineWidth() << "\"";
+
+ if( stroke.lineCap() != m_gc.current()->stroke.lineCap() )
+ {
+ if( stroke.lineCap() == VStroke::capButt )
+ *m_body << " StrokeLineCap=\"Butt\"";
+ else if( stroke.lineCap() == VStroke::capRound )
+ *m_body << " StrokeLineCap=\"round\"";
+ else if( stroke.lineCap() == VStroke::capSquare )
+ *m_body << " StrokeLineCap=\"square\"";
+ }
+
+ if( stroke.lineJoin() != m_gc.current()->stroke.lineJoin() )
+ {
+ if( stroke.lineJoin() == VStroke::joinMiter )
+ {
+ *m_body << " StrokeLineJoin=\"Miter\"";
+ *m_body << " StrokeMiterLimit=\"" << stroke.miterLimit() << "\"";
+ }
+ else if( stroke.lineJoin() == VStroke::joinRound )
+ *m_body << " StrokeLineJoin=\"Round\"";
+ else if( stroke.lineJoin() == VStroke::joinBevel )
+ *m_body << " StrokeLineJoin=\"Bevel\"";
+ }
+
+ // dash
+ if( stroke.dashPattern().array().count() > 0 )
+ {
+ *m_body << " StrokeDashOffset=\"" << stroke.dashPattern().offset() << "\"";
+ *m_body << " StrokeDashArray=\" ";
+
+ QValueListConstIterator<float> itr;
+ for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr )
+ {
+ *m_body << *itr << " ";
+ }
+ *m_body << "\"";
+ }
+}
+
+void
+XAMLExport::getHexColor( QTextStream *stream, const VColor& color )
+{
+ // Convert the various color-spaces to hex
+
+ QString Output;
+
+ VColor copy( color );
+ copy.setColorSpace( VColor::rgb );
+
+ Output.sprintf( "#%02x%02x%02x", int( copy[0] * 255.0 ), int( copy[1] * 255.0 ), int( copy[2] * 255.0 ) );
+
+ *stream << Output;
+}
+
+#include "xamlexport.moc"
+
diff --git a/filters/karbon/xaml/xamlexport.h b/filters/karbon/xaml/xamlexport.h
new file mode 100644
index 00000000..3d2701c6
--- /dev/null
+++ b/filters/karbon/xaml/xamlexport.h
@@ -0,0 +1,76 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, 2003 The Karbon Developers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __XAMLEXPORT_H__
+#define __XAMLEXPORT_H__
+
+#include <KoFilter.h>
+
+#include "vvisitor.h"
+#include "vgradient.h"
+
+#include "xamlgraphiccontext.h"
+
+#include <qptrstack.h>
+
+class QTextStream;
+class VColor;
+class VPath;
+class VDocument;
+class VFill;
+class VGroup;
+class VLayer;
+class VSubpath;
+class VStroke;
+class VText;
+
+
+class XAMLExport : public KoFilter, private VVisitor
+{
+ Q_OBJECT
+
+public:
+ XAMLExport( KoFilter* parent, const char* name, const QStringList& );
+ virtual ~XAMLExport() {}
+
+ virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to );
+
+private:
+ virtual void visitVPath( VPath& composite );
+ virtual void visitVDocument( VDocument& document );
+ virtual void visitVGroup( VGroup& group );
+ virtual void visitVSubpath( VSubpath& path );
+ //virtual void visitVText( VText& text );
+
+ void getStroke( const VStroke& stroke );
+ void getColorStops( const QPtrVector<VColorStop> &colorStops );
+ void getFill( const VFill& fill );
+ void getGradient( const VGradient& grad );
+ void getHexColor( QTextStream *, const VColor& color );
+ QString getID( VObject *obj );
+
+ QTextStream* m_stream;
+ QTextStream* m_defs;
+ QTextStream* m_body;
+
+ QPtrStack<XAMLGraphicsContext> m_gc;
+};
+
+#endif
+
diff --git a/filters/karbon/xaml/xamlgraphiccontext.h b/filters/karbon/xaml/xamlgraphiccontext.h
new file mode 100644
index 00000000..db4a8363
--- /dev/null
+++ b/filters/karbon/xaml/xamlgraphiccontext.h
@@ -0,0 +1,46 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003, The Karbon Developers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __XAMLGRAPHICSCONTEXT_H__
+#define __XAMLGRAPHICSCONTEXT_H__
+
+#include <core/vfill.h>
+#include <core/vstroke.h>
+#include <core/vfillrule.h>
+
+class XAMLGraphicsContext
+{
+public:
+ XAMLGraphicsContext()
+ {
+ stroke.setType( VStroke::none ); // default is no stroke
+ stroke.setLineWidth( 1.0 );
+ stroke.setLineCap( VStroke::capButt );
+ stroke.setLineJoin( VStroke::joinMiter );
+ fill.setColor( VColor( Qt::black ) );
+ fillRule = winding;
+ }
+ VFill fill;
+ VFillRule fillRule;
+ VStroke stroke;
+ QWMatrix matrix;
+ QFont font;
+};
+
+#endif
diff --git a/filters/karbon/xaml/xamlimport.cc b/filters/karbon/xaml/xamlimport.cc
new file mode 100644
index 00000000..297ff68d
--- /dev/null
+++ b/filters/karbon/xaml/xamlimport.cc
@@ -0,0 +1,1042 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, 2003, The Karbon Developers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "xamlimport.h"
+#include "color.h"
+#include <KoFilterChain.h>
+#include <kgenericfactory.h>
+#include <kdebug.h>
+#include <KoUnit.h>
+#include <KoGlobal.h>
+#include <shapes/vellipse.h>
+#include <shapes/vrectangle.h>
+#include <shapes/vpolygon.h>
+#include <commands/vtransformcmd.h>
+#include <core/vsegment.h>
+#include <core/vtext.h>
+#include <core/vglobal.h>
+#include <core/vgroup.h>
+#include <core/vimage.h>
+#include <core/vlayer.h>
+#include <qcolor.h>
+#include <qfile.h>
+#include <kfilterdev.h>
+
+typedef KGenericFactory<XAMLImport, KoFilter> XAMLImportFactory;
+K_EXPORT_COMPONENT_FACTORY( libkarbonxamlimport, XAMLImportFactory( "kofficefilters" ) )
+
+XAMLImport::XAMLImport(KoFilter *, const char *, const QStringList&) :
+ KoFilter(),
+ outdoc( "DOC" )
+{
+ m_gc.setAutoDelete( true );
+}
+
+XAMLImport::~XAMLImport()
+{
+}
+
+KoFilter::ConversionStatus XAMLImport::convert(const QCString& from, const QCString& to)
+{
+ // check for proper conversion
+ if( to != "application/x-karbon" || from != "image/wvg+xml" )
+ return KoFilter::NotImplemented;
+
+ //Find the last extension
+ QString strExt;
+ QString fileIn ( m_chain->inputFile() );
+ const int result=fileIn.findRev('.');
+ if (result>=0)
+ {
+ strExt=fileIn.mid(result).lower();
+ }
+
+ QString strMime; // Mime type of the compressor
+ if ((strExt==".gz") //in case of .svg.gz (logical extension)
+ ||(strExt==".wvgz")) //in case of .svgz (extension used prioritary)
+ strMime="application/x-gzip"; // Compressed with gzip
+ else if (strExt==".bz2") //in case of .svg.bz2 (logical extension)
+ strMime="application/x-bzip2"; // Compressed with bzip2
+ else
+ strMime="text/plain";
+
+ kdDebug(30514) << "File extension: -" << strExt << "- Compression: " << strMime << endl;
+
+ QIODevice* in = KFilterDev::deviceForFile(fileIn,strMime);
+
+ if (!in->open(IO_ReadOnly))
+ {
+ kdError(30514) << "Cannot open file! Aborting!" << endl;
+ delete in;
+ return KoFilter::FileNotFound;
+ }
+
+ int line, col;
+ QString errormessage;
+ const bool parsed=inpdoc.setContent( in, &errormessage, &line, &col );
+ in->close();
+ delete in;
+ if ( ! parsed )
+ {
+ kdError(30514) << "Error while parsing file: "
+ << "at line " << line << " column: " << col
+ << " message: " << errormessage << endl;
+ // ### TODO: feedback to the user
+ return KoFilter::ParsingError;
+ }
+
+ // Do the conversion!
+ convert();
+
+ KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write );
+ if( !out )
+ {
+ kdError(30514) << "Unable to open output file!" << endl;
+ return KoFilter::StorageCreationError;
+ }
+ QCString cstring = outdoc.toCString(); // utf-8 already
+ out->writeBlock( cstring.data(), cstring.length() );
+
+ return KoFilter::OK; // was successful
+}
+
+void
+XAMLImport::convert()
+{
+ XAMLGraphicsContext *gc = new XAMLGraphicsContext;
+ QDomElement docElem = inpdoc.documentElement();
+ KoRect bbox( 0, 0, 550.0, 841.0 );
+ double width = !docElem.attribute( "width" ).isEmpty() ? parseUnit( docElem.attribute( "width" ), true, false, bbox ) : 550.0;
+ double height = !docElem.attribute( "height" ).isEmpty() ? parseUnit( docElem.attribute( "height" ), false, true, bbox ) : 841.0;
+ m_document.setWidth( width );
+ m_document.setHeight( height );
+ m_outerRect = m_document.boundingBox();
+
+ // undo y-mirroring
+ if( !docElem.attribute( "viewBox" ).isEmpty() )
+ {
+ // allow for viewbox def with ',' or whitespace
+ QString viewbox( docElem.attribute( "viewBox" ) );
+ QStringList points = QStringList::split( ' ', viewbox.replace( ',', ' ').simplifyWhiteSpace() );
+
+ gc->matrix.scale( width / points[2].toFloat() , height / points[3].toFloat() );
+ m_outerRect.setWidth( m_outerRect.width() * ( points[2].toFloat() / width ) );
+ m_outerRect.setHeight( m_outerRect.height() * ( points[3].toFloat() / height ) );
+ }
+ m_gc.push( gc );
+ parseGroup( 0L, docElem );
+
+ QWMatrix mat;
+ mat.scale( 1, -1 );
+ mat.translate( 0, -m_document.height() );
+ VTransformCmd trafo( 0L, mat );
+ trafo.visit( m_document );
+ outdoc = m_document.saveXML();
+}
+
+#define DPI 90
+
+double
+XAMLImport::toPercentage( QString s )
+{
+ if( s.endsWith( "%" ) )
+ return s.remove( '%' ).toDouble();
+ else
+ return s.toDouble() * 100.0;
+}
+
+double
+XAMLImport::fromPercentage( QString s )
+{
+ if( s.endsWith( "%" ) )
+ return s.remove( '%' ).toDouble() / 100.0;
+ else
+ return s.toDouble();
+}
+
+// parses the number into parameter number
+const char *
+getNumber( const char *ptr, double &number )
+{
+ int integer, exponent;
+ double decimal, frac;
+ int sign, expsign;
+
+ exponent = 0;
+ integer = 0;
+ frac = 1.0;
+ decimal = 0;
+ sign = 1;
+ expsign = 1;
+
+ // read the sign
+ if(*ptr == '+')
+ ptr++;
+ else if(*ptr == '-')
+ {
+ ptr++;
+ sign = -1;
+ }
+
+ // read the integer part
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ integer = (integer * 10) + *(ptr++) - '0';
+ if(*ptr == '.') // read the decimals
+ {
+ ptr++;
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ decimal += (*(ptr++) - '0') * (frac *= 0.1);
+ }
+
+ if(*ptr == 'e' || *ptr == 'E') // read the exponent part
+ {
+ ptr++;
+
+ // read the sign of the exponent
+ if(*ptr == '+')
+ ptr++;
+ else if(*ptr == '-')
+ {
+ ptr++;
+ expsign = -1;
+ }
+
+ exponent = 0;
+ while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
+ {
+ exponent *= 10;
+ exponent += *ptr - '0';
+ ptr++;
+ }
+ }
+ number = integer + decimal;
+ number *= sign * pow( (double)10, double( expsign * exponent ) );
+
+ return ptr;
+}
+
+
+double
+XAMLImport::parseUnit( const QString &unit, bool horiz, bool vert, KoRect bbox )
+{
+ // TODO : percentage?
+ double value = 0;
+ const char *start = unit.latin1();
+ if(!start) {
+ return 0;
+ }
+ const char *end = getNumber( start, value );
+
+ if( uint( end - start ) < unit.length() )
+ {
+ if( unit.right( 2 ) == "pt" )
+ value = ( value / 72.0 ) * DPI;
+ else if( unit.right( 2 ) == "cm" )
+ value = ( value / 2.54 ) * DPI;
+ else if( unit.right( 2 ) == "pc" )
+ value = ( value / 6.0 ) * DPI;
+ else if( unit.right( 2 ) == "mm" )
+ value = ( value / 25.4 ) * DPI;
+ else if( unit.right( 2 ) == "in" )
+ value = value * DPI;
+ else if( unit.right( 2 ) == "pt" )
+ value = ( value / 72.0 ) * DPI;
+ else if( unit.right( 2 ) == "em" )
+ value = value * m_gc.current()->font.pointSize() / ( sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ) );
+ else if( unit.right( 1 ) == "%" )
+ {
+ if( horiz && vert )
+ value = ( value / 100.0 ) * (sqrt( pow( bbox.width(), 2 ) + pow( bbox.height(), 2 ) ) / sqrt( 2.0 ) );
+ else if( horiz )
+ value = ( value / 100.0 ) * bbox.width();
+ else if( vert )
+ value = ( value / 100.0 ) * bbox.height();
+ }
+ }
+ /*else
+ {
+ if( m_gc.current() )
+ {
+ if( horiz && vert )
+ value *= sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 );
+ else if( horiz )
+ value /= m_gc.current()->matrix.m11();
+ else if( vert )
+ value /= m_gc.current()->matrix.m22();
+ }
+ }*/
+ return value;
+}
+
+QColor
+XAMLImport::parseColor( const QString &rgbColor )
+{
+ int r, g, b;
+ keywordToRGB( rgbColor, r, g, b );
+ return QColor( r, g, b );
+}
+
+void
+XAMLImport::parseColor( VColor &color, const QString &s )
+{
+ if( s.startsWith( "rgb(" ) )
+ {
+ QString parse = s.stripWhiteSpace();
+ QStringList colors = QStringList::split( ',', parse );
+ QString r = colors[0].right( ( colors[0].length() - 4 ) );
+ QString g = colors[1];
+ QString b = colors[2].left( ( colors[2].length() - 1 ) );
+
+ if( r.contains( "%" ) )
+ {
+ r = r.left( r.length() - 1 );
+ r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) );
+ }
+
+ if( g.contains( "%" ) )
+ {
+ g = g.left( g.length() - 1 );
+ g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) );
+ }
+
+ if( b.contains( "%" ) )
+ {
+ b = b.left( b.length() - 1 );
+ b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) );
+ }
+
+ QColor c( r.toInt(), g.toInt(), b.toInt() );
+ color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 );
+ }
+ else
+ {
+ QString rgbColor = s.stripWhiteSpace();
+ QColor c;
+ if( rgbColor.startsWith( "#" ) )
+ c.setNamedColor( rgbColor );
+ else
+ c = parseColor( rgbColor );
+ color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 );
+ }
+}
+
+void
+XAMLImport::parseColorStops( VGradient *gradient, const QDomElement &e )
+{
+ VColor c;
+ for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ QDomElement stop = n.toElement();
+ if( stop.tagName() == "stop" )
+ {
+ float offset;
+ QString temp = stop.attribute( "offset" );
+ if( temp.contains( '%' ) )
+ {
+ temp = temp.left( temp.length() - 1 );
+ offset = temp.toFloat() / 100.0;
+ }
+ else
+ offset = temp.toFloat();
+
+ if( !stop.attribute( "stop-color" ).isEmpty() )
+ parseColor( c, stop.attribute( "stop-color" ) );
+ else
+ {
+ // try style attr
+ QString style = stop.attribute( "style" ).simplifyWhiteSpace();
+ QStringList substyles = QStringList::split( ';', style );
+ for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it )
+ {
+ QStringList substyle = QStringList::split( ':', (*it) );
+ QString command = substyle[0].stripWhiteSpace();
+ QString params = substyle[1].stripWhiteSpace();
+ if( command == "stop-color" )
+ parseColor( c, params );
+ if( command == "stop-opacity" )
+ c.setOpacity( params.toDouble() );
+ }
+
+ }
+ if( !stop.attribute( "stop-opacity" ).isEmpty() )
+ c.setOpacity( stop.attribute( "stop-opacity" ).toDouble() );
+ gradient->addStop( c, offset, 0.5 );
+ }
+ }
+}
+
+void
+XAMLImport::parseGradient( const QDomElement &e )
+{
+ GradientHelper gradhelper;
+ gradhelper.gradient.clearStops();
+ gradhelper.gradient.setRepeatMethod( VGradient::none );
+
+ QString href = e.attribute( "xlink:href" ).mid( 1 );
+ if( !href.isEmpty() )
+ {
+ //kdDebug() << "Indexing with href : " << href.latin1() << endl;
+ gradhelper.gradient = m_gradients[ href ].gradient;
+ }
+
+ gradhelper.bbox = e.attribute( "gradientUnits" ) != "userSpaceOnUse";
+
+ if( e.tagName() == "linearGradient" )
+ {
+ if( gradhelper.bbox )
+ {
+ gradhelper.gradient.setOrigin( KoPoint( toPercentage( e.attribute( "x1", "0%" ) ), toPercentage( e.attribute( "y1", "0%" ) ) ) );
+ gradhelper.gradient.setVector( KoPoint( toPercentage( e.attribute( "x2", "100%" ) ), toPercentage( e.attribute( "y2", "0%" ) ) ) );
+ }
+ else
+ {
+ gradhelper.gradient.setOrigin( KoPoint( e.attribute( "x1" ).toDouble(), e.attribute( "y1" ).toDouble() ) );
+ gradhelper.gradient.setVector( KoPoint( e.attribute( "x2" ).toDouble(), e.attribute( "y2" ).toDouble() ) );
+ }
+ }
+ else
+ {
+ if( gradhelper.bbox )
+ {
+ gradhelper.gradient.setOrigin( KoPoint( toPercentage( e.attribute( "cx", "50%" ) ), toPercentage( e.attribute( "cy", "50%" ) ) ) );
+ gradhelper.gradient.setVector( KoPoint( toPercentage( e.attribute( "cx", "50%" ) ) + toPercentage( e.attribute( "r", "50%" ) ),
+ toPercentage( e.attribute( "cy", "50%" ) ) ) );
+ gradhelper.gradient.setFocalPoint( KoPoint( toPercentage( e.attribute( "fx", "50%" ) ), toPercentage( e.attribute( "fy", "50%" ) ) ) );
+ }
+ else
+ {
+ gradhelper.gradient.setOrigin( KoPoint( e.attribute( "cx" ).toDouble(), e.attribute( "cy" ).toDouble() ) );
+ gradhelper.gradient.setFocalPoint( KoPoint( e.attribute( "fx" ).toDouble(), e.attribute( "fy" ).toDouble() ) );
+ gradhelper.gradient.setVector( KoPoint( e.attribute( "cx" ).toDouble() + e.attribute( "r" ).toDouble(), e.attribute( "cy" ).toDouble() ) );
+ }
+ gradhelper.gradient.setType( VGradient::radial );
+ }
+ // handle spread method
+ QString spreadMethod = e.attribute( "spreadMethod" );
+ if( !spreadMethod.isEmpty() )
+ {
+ if( spreadMethod == "reflect" )
+ gradhelper.gradient.setRepeatMethod( VGradient::reflect );
+ else if( spreadMethod == "repeat" )
+ gradhelper.gradient.setRepeatMethod( VGradient::repeat );
+ }
+ parseColorStops( &gradhelper.gradient, e );
+ //gradient.setGradientTransform( parseTransform( e.attribute( "gradientTransform" ) ) );
+ gradhelper.gradientTransform = VPath::parseTransform( e.attribute( "gradientTransform" ) );
+ m_gradients.insert( e.attribute( "id" ), gradhelper );
+}
+
+void
+XAMLImport::parsePA( VObject *obj, XAMLGraphicsContext *gc, const QString &command, const QString &params )
+{
+ VColor fillcolor = gc->fill.color();
+ VColor strokecolor = gc->stroke.color();
+
+ if( command == "fill" )
+ {
+ if( params == "none" )
+ gc->fill.setType( VFill::none );
+ else if( params.startsWith( "url(" ) )
+ {
+ unsigned int start = params.find("#") + 1;
+ unsigned int end = params.findRev(")");
+ QString key = params.mid( start, end - start );
+ gc->fill.gradient() = m_gradients[ key ].gradient;
+ if( m_gradients[ key ].bbox )
+ {
+ // adjust to bbox
+ KoRect bbox = obj->boundingBox();
+ //kdDebug() << "bbox x : " << bbox.x() << endl;
+ //kdDebug() << "!!!!!!bbox y : " << bbox.y() << endl;
+ //kdDebug() << gc->fill.gradient().origin().x() << endl;
+ //kdDebug() << gc->fill.gradient().vector().x() << endl;
+ double offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox );
+ double offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().y() ), false, true, bbox );
+ gc->fill.gradient().setOrigin( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) );
+ offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox );
+ offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox );
+ gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) );
+ offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox );
+ offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().y() ), false, true, bbox );
+ gc->fill.gradient().setVector( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) );
+ //kdDebug() << offsety << endl;
+ //kdDebug() << gc->fill.gradient().origin().x() << endl;
+ //kdDebug() << gc->fill.gradient().origin().y() << endl;
+ //kdDebug() << gc->fill.gradient().vector().x() << endl;
+ //kdDebug() << gc->fill.gradient().vector().y() << endl;
+ }
+ gc->fill.gradient().transform( m_gradients[ key ].gradientTransform );
+ if( !m_gradients[ key ].bbox )
+ gc->fill.gradient().transform( gc->matrix );
+ gc->fill.setType( VFill::grad );
+ }
+ else
+ {
+ parseColor( fillcolor, params );
+ gc->fill.setType( VFill::solid );
+ }
+ }
+ else if( command == "fill-rule" )
+ {
+ if( params == "nonzero" )
+ gc->fillRule = winding;
+ else if( params == "evenodd" )
+ gc->fillRule = evenOdd;
+ }
+ else if( command == "stroke" )
+ {
+ if( params == "none" )
+ gc->stroke.setType( VStroke::none );
+ else if( params.startsWith( "url(" ) )
+ {
+ unsigned int start = params.find("#") + 1;
+ unsigned int end = params.findRev(")");
+ QString key = params.mid( start, end - start );
+ gc->stroke.gradient() = m_gradients[ key ].gradient;
+ gc->stroke.gradient().transform( m_gradients[ key ].gradientTransform );
+ gc->stroke.gradient().transform( gc->matrix );
+ gc->stroke.setType( VStroke::grad );
+ }
+ else
+ {
+ parseColor( strokecolor, params );
+ gc->stroke.setType( VStroke::solid );
+ }
+ }
+ else if( command == "stroke-width" )
+ gc->stroke.setLineWidth( parseUnit( params, true, true, m_outerRect ) );
+ else if( command == "stroke-linejoin" )
+ {
+ if( params == "miter" )
+ gc->stroke.setLineJoin( VStroke::joinMiter );
+ else if( params == "round" )
+ gc->stroke.setLineJoin( VStroke::joinRound );
+ else if( params == "bevel" )
+ gc->stroke.setLineJoin( VStroke::joinBevel );
+ }
+ else if( command == "stroke-linecap" )
+ {
+ if( params == "butt" )
+ gc->stroke.setLineCap( VStroke::capButt );
+ else if( params == "round" )
+ gc->stroke.setLineCap( VStroke::capRound );
+ else if( params == "square" )
+ gc->stroke.setLineCap( VStroke::capSquare );
+ }
+ else if( command == "stroke-miterlimit" )
+ gc->stroke.setMiterLimit( params.toFloat() );
+ else if( command == "stroke-dasharray" )
+ {
+ QValueList<float> array;
+ if(params != "none")
+ {
+ QStringList dashes = QStringList::split( ' ', params );
+ for( QStringList::Iterator it = dashes.begin(); it != dashes.end(); ++it )
+ array.append( (*it).toFloat() );
+ }
+ gc->stroke.dashPattern().setArray( array );
+ }
+ else if( command == "stroke-dashoffset" )
+ gc->stroke.dashPattern().setOffset( params.toFloat() );
+ // handle opacity
+ else if( command == "stroke-opacity" )
+ strokecolor.setOpacity( fromPercentage( params ) );
+ else if( command == "fill-opacity" )
+ fillcolor.setOpacity( fromPercentage( params ) );
+ else if( command == "opacity" )
+ {
+ fillcolor.setOpacity( fromPercentage( params ) );
+ strokecolor.setOpacity( fromPercentage( params ) );
+ }
+ else if( command == "font-family" )
+ {
+ QString family = params;
+ family.replace( '\'' , ' ' );
+ gc->font.setFamily( family );
+ }
+ else if( command == "font-size" )
+ {
+ float pointSize = parseUnit( params );
+ pointSize *= gc->matrix.m22() > 0 ? gc->matrix.m22() : -1.0 * gc->matrix.m22();
+ gc->font.setPointSizeFloat( pointSize );
+ }
+ else if( command == "text-decoration" )
+ {
+ if( params == "line-through" )
+ gc->font.setStrikeOut( true );
+ else if( params == "underline" )
+ gc->font.setUnderline( true );
+ }
+ if( gc->fill.type() != VFill::none )
+ gc->fill.setColor( fillcolor, false );
+ //if( gc->stroke.type() == VStroke::solid )
+ gc->stroke.setColor( strokecolor );
+}
+
+void
+XAMLImport::addGraphicContext()
+{
+ XAMLGraphicsContext *gc = new XAMLGraphicsContext;
+ // set as default
+ if( m_gc.current() )
+ *gc = *( m_gc.current() );
+ m_gc.push( gc );
+}
+
+void
+XAMLImport::setupTransform( const QDomElement &e )
+{
+ XAMLGraphicsContext *gc = m_gc.current();
+
+ QWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) );
+ gc->matrix = mat * gc->matrix;
+}
+
+void
+XAMLImport::parseStyle( VObject *obj, const QDomElement &e )
+{
+ XAMLGraphicsContext *gc = m_gc.current();
+ if( !gc ) return;
+
+ // try normal PA
+ if( !e.attribute( "fill" ).isEmpty() )
+ parsePA( obj, gc, "fill", e.attribute( "fill" ) );
+ if( !e.attribute( "fill-rule" ).isEmpty() )
+ parsePA( obj, gc, "fill-rule", e.attribute( "fill-rule" ) );
+ if( !e.attribute( "stroke" ).isEmpty() )
+ parsePA( obj, gc, "stroke", e.attribute( "stroke" ) );
+ if( !e.attribute( "stroke-width" ).isEmpty() )
+ parsePA( obj, gc, "stroke-width", e.attribute( "stroke-width" ) );
+ if( !e.attribute( "stroke-linejoin" ).isEmpty() )
+ parsePA( obj, gc, "stroke-linejoin", e.attribute( "stroke-linejoin" ) );
+ if( !e.attribute( "stroke-linecap" ).isEmpty() )
+ parsePA( obj, gc, "stroke-linecap", e.attribute( "stroke-linecap" ) );
+ if( !e.attribute( "stroke-dasharray" ).isEmpty() )
+ parsePA( obj, gc, "stroke-dasharray", e.attribute( "stroke-dasharray" ) );
+ if( !e.attribute( "stroke-dashoffset" ).isEmpty() )
+ parsePA( obj, gc, "stroke-dashoffset", e.attribute( "stroke-dashoffset" ) );
+ if( !e.attribute( "stroke-opacity" ).isEmpty() )
+ parsePA( obj, gc, "stroke-opacity", e.attribute( "stroke-opacity" ) );
+ if( !e.attribute( "stroke-miterlimit" ).isEmpty() )
+ parsePA( obj, gc, "stroke-miterlimit", e.attribute( "stroke-miterlimit" ) );
+ if( !e.attribute( "fill-opacity" ).isEmpty() )
+ parsePA( obj, gc, "fill-opacity", e.attribute( "fill-opacity" ) );
+ if( !e.attribute( "opacity" ).isEmpty() )
+ parsePA( obj, gc, "opacity", e.attribute( "opacity" ) );
+
+ // try style attr
+ QString style = e.attribute( "style" ).simplifyWhiteSpace();
+ QStringList substyles = QStringList::split( ';', style );
+ for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it )
+ {
+ QStringList substyle = QStringList::split( ':', (*it) );
+ QString command = substyle[0].stripWhiteSpace();
+ QString params = substyle[1].stripWhiteSpace();
+ parsePA( obj, gc, command, params );
+ }
+
+ obj->setFill( gc->fill );
+ if( dynamic_cast<VPath *>( obj ) )
+ dynamic_cast<VPath *>( obj )->setFillRule( gc->fillRule );
+ // stroke scaling
+ double lineWidth = gc->stroke.lineWidth();
+ gc->stroke.setLineWidth( lineWidth * sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ) );
+ obj->setStroke( gc->stroke );
+ gc->stroke.setLineWidth( lineWidth );
+}
+
+void
+XAMLImport::parseFont( const QDomElement &e )
+{
+ XAMLGraphicsContext *gc = m_gc.current();
+ if( !gc ) return;
+
+ if( ! e.attribute( "font-family" ).isEmpty() )
+ parsePA( 0L, m_gc.current(), "font-family", e.attribute( "font-family" ) );
+ if( ! e.attribute( "font-size" ).isEmpty() )
+ parsePA( 0L, m_gc.current(), "font-size", e.attribute( "font-size" ) );
+ if( ! e.attribute( "text-decoration" ).isEmpty() )
+ parsePA( 0L, m_gc.current(), "text-decoration", e.attribute( "text-decoration" ) );
+}
+
+void
+XAMLImport::parseGroup( VGroup *grp, const QDomElement &e )
+{
+ bool isDef = false;
+ if( e.tagName() == "defs" )
+ isDef = true;
+
+ for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ QDomElement b = n.toElement();
+ if( b.isNull() ) continue;
+ VObject *obj = 0L;
+ if( b.tagName() == "g" )
+ {
+ VGroup *group;
+ if ( grp )
+ group = new VGroup( grp );
+ else
+ group = new VGroup( &m_document );
+
+ addGraphicContext();
+ setupTransform( b );
+ parseStyle( group, b );
+ parseFont( b );
+ parseGroup( group, b );
+
+ // handle id
+ if( !b.attribute("id").isEmpty() )
+ group->setName( b.attribute("id") );
+ if( grp )
+ grp->append( group );
+ else
+ m_document.append( group );
+ delete( m_gc.pop() );
+ continue;
+ }
+ if( b.tagName() == "defs" )
+ {
+ parseGroup( 0L, b ); // try for gradients at least
+ continue;
+ }
+ else if( b.tagName() == "linearGradient" || b.tagName() == "radialGradient" )
+ {
+ parseGradient( b );
+ continue;
+ }
+ else if( b.tagName() == "rect" ||
+ b.tagName() == "ellipse" ||
+ b.tagName() == "circle" ||
+ b.tagName() == "line" ||
+ b.tagName() == "polyline" ||
+ b.tagName() == "polygon" ||
+ b.tagName() == "path" ||
+ b.tagName() == "image" )
+ {
+ if (!isDef)
+ obj = createObject( b );
+ else
+ m_paths.insert( b.attribute( "id" ), b );
+ }
+ else if( b.tagName() == "text" )
+ {
+ if( isDef )
+ m_paths.insert( b.attribute( "id" ), b );
+ else
+ createText( grp, b );
+ }
+ else if( b.tagName() == "use" )
+ {
+ double tx = b.attribute( "x" ).toDouble();
+ double ty = b.attribute( "y" ).toDouble();
+
+ if( !b.attribute( "xlink:href" ).isEmpty() )
+ {
+ QString params = b.attribute( "xlink:href" );
+ unsigned int start = params.find("#") + 1;
+ unsigned int end = params.findRev(")");
+ QString key = params.mid( start, end - start );
+ if(m_paths.contains(key))
+ {
+ QDomElement a = m_paths[key];
+ obj = createObject( a );
+ m_gc.current()->matrix.translate(tx,ty);
+ parsePA( grp, m_gc.current(), "fill", b.attribute( "fill" ) );
+ }
+ }
+ }
+ if( !obj ) continue;
+ VTransformCmd trafo( 0L, m_gc.current()->matrix );
+ trafo.visit( *obj );
+ parseStyle( obj, b );
+ // handle id
+ if( !b.attribute("id").isEmpty() )
+ obj->setName( b.attribute("id") );
+ if( grp )
+ grp->append( obj );
+ else
+ m_document.append( obj );
+ delete( m_gc.pop() );
+ }
+}
+
+VObject* XAMLImport::findObject( const QString &name, VGroup* group )
+{
+ if( ! group )
+ return 0L;
+
+ VObjectListIterator itr = group->objects();
+
+ for( uint objcount = 1; itr.current(); ++itr, objcount++ )
+ if( itr.current()->state() != VObject::deleted )
+ {
+ if( itr.current()->name() == name )
+ return itr.current();
+
+ if( dynamic_cast<VGroup *>( itr.current() ) )
+ {
+ VObject *obj = findObject( name, dynamic_cast<VGroup *>( itr.current() ) );
+ if( obj )
+ return obj;
+ }
+ }
+
+ return 0L;
+}
+
+VObject* XAMLImport::findObject( const QString &name )
+{
+ QPtrVector<VLayer> vector;
+ m_document.layers().toVector( &vector );
+ for( int i = vector.count() - 1; i >= 0; i-- )
+ {
+ if ( vector[i]->state() != VObject::deleted )
+ {
+ VObject* obj = findObject( name, dynamic_cast<VGroup *>( vector[i] ) );
+ if( obj )
+ return obj;
+ }
+ }
+
+ return 0L;
+}
+
+void XAMLImport::createText( VGroup *grp, const QDomElement &b )
+{
+ VText *text = 0L;
+ QString content;
+ VSubpath base( 0L );
+ VPath *path = 0L;
+
+ addGraphicContext();
+ setupTransform( b );
+ VTransformCmd trafo( 0L, m_gc.current()->matrix );
+
+ parseFont( b );
+
+ if( b.hasChildNodes() )
+ {
+ if( base.isEmpty() && ! b.attribute( "x" ).isEmpty() && ! b.attribute( "y" ).isEmpty() )
+ {
+ double x = parseUnit( b.attribute( "x" ) );
+ double y = parseUnit( b.attribute( "y" ) );
+ base.moveTo( KoPoint( x, y ) );
+ base.lineTo( KoPoint( x + 10, y ) );
+ }
+
+ for( QDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ QDomElement e = n.toElement();
+ if( e.isNull() )
+ {
+ content += n.toCharacterData().data();
+ }
+ else if( e.tagName() == "textPath" )
+ {
+ if( e.attribute( "xlink:href" ).isEmpty() )
+ continue;
+
+ QString uri = e.attribute( "xlink:href" );
+ unsigned int start = uri.find("#") + 1;
+ unsigned int end = uri.findRev(")");
+ QString key = uri.mid( start, end - start );
+ if( ! m_paths.contains(key) )
+ {
+ VObject* obj = findObject( key );
+ if( obj )
+ path = dynamic_cast<VPath*>( obj );
+ }
+ else
+ {
+ QDomElement p = m_paths[key];
+ path = dynamic_cast<VPath*>( createObject( p ) );
+ if( path )
+ path->setState( VObject::deleted );
+ }
+ if( ! path )
+ continue;
+ base = *path->paths().getFirst();
+ content += e.text();
+ }
+ else if( e.tagName() == "tspan" )
+ {
+ // only use text of tspan element, as we are not supporting text
+ // with different styles
+ content += e.text();
+ if( base.isEmpty() && ! e.attribute( "x" ).isEmpty() && ! e.attribute( "y" ).isEmpty() )
+ {
+ QStringList posX = QStringList::split( ", ", e.attribute( "x" ) );
+ QStringList posY = QStringList::split( ", ", e.attribute( "y" ) );
+ if( posX.count() && posY.count() )
+ {
+ double x = parseUnit( posX.first() );
+ double y = parseUnit( posY.first() );
+ base.moveTo( KoPoint( x, y ) );
+ base.lineTo( KoPoint( x + 10, y ) );
+ }
+ }
+ }
+ else if( e.tagName() == "tref" )
+ {
+ if( e.attribute( "xlink:href" ).isEmpty() )
+ continue;
+
+ QString uri = e.attribute( "xlink:href" );
+ unsigned int start = uri.find("#") + 1;
+ unsigned int end = uri.findRev(")");
+ QString key = uri.mid( start, end - start );
+
+ if( ! m_paths.contains(key) )
+ {
+ VObject* obj = findObject( key );
+ if( obj )
+ content += dynamic_cast<VText*>( obj )->text();
+ }
+ else
+ {
+ QDomElement p = m_paths[key];
+ content += p.text();
+ }
+ }
+ else
+ continue;
+ }
+ text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, content.simplifyWhiteSpace() );
+ }
+ else
+ {
+ VSubpath base( 0L );
+ double x = parseUnit( b.attribute( "x" ) );
+ double y = parseUnit( b.attribute( "y" ) );
+ base.moveTo( KoPoint( x, y ) );
+ base.lineTo( KoPoint( x + 10, y ) );
+ text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, b.text().simplifyWhiteSpace() );
+ }
+
+ if( text )
+ {
+ text->setParent( &m_document );
+
+ parseStyle( text, b );
+ trafo.visit( *text );
+
+ if( !b.attribute("id").isEmpty() )
+ text->setName( b.attribute("id") );
+
+ if( grp )
+ grp->append( text );
+ else
+ m_document.append( text );
+ }
+ delete( m_gc.pop() );
+}
+
+VObject* XAMLImport::createObject( const QDomElement &b )
+{
+ if( b.tagName() == "rect" )
+ {
+ addGraphicContext();
+ double x = parseUnit( b.attribute( "x" ), true, false, m_outerRect );
+ double y = parseUnit( b.attribute( "y" ), false, true, m_outerRect );
+ double width = parseUnit( b.attribute( "width" ), true, false, m_outerRect );
+ double height = parseUnit( b.attribute( "height" ), false, true, m_outerRect );
+ setupTransform( b );
+ return new VRectangle( 0L, KoPoint( x, height + y ) , width, height );
+ }
+ else if( b.tagName() == "ellipse" )
+ {
+ addGraphicContext();
+ setupTransform( b );
+ double rx = parseUnit( b.attribute( "rx" ) );
+ double ry = parseUnit( b.attribute( "ry" ) );
+ double left = parseUnit( b.attribute( "cx" ) ) - rx;
+ double top = parseUnit( b.attribute( "cy" ) ) - ry;
+ return new VEllipse( 0L, KoPoint( left, top ), rx * 2.0, ry * 2.0 );
+ }
+ else if( b.tagName() == "circle" )
+ {
+ addGraphicContext();
+ setupTransform( b );
+ double r = parseUnit( b.attribute( "r" ) );
+ double left = parseUnit( b.attribute( "cx" ) ) - r;
+ double top = parseUnit( b.attribute( "cy" ) ) - r;
+ return new VEllipse( 0L, KoPoint( left, top ), r * 2.0, r * 2.0 );
+ }
+ else if( b.tagName() == "line" )
+ {
+ addGraphicContext();
+ setupTransform( b );
+ VPath *path = new VPath( &m_document );
+ double x1 = b.attribute( "x1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x1" ) );
+ double y1 = b.attribute( "y1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y1" ) );
+ double x2 = b.attribute( "x2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x2" ) );
+ double y2 = b.attribute( "y2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y2" ) );
+ path->moveTo( KoPoint( x1, y1 ) );
+ path->lineTo( KoPoint( x2, y2 ) );
+ return path;
+ }
+ else if( b.tagName() == "polyline" || b.tagName() == "polygon" )
+ {
+ addGraphicContext();
+ setupTransform( b );
+ VPath *path = new VPath( &m_document );
+ bool bFirst = true;
+
+ QString points = b.attribute( "points" ).simplifyWhiteSpace();
+ points.replace( ',', ' ' );
+ points.remove( '\r' );
+ points.remove( '\n' );
+ QStringList pointList = QStringList::split( ' ', points );
+ for( QStringList::Iterator it = pointList.begin(); it != pointList.end(); ++it)
+ {
+ KoPoint point;
+ point.setX( (*it).toDouble() );
+ point.setY( (*it).toDouble() );
+ if( bFirst )
+ {
+ path->moveTo( point );
+ bFirst = false;
+ }
+ else
+ path->lineTo( point );
+ }
+ if( b.tagName() == "polygon" ) path->close();
+ return path;
+ }
+ else if( b.tagName() == "path" )
+ {
+ addGraphicContext();
+ setupTransform( b );
+ VPath *path = new VPath( &m_document );
+ path->loadSvgPath( b.attribute( "d" ) );
+ return path;
+ }
+ else if( b.tagName() == "image" )
+ {
+ addGraphicContext();
+ setupTransform( b );
+ QString fname = b.attribute("xlink:href");
+ return new VImage( 0L, fname );
+ }
+
+ return 0L;
+}
+
+#include <xamlimport.moc>
diff --git a/filters/karbon/xaml/xamlimport.h b/filters/karbon/xaml/xamlimport.h
new file mode 100644
index 00000000..05763419
--- /dev/null
+++ b/filters/karbon/xaml/xamlimport.h
@@ -0,0 +1,91 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, The Karbon Developers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __XAMLIMPORT_H__
+#define __XAMLIMPORT_H__
+
+#include <KoFilter.h>
+#include <qdom.h>
+#include <qmap.h>
+#include <qptrstack.h>
+#include <core/vdocument.h>
+#include <core/vgradient.h>
+#include <core/vfill.h>
+#include <core/vstroke.h>
+#include <core/vfillrule.h>
+#include "xamlgraphiccontext.h"
+
+class VGroup;
+class VPath;
+
+class XAMLImport : public KoFilter
+{
+ Q_OBJECT
+
+public:
+ XAMLImport(KoFilter *parent, const char *name, const QStringList&);
+ virtual ~XAMLImport();
+
+ virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to);
+
+protected:
+ class GradientHelper
+ {
+ public:
+ GradientHelper()
+ {
+ bbox = true;
+ }
+ VGradient gradient;
+ bool bbox;
+ QWMatrix gradientTransform;
+ };
+
+ void parseGroup( VGroup *, const QDomElement & );
+ void parseStyle( VObject *, const QDomElement & );
+ void parsePA( VObject *, XAMLGraphicsContext *, const QString &, const QString & );
+ void parseGradient( const QDomElement & );
+ void parseColorStops( VGradient *, const QDomElement & );
+ double parseUnit( const QString &, bool horiz = false, bool vert = false, KoRect bbox = KoRect() );
+ void parseColor( VColor &, const QString & );
+ QColor parseColor( const QString & );
+ double toPercentage( QString );
+ double fromPercentage( QString );
+ void setupTransform( const QDomElement & );
+ void addGraphicContext();
+ QDomDocument inpdoc;
+ QDomDocument outdoc;
+ void convert();
+ VObject* createObject( const QDomElement & );
+ void createText( VGroup *, const QDomElement & );
+ void parseFont( const QDomElement & );
+ // find object with given id in document
+ VObject* findObject( const QString &name );
+ // find object with given id in given group
+ VObject* findObject( const QString &name, VGroup * );
+
+private:
+ VDocument m_document;
+ QPtrStack<XAMLGraphicsContext> m_gc;
+ QMap<QString, GradientHelper> m_gradients;
+ QMap<QString, QDomElement> m_paths;
+ KoRect m_outerRect;
+};
+
+#endif