diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /filters/karbon/xaml | |
download | koffice-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.am | 35 | ||||
-rw-r--r-- | filters/karbon/xaml/color.h | 306 | ||||
-rw-r--r-- | filters/karbon/xaml/karbon_xaml_export.desktop | 54 | ||||
-rw-r--r-- | filters/karbon/xaml/karbon_xaml_import.desktop | 53 | ||||
-rw-r--r-- | filters/karbon/xaml/xamlexport.cc | 371 | ||||
-rw-r--r-- | filters/karbon/xaml/xamlexport.h | 76 | ||||
-rw-r--r-- | filters/karbon/xaml/xamlgraphiccontext.h | 46 | ||||
-rw-r--r-- | filters/karbon/xaml/xamlimport.cc | 1042 | ||||
-rw-r--r-- | filters/karbon/xaml/xamlimport.h | 91 |
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 ¶ms ) +{ + 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 |