1*c667dd47SPedro Giffuni#!/usr/bin/env perl -w 27e90fac2SAndrew Rist#************************************************************** 37e90fac2SAndrew Rist# 47e90fac2SAndrew Rist# Licensed to the Apache Software Foundation (ASF) under one 57e90fac2SAndrew Rist# or more contributor license agreements. See the NOTICE file 67e90fac2SAndrew Rist# distributed with this work for additional information 77e90fac2SAndrew Rist# regarding copyright ownership. The ASF licenses this file 87e90fac2SAndrew Rist# to you under the Apache License, Version 2.0 (the 97e90fac2SAndrew Rist# "License"); you may not use this file except in compliance 107e90fac2SAndrew Rist# with the License. You may obtain a copy of the License at 117e90fac2SAndrew Rist# 127e90fac2SAndrew Rist# http://www.apache.org/licenses/LICENSE-2.0 137e90fac2SAndrew Rist# 147e90fac2SAndrew Rist# Unless required by applicable law or agreed to in writing, 157e90fac2SAndrew Rist# software distributed under the License is distributed on an 167e90fac2SAndrew Rist# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 177e90fac2SAndrew Rist# KIND, either express or implied. See the License for the 187e90fac2SAndrew Rist# specific language governing permissions and limitations 197e90fac2SAndrew Rist# under the License. 207e90fac2SAndrew Rist# 217e90fac2SAndrew Rist#************************************************************** 227e90fac2SAndrew Rist 237e90fac2SAndrew Rist 24cdf0e10cSrcweir 25cdf0e10cSrcweiruse warnings; 26cdf0e10cSrcweir 27cdf0e10cSrcweirsub usage() { 28cdf0e10cSrcweir print STDERR <<EOF; 29cdf0e10cSrcweirUsage: preset-definitions-to-shape-types.pl <shapes> <text> 30cdf0e10cSrcweir 31cdf0e10cSrcweirConverts presetShapeDefinitions.xml and presetTextWarpDefinitions.xml to a 32cdf0e10cSrcweir.cxx that contains VML with the definitions of the shapes. The result is 33cdf0e10cSrcweirwritten to stdout. 34cdf0e10cSrcweir 35cdf0e10cSrcweir<shapes> presetShapeDefinitions.xml (including the path to it) 36cdf0e10cSrcweir<text> presetTextWarpDefinitions.xml (including the path to it) 37cdf0e10cSrcweirEOF 38cdf0e10cSrcweir exit 1; 39cdf0e10cSrcweir} 40cdf0e10cSrcweir 41cdf0e10cSrcweirsub show_call_stack 42cdf0e10cSrcweir{ 43cdf0e10cSrcweir my ( $path, $line, $subr ); 44cdf0e10cSrcweir my $max_depth = 30; 45cdf0e10cSrcweir my $i = 1; 46cdf0e10cSrcweir print STDERR "--- Begin stack trace ---\n"; 47cdf0e10cSrcweir while ( (my @call_details = (caller($i++))) && ($i<$max_depth) ) { 48cdf0e10cSrcweir print STDERR "$call_details[1] line $call_details[2] in function $call_details[3]\n"; 49cdf0e10cSrcweir } 50cdf0e10cSrcweir print STDERR "--- End stack trace ---\n"; 51cdf0e10cSrcweir} 52cdf0e10cSrcweir 53cdf0e10cSrcweir$src_shapes = shift; 54cdf0e10cSrcweir$src_text = shift; 55cdf0e10cSrcweir 56cdf0e10cSrcweirusage() if ( !defined( $src_shapes ) || !defined( $src_text ) || 57cdf0e10cSrcweir $src_shapes eq "-h" || $src_shapes eq "--help" || 58cdf0e10cSrcweir !-f $src_shapes || !-f $src_text ); 59cdf0e10cSrcweir 60cdf0e10cSrcweir# Global variables 61cdf0e10cSrcweir@levels = (); 62cdf0e10cSrcweir$shape_name = ""; 63cdf0e10cSrcweir$state = ""; 64cdf0e10cSrcweir$path = ""; 65cdf0e10cSrcweir$adjust = ""; 66cdf0e10cSrcweir$max_adj_no = 0; 67cdf0e10cSrcweir@formulas = (); 68cdf0e10cSrcweir%variables = (); 69cdf0e10cSrcweir$ignore_this_shape = 0; 70cdf0e10cSrcweir$handles = ""; 71cdf0e10cSrcweir$textboxrect = ""; 72cdf0e10cSrcweir$last_pos_x = ""; 73cdf0e10cSrcweir$last_pos_y = ""; 74cdf0e10cSrcweir$no_stroke = 0; 75cdf0e10cSrcweir$no_fill = 0; 76cdf0e10cSrcweir$path_w = 1; 77cdf0e10cSrcweir$path_h = 1; 78cdf0e10cSrcweir@quadratic_bezier = (); 79cdf0e10cSrcweir 80cdf0e10cSrcweir%result_shapes = (); 81cdf0e10cSrcweir 82cdf0e10cSrcweir%shapes_ids = ( 83cdf0e10cSrcweir 0 => 'notPrimitive', 84cdf0e10cSrcweir 1 => 'rectangle', 85cdf0e10cSrcweir 2 => 'roundRectangle', 86cdf0e10cSrcweir 3 => 'ellipse', 87cdf0e10cSrcweir 4 => 'diamond', 88cdf0e10cSrcweir 5 => 'triangle', 89cdf0e10cSrcweir 6 => 'rtTriangle', 90cdf0e10cSrcweir 7 => 'parallelogram', 91cdf0e10cSrcweir 8 => 'trapezoid', 92cdf0e10cSrcweir 9 => 'hexagon', 93cdf0e10cSrcweir 10 => 'octagon', 94cdf0e10cSrcweir 11 => 'plus', 95cdf0e10cSrcweir 12 => 'star5', 96cdf0e10cSrcweir 13 => 'rightArrow', 97cdf0e10cSrcweir 14 => 'thickArrow', # should not be used 98cdf0e10cSrcweir 15 => 'homePlate', 99cdf0e10cSrcweir 16 => 'cube', 100cdf0e10cSrcweir 17 => 'wedgeRoundRectCallout', # balloon 101cdf0e10cSrcweir 18 => 'star16', # seal 102cdf0e10cSrcweir 19 => 'arc', 103cdf0e10cSrcweir 20 => 'line', 104cdf0e10cSrcweir 21 => 'plaque', 105cdf0e10cSrcweir 22 => 'can', 106cdf0e10cSrcweir 23 => 'donut', 107cdf0e10cSrcweir 24 => 'textPlain', # textSimple - FIXME MS Office 2007 converts these to textboxes with unstyled text, so is it actually correct to map it to a real style? 108cdf0e10cSrcweir 25 => 'textStop', # textOctagon FIXME see 24 109cdf0e10cSrcweir 26 => 'textTriangle', # textHexagon FIXMME see 24 110cdf0e10cSrcweir 27 => 'textCanDown', # textCurve FIXMME see 24 111cdf0e10cSrcweir 28 => 'textWave1', # textWave FIXMME see 24 112cdf0e10cSrcweir 29 => 'textArchUpPour', # textRing FIXMME see 24 113cdf0e10cSrcweir 30 => 'textCanDown', # textOnCurve FIXMME see 24 114cdf0e10cSrcweir 31 => 'textArchUp', # textOnRing FIXMME see 24 115cdf0e10cSrcweir 32 => 'straightConnector1', 116cdf0e10cSrcweir 33 => 'bentConnector2', 117cdf0e10cSrcweir 34 => 'bentConnector3', 118cdf0e10cSrcweir 35 => 'bentConnector4', 119cdf0e10cSrcweir 36 => 'bentConnector5', 120cdf0e10cSrcweir 37 => 'curvedConnector2', 121cdf0e10cSrcweir 38 => 'curvedConnector3', 122cdf0e10cSrcweir 39 => 'curvedConnector4', 123cdf0e10cSrcweir 40 => 'curvedConnector5', 124cdf0e10cSrcweir 41 => 'callout1', 125cdf0e10cSrcweir 42 => 'callout2', 126cdf0e10cSrcweir 43 => 'callout3', 127cdf0e10cSrcweir 44 => 'accentCallout1', 128cdf0e10cSrcweir 45 => 'accentCallout2', 129cdf0e10cSrcweir 46 => 'accentCallout3', 130cdf0e10cSrcweir 47 => 'borderCallout1', 131cdf0e10cSrcweir 48 => 'borderCallout2', 132cdf0e10cSrcweir 49 => 'borderCallout3', 133cdf0e10cSrcweir 50 => 'accentBorderCallout1', 134cdf0e10cSrcweir 51 => 'accentBorderCallout2', 135cdf0e10cSrcweir 52 => 'accentBorderCallout3', 136cdf0e10cSrcweir 53 => 'ribbon', 137cdf0e10cSrcweir 54 => 'ribbon2', 138cdf0e10cSrcweir 55 => 'chevron', 139cdf0e10cSrcweir 56 => 'pentagon', 140cdf0e10cSrcweir 57 => 'noSmoking', 141cdf0e10cSrcweir 58 => 'star8', # seal8 142cdf0e10cSrcweir 59 => 'star16', # seal16 143cdf0e10cSrcweir 60 => 'star32', # seal32 144cdf0e10cSrcweir 61 => 'wedgeRectCallout', 145cdf0e10cSrcweir 62 => 'wedgeRoundRectCallout', # wedgeRRectCallout 146cdf0e10cSrcweir 63 => 'wedgeEllipseCallout', 147cdf0e10cSrcweir 64 => 'wave', 148cdf0e10cSrcweir 65 => 'foldedCorner', 149cdf0e10cSrcweir 66 => 'leftArrow', 150cdf0e10cSrcweir 67 => 'downArrow', 151cdf0e10cSrcweir 68 => 'upArrow', 152cdf0e10cSrcweir 69 => 'leftRightArrow', 153cdf0e10cSrcweir 70 => 'upDownArrow', 154cdf0e10cSrcweir 71 => 'irregularSeal1', 155cdf0e10cSrcweir 72 => 'irregularSeal2', 156cdf0e10cSrcweir 73 => 'lightningBolt', 157cdf0e10cSrcweir 74 => 'heart', 158cdf0e10cSrcweir 75 => 'frame', # pictureFrame 159cdf0e10cSrcweir 76 => 'quadArrow', 160cdf0e10cSrcweir 77 => 'leftArrowCallout', 161cdf0e10cSrcweir 78 => 'rightArrowCallout', 162cdf0e10cSrcweir 79 => 'upArrowCallout', 163cdf0e10cSrcweir 80 => 'downArrowCallout', 164cdf0e10cSrcweir 81 => 'leftRightArrowCallout', 165cdf0e10cSrcweir 82 => 'upDownArrowCallout', 166cdf0e10cSrcweir 83 => 'quadArrowCallout', 167cdf0e10cSrcweir 84 => 'bevel', 168cdf0e10cSrcweir 85 => 'leftBracket', 169cdf0e10cSrcweir 86 => 'rightBracket', 170cdf0e10cSrcweir 87 => 'leftBrace', 171cdf0e10cSrcweir 88 => 'rightBrace', 172cdf0e10cSrcweir 89 => 'leftUpArrow', 173cdf0e10cSrcweir 90 => 'bentUpArrow', 174cdf0e10cSrcweir 91 => 'bentArrow', 175cdf0e10cSrcweir 92 => 'star24', # seal24 176cdf0e10cSrcweir 93 => 'stripedRightArrow', 177cdf0e10cSrcweir 94 => 'notchedRightArrow', 178cdf0e10cSrcweir 95 => 'blockArc', 179cdf0e10cSrcweir 96 => 'smileyFace', 180cdf0e10cSrcweir 97 => 'verticalScroll', 181cdf0e10cSrcweir 98 => 'horizontalScroll', 182cdf0e10cSrcweir 99 => 'circularArrow', 183cdf0e10cSrcweir 100 => 'notchedCircularArrow', # should not be used 184cdf0e10cSrcweir 101 => 'uturnArrow', 185cdf0e10cSrcweir 102 => 'curvedRightArrow', 186cdf0e10cSrcweir 103 => 'curvedLeftArrow', 187cdf0e10cSrcweir 104 => 'curvedUpArrow', 188cdf0e10cSrcweir 105 => 'curvedDownArrow', 189cdf0e10cSrcweir 106 => 'cloudCallout', 190cdf0e10cSrcweir 107 => 'ellipseRibbon', 191cdf0e10cSrcweir 108 => 'ellipseRibbon2', 192cdf0e10cSrcweir 109 => 'flowChartProcess', 193cdf0e10cSrcweir 110 => 'flowChartDecision', 194cdf0e10cSrcweir 111 => 'flowChartInputOutput', 195cdf0e10cSrcweir 112 => 'flowChartPredefinedProcess', 196cdf0e10cSrcweir 113 => 'flowChartInternalStorage', 197cdf0e10cSrcweir 114 => 'flowChartDocument', 198cdf0e10cSrcweir 115 => 'flowChartMultidocument', 199cdf0e10cSrcweir 116 => 'flowChartTerminator', 200cdf0e10cSrcweir 117 => 'flowChartPreparation', 201cdf0e10cSrcweir 118 => 'flowChartManualInput', 202cdf0e10cSrcweir 119 => 'flowChartManualOperation', 203cdf0e10cSrcweir 120 => 'flowChartConnector', 204cdf0e10cSrcweir 121 => 'flowChartPunchedCard', 205cdf0e10cSrcweir 122 => 'flowChartPunchedTape', 206cdf0e10cSrcweir 123 => 'flowChartSummingJunction', 207cdf0e10cSrcweir 124 => 'flowChartOr', 208cdf0e10cSrcweir 125 => 'flowChartCollate', 209cdf0e10cSrcweir 126 => 'flowChartSort', 210cdf0e10cSrcweir 127 => 'flowChartExtract', 211cdf0e10cSrcweir 128 => 'flowChartMerge', 212cdf0e10cSrcweir 129 => 'flowChartOfflineStorage', 213cdf0e10cSrcweir 130 => 'flowChartOnlineStorage', 214cdf0e10cSrcweir 131 => 'flowChartMagneticTape', 215cdf0e10cSrcweir 132 => 'flowChartMagneticDisk', 216cdf0e10cSrcweir 133 => 'flowChartMagneticDrum', 217cdf0e10cSrcweir 134 => 'flowChartDisplay', 218cdf0e10cSrcweir 135 => 'flowChartDelay', 219cdf0e10cSrcweir 136 => 'textPlain', # textPlainText 220cdf0e10cSrcweir 137 => 'textStop', 221cdf0e10cSrcweir 138 => 'textTriangle', 222cdf0e10cSrcweir 139 => 'textTriangleInverted', 223cdf0e10cSrcweir 140 => 'textChevron', 224cdf0e10cSrcweir 141 => 'textChevronInverted', 225cdf0e10cSrcweir 142 => 'textRingInside', 226cdf0e10cSrcweir 143 => 'textRingOutside', 227cdf0e10cSrcweir 144 => 'textArchUp', # textArchUpCurve 228cdf0e10cSrcweir 145 => 'textArchDown', # textArchDownCurve 229cdf0e10cSrcweir 146 => 'textCircle', # textCircleCurve 230cdf0e10cSrcweir 147 => 'textButton', # textButtonCurve 231cdf0e10cSrcweir 148 => 'textArchUpPour', 232cdf0e10cSrcweir 149 => 'textArchDownPour', 233cdf0e10cSrcweir 150 => 'textCirclePour', 234cdf0e10cSrcweir 151 => 'textButtonPour', 235cdf0e10cSrcweir 152 => 'textCurveUp', 236cdf0e10cSrcweir 153 => 'textCurveDown', 237cdf0e10cSrcweir 154 => 'textCascadeUp', 238cdf0e10cSrcweir 155 => 'textCascadeDown', 239cdf0e10cSrcweir 156 => 'textWave1', 240cdf0e10cSrcweir 157 => 'textWave2', 241cdf0e10cSrcweir 158 => 'textWave3', 242cdf0e10cSrcweir 159 => 'textWave4', 243cdf0e10cSrcweir 160 => 'textInflate', 244cdf0e10cSrcweir 161 => 'textDeflate', 245cdf0e10cSrcweir 162 => 'textInflateBottom', 246cdf0e10cSrcweir 163 => 'textDeflateBottom', 247cdf0e10cSrcweir 164 => 'textInflateTop', 248cdf0e10cSrcweir 165 => 'textDeflateTop', 249cdf0e10cSrcweir 166 => 'textDeflateInflate', 250cdf0e10cSrcweir 167 => 'textDeflateInflateDeflate', 251cdf0e10cSrcweir 168 => 'textFadeRight', 252cdf0e10cSrcweir 169 => 'textFadeLeft', 253cdf0e10cSrcweir 170 => 'textFadeUp', 254cdf0e10cSrcweir 171 => 'textFadeDown', 255cdf0e10cSrcweir 172 => 'textSlantUp', 256cdf0e10cSrcweir 173 => 'textSlantDown', 257cdf0e10cSrcweir 174 => 'textCanUp', 258cdf0e10cSrcweir 175 => 'textCanDown', 259cdf0e10cSrcweir 176 => 'flowChartAlternateProcess', 260cdf0e10cSrcweir 177 => 'flowChartOffpageConnector', 261cdf0e10cSrcweir 178 => 'callout1', # callout90 262cdf0e10cSrcweir 179 => 'accentCallout1', # accentCallout90 263cdf0e10cSrcweir 180 => 'borderCallout1', # borderCallout90 264cdf0e10cSrcweir 181 => 'accentBorderCallout1', # accentBorderCallout90 265cdf0e10cSrcweir 182 => 'leftRightUpArrow', 266cdf0e10cSrcweir 183 => 'sun', 267cdf0e10cSrcweir 184 => 'moon', 268cdf0e10cSrcweir 185 => 'bracketPair', 269cdf0e10cSrcweir 186 => 'bracePair', 270cdf0e10cSrcweir 187 => 'star4', # seal4 271cdf0e10cSrcweir 188 => 'doubleWave', 272cdf0e10cSrcweir 189 => 'actionButtonBlank', 273cdf0e10cSrcweir 190 => 'actionButtonHome', 274cdf0e10cSrcweir 191 => 'actionButtonHelp', 275cdf0e10cSrcweir 192 => 'actionButtonInformation', 276cdf0e10cSrcweir 193 => 'actionButtonForwardNext', 277cdf0e10cSrcweir 194 => 'actionButtonBackPrevious', 278cdf0e10cSrcweir 195 => 'actionButtonEnd', 279cdf0e10cSrcweir 196 => 'actionButtonBeginning', 280cdf0e10cSrcweir 197 => 'actionButtonReturn', 281cdf0e10cSrcweir 198 => 'actionButtonDocument', 282cdf0e10cSrcweir 199 => 'actionButtonSound', 283cdf0e10cSrcweir 200 => 'actionButtonMovie', 284cdf0e10cSrcweir 201 => 'hostControl', # should not be used 285cdf0e10cSrcweir 202 => 'textBox' 286cdf0e10cSrcweir); 287a893be29SPedro Giffuni# An error occurred, we have to ignore this shape 288cdf0e10cSrcweirsub error( $ ) 289cdf0e10cSrcweir{ 290cdf0e10cSrcweir my ( $msg ) = @_; 291cdf0e10cSrcweir 292cdf0e10cSrcweir $ignore_this_shape = 1; 293cdf0e10cSrcweir print STDERR "ERROR (in $shape_name ): $msg\n"; 294cdf0e10cSrcweir} 295cdf0e10cSrcweir 296cdf0e10cSrcweir# Check that we are in the correct level 297cdf0e10cSrcweirsub is_level( $$ ) 298cdf0e10cSrcweir{ 299cdf0e10cSrcweir my ( $level, $value ) = @_; 300cdf0e10cSrcweir 301cdf0e10cSrcweir if ( $level > 0 ) { 302cdf0e10cSrcweir error( "Error in is_level(), \$level should be <= 0." ); 303cdf0e10cSrcweir } 304cdf0e10cSrcweir return ( $#levels + $level > 0 ) && ( $levels[$#levels + $level] eq $value ); 305cdf0e10cSrcweir} 306cdf0e10cSrcweir 307cdf0e10cSrcweir# Setup the %variables map with predefined values 308cdf0e10cSrcweirsub setup_variables() 309cdf0e10cSrcweir{ 310cdf0e10cSrcweir %variables = ( 311cdf0e10cSrcweir 'l' => 0, 312cdf0e10cSrcweir 't' => 0, 313cdf0e10cSrcweir 'r' => 21600, 314cdf0e10cSrcweir 'b' => 21600, 315cdf0e10cSrcweir 316cdf0e10cSrcweir 'w' => 21600, 317cdf0e10cSrcweir 'h' => 21600, 318cdf0e10cSrcweir 'ss' => 21600, 319cdf0e10cSrcweir 'ls' => 21600, 320cdf0e10cSrcweir 321cdf0e10cSrcweir 'ssd2' => 10800, # 1/2 322cdf0e10cSrcweir 'ssd4' => 5400, # 1/4 323cdf0e10cSrcweir 'ssd6' => 3600, # 1/6 324cdf0e10cSrcweir 'ssd8' => 2700, # 1/8 325cdf0e10cSrcweir 'ssd16' => 1350, # 1/16 326cdf0e10cSrcweir 'ssd32' => 675, # 1/32 327cdf0e10cSrcweir 328cdf0e10cSrcweir 'hc' => 10800, # horizontal center 329cdf0e10cSrcweir 'vc' => 10800, # vertical center 330cdf0e10cSrcweir 331cdf0e10cSrcweir 'wd2' => 10800, # 1/2 332cdf0e10cSrcweir 'wd3' => 7200, # 1/3 333cdf0e10cSrcweir 'wd4' => 5400, # 1/4 334cdf0e10cSrcweir 'wd5' => 4320, # 1/5 335cdf0e10cSrcweir 'wd6' => 3600, # 1/6 336cdf0e10cSrcweir 'wd8' => 2700, # 1/8 337cdf0e10cSrcweir 'wd10' => 2160, # 1/10 338cdf0e10cSrcweir 'wd12' => 1800, # 1/12 339cdf0e10cSrcweir 'wd32' => 675, # 1/32 340cdf0e10cSrcweir 341cdf0e10cSrcweir 'hd2' => 10800, # 1/2 342cdf0e10cSrcweir 'hd3' => 7200, # 1/3 343cdf0e10cSrcweir 'hd4' => 5400, # 1/4 344cdf0e10cSrcweir 'hd5' => 4320, # 1/5 345cdf0e10cSrcweir 'hd6' => 3600, # 1/6 346cdf0e10cSrcweir 'hd8' => 2700, # 1/8 347cdf0e10cSrcweir 'hd10' => 2160, # 1/10 348cdf0e10cSrcweir 'hd12' => 1800, # 1/12 349cdf0e10cSrcweir 'hd32' => 675, # 1/32 350cdf0e10cSrcweir 351cdf0e10cSrcweir '25000' => 5400, 352cdf0e10cSrcweir '12500' => 2700, 353cdf0e10cSrcweir 354cdf0e10cSrcweir 'cd4' => 90, # 1/4 of a circle 355cdf0e10cSrcweir 'cd2' => 180, # 1/2 of a circle 356cdf0e10cSrcweir '3cd4' => 270, # 3/4 of a circle 357cdf0e10cSrcweir 358cdf0e10cSrcweir 'cd8' => 45, # 1/8 of a circle 359cdf0e10cSrcweir '3cd8' => 135, # 3/8 of a circle 360cdf0e10cSrcweir '5cd8' => 225, # 5/8 of a circle 361cdf0e10cSrcweir '7cd8' => 315, # 7/8 of a circle 362cdf0e10cSrcweir 363cdf0e10cSrcweir '-5400000' => -90, 364cdf0e10cSrcweir '-10800000'=> -180, 365cdf0e10cSrcweir '-16200000'=> -270, 366cdf0e10cSrcweir '-21600000'=> -360, 367cdf0e10cSrcweir '-21599999'=> -360, 368cdf0e10cSrcweir 369cdf0e10cSrcweir '5400000' => 90, 370cdf0e10cSrcweir '10800000' => 180, 371cdf0e10cSrcweir '16200000' => 270, 372cdf0e10cSrcweir '21600000' => 360, 373cdf0e10cSrcweir '21599999' => 360 374cdf0e10cSrcweir# 375cdf0e10cSrcweir# '21600000' => 360, # angle conversions 376cdf0e10cSrcweir# '27000000' => 450, 377cdf0e10cSrcweir# '32400000' => 540, 378cdf0e10cSrcweir# '37800000' => 630 379cdf0e10cSrcweir ); 380cdf0e10cSrcweir} 381cdf0e10cSrcweir 382cdf0e10cSrcweir# Convert the (predefiend) value to a number 383cdf0e10cSrcweirsub value( $ ) 384cdf0e10cSrcweir{ 385cdf0e10cSrcweir my ( $val ) = @_; 386cdf0e10cSrcweir 387cdf0e10cSrcweir my $result = $variables{$val}; 388cdf0e10cSrcweir return $result if ( defined( $result ) ); 389cdf0e10cSrcweir 390cdf0e10cSrcweir return $val if ( $val =~ /^[0-9-]+$/ ); 391cdf0e10cSrcweir 392cdf0e10cSrcweir error( "Unknown variable '$val'." ); 393cdf0e10cSrcweir 394cdf0e10cSrcweir show_call_stack(); 395cdf0e10cSrcweir return $val; 396cdf0e10cSrcweir} 397cdf0e10cSrcweir 398cdf0e10cSrcweir# Convert the DrawingML formula to a VML one 399cdf0e10cSrcweir%command_variables = ( 400cdf0e10cSrcweir 'w' => 'width', 401cdf0e10cSrcweir 'h' => 'height', 402cdf0e10cSrcweir 'r' => 'width', 403cdf0e10cSrcweir 'b' => 'height' 404cdf0e10cSrcweir); 405cdf0e10cSrcweir 406cdf0e10cSrcweir# The same as value(), but some of the hardcoded values can have a name 407cdf0e10cSrcweirsub command_value( $ ) 408cdf0e10cSrcweir{ 409cdf0e10cSrcweir my ( $value ) = @_; 410cdf0e10cSrcweir 411cdf0e10cSrcweir return "" if ( $value eq "" ); 412cdf0e10cSrcweir 413cdf0e10cSrcweir return $value if ( $value =~ /^@/ ); 414cdf0e10cSrcweir 415cdf0e10cSrcweir my $command_val = $command_variables{$value}; 416cdf0e10cSrcweir if ( defined( $command_val ) ) { 417cdf0e10cSrcweir return $command_val; 418cdf0e10cSrcweir } 419cdf0e10cSrcweir 420cdf0e10cSrcweir return value( $value ); 421cdf0e10cSrcweir} 422cdf0e10cSrcweir 423cdf0e10cSrcweir# Insert the new formula to the list of formulas 424cdf0e10cSrcweir# Creates the name if it's empty... 425cdf0e10cSrcweirsub insert_formula( $$ ) 426cdf0e10cSrcweir{ 427cdf0e10cSrcweir my ( $name, $fmla ) = @_; 428cdf0e10cSrcweir 429cdf0e10cSrcweir my $i = 0; 430cdf0e10cSrcweir foreach $f ( @formulas ) { 431cdf0e10cSrcweir if ( $f eq $fmla ) { 432cdf0e10cSrcweir if ( $name ne "" ) { 433cdf0e10cSrcweir $variables{$name} = "@" . $i; 434cdf0e10cSrcweir } 435cdf0e10cSrcweir return "@" . $i; 436cdf0e10cSrcweir } 437cdf0e10cSrcweir ++$i; 438cdf0e10cSrcweir } 439cdf0e10cSrcweir 440cdf0e10cSrcweir if ( $name eq "" ) { 441cdf0e10cSrcweir $name = "@" . ( $#formulas + 1 ); 442cdf0e10cSrcweir } 443cdf0e10cSrcweir 444cdf0e10cSrcweir $variables{$name} = "@" . ( $#formulas + 1 ); 445cdf0e10cSrcweir push @formulas, $fmla; 446cdf0e10cSrcweir 447cdf0e10cSrcweir if ( $#formulas > 127 ) { 448cdf0e10cSrcweir error( "Reached the maximum amount of formulas, have to ignore the shape '$shape_name'" ); 449cdf0e10cSrcweir } 450cdf0e10cSrcweir 451cdf0e10cSrcweir return $variables{$name}; 452cdf0e10cSrcweir} 453cdf0e10cSrcweir 454cdf0e10cSrcweir# The same as insert_formula(), but converts the params 455cdf0e10cSrcweirsub insert_formula_params( $$$$$ ) 456cdf0e10cSrcweir{ 457cdf0e10cSrcweir my ( $name, $command, $p1, $p2, $p3 ) = @_; 458cdf0e10cSrcweir 459cdf0e10cSrcweir my $result = $command; 460cdf0e10cSrcweir if ( $p1 ne "" ) { 461cdf0e10cSrcweir $result .= " " . command_value( $p1 ); 462cdf0e10cSrcweir if ( $p2 ne "" ) { 463cdf0e10cSrcweir $result .= " " . command_value( $p2 ); 464cdf0e10cSrcweir if ( $p3 ne "" ) { 465cdf0e10cSrcweir $result .= " " . command_value( $p3 ); 466cdf0e10cSrcweir } 467cdf0e10cSrcweir } 468cdf0e10cSrcweir } 469cdf0e10cSrcweir 470cdf0e10cSrcweir return insert_formula( $name, $result ); 471cdf0e10cSrcweir} 472cdf0e10cSrcweir 473cdf0e10cSrcweir# Convert the formula from DrawingML to VML 474cdf0e10cSrcweirsub convert_formula( $$ ) 475cdf0e10cSrcweir{ 476cdf0e10cSrcweir my ( $name, $fmla ) = @_; 477cdf0e10cSrcweir 478cdf0e10cSrcweir if ( $fmla =~ /^([^ ]+)/ ) { 479cdf0e10cSrcweir my $command = $1; 480cdf0e10cSrcweir 481cdf0e10cSrcweir # parse the parameters 482cdf0e10cSrcweir ( my $values = $fmla ) =~ s/^([^ ]+) *//; 483cdf0e10cSrcweir my $p1 = "", $p2 = "", $p3 = ""; 484cdf0e10cSrcweir if ( $values =~ /^([^ ]+)/ ) { 485cdf0e10cSrcweir $p1 = $1; 486cdf0e10cSrcweir $values =~ s/^([^ ]+) *//; 487cdf0e10cSrcweir if ( $values =~ /^([^ ]+)/ ) { 488cdf0e10cSrcweir $p2 = $1; 489cdf0e10cSrcweir $values =~ s/^([^ ]+) *//; 490cdf0e10cSrcweir if ( $values =~ /^([^ ]+)/ ) { 491cdf0e10cSrcweir $p3 = $1; 492cdf0e10cSrcweir } 493cdf0e10cSrcweir } 494cdf0e10cSrcweir } 495cdf0e10cSrcweir 496cdf0e10cSrcweir # now convert the formula 497cdf0e10cSrcweir if ( $command eq "+-" ) { 498cdf0e10cSrcweir if ( $p1 eq "100000" ) { 499cdf0e10cSrcweir $p1 = value( 'w' ); 500cdf0e10cSrcweir } 501cdf0e10cSrcweir insert_formula_params( $name, "sum", $p1, $p2, $p3 ); 502cdf0e10cSrcweir return; 503cdf0e10cSrcweir } 504cdf0e10cSrcweir elsif ( $command eq "*/" ) { 505cdf0e10cSrcweir if ( ( $p2 =~ /^(w|h|ss|hd2|wd2|vc)$/ ) && defined( $variables{$p1} ) ) { 506cdf0e10cSrcweir # switch it ;-) - presetTextWarpDefinitions.xml has it in other order 507cdf0e10cSrcweir my $tmp = $p1; 508cdf0e10cSrcweir $p1 = $p2; 509cdf0e10cSrcweir $p2 = $tmp; 510cdf0e10cSrcweir } 511cdf0e10cSrcweir 512cdf0e10cSrcweir if ( ( $p1 =~ /^(w|h|ss|hd2|wd2|vc)$/ ) && defined( $variables{$p2} ) ) { 513cdf0e10cSrcweir my $val3 = $p3; 514cdf0e10cSrcweir if ( $val3 =~ /^[0-9-]+$/ ) { 515cdf0e10cSrcweir $val3 *= ( value( 'w' ) / value( $p1 ) ); 516cdf0e10cSrcweir 517cdf0e10cSrcweir # Oh yes, I'm too lazy to implement the full GCD here ;-) 518cdf0e10cSrcweir if ( ( $val3 % 100000 ) == 0 ) { 519cdf0e10cSrcweir $p1 = 1; 520cdf0e10cSrcweir $p3 = sprintf( "%.0f", ( $val3 / 100000 ) ); 521cdf0e10cSrcweir } 522cdf0e10cSrcweir elsif ( $val3 < 100000 ) { 523cdf0e10cSrcweir $p3 = 1; 524cdf0e10cSrcweir while ( ( ( $p3 * 100000 ) % $val3 ) != 0 ) { 525cdf0e10cSrcweir ++$p3 526cdf0e10cSrcweir } 527cdf0e10cSrcweir $p1 = ( $p3 * 100000 ) / $val3; 528cdf0e10cSrcweir } 529cdf0e10cSrcweir else { 530cdf0e10cSrcweir error( "Need to count the greatest common divisor." ); 531cdf0e10cSrcweir } 532cdf0e10cSrcweir } 533cdf0e10cSrcweir } 534cdf0e10cSrcweir elsif ( $p3 eq "100000" && $p2 =~ /^[0-9-]+$/ ) { 535cdf0e10cSrcweir # prevent overflows in some shapes 536cdf0e10cSrcweir $p2 = sprintf( "%.0f", ( $p2 / 10 ) ); 537cdf0e10cSrcweir $p3 /= 10; 538cdf0e10cSrcweir } 539cdf0e10cSrcweir elsif ( $p3 eq "32768" && $p2 =~ /^[0-9-]+$/ ) { 540cdf0e10cSrcweir # prevent overflows in some shapes 541cdf0e10cSrcweir $p2 = sprintf( "%.0f", ( $p2 / 8 ) ); 542cdf0e10cSrcweir $p3 /= 8; 543cdf0e10cSrcweir } 544cdf0e10cSrcweir elsif ( $p3 eq "50000" ) { 545cdf0e10cSrcweir $p3 = 10800; 546cdf0e10cSrcweir } 547cdf0e10cSrcweir elsif ( $name =~ /^maxAdj/ ) { 548cdf0e10cSrcweir my $val = value( $p1 ); 549cdf0e10cSrcweir if ( $val =~ /^[0-9-]+$/ ) { 550cdf0e10cSrcweir $p1 = sprintf( "%.0f", ( value( 'w' ) * $val / 100000 ) ); 551cdf0e10cSrcweir } 552cdf0e10cSrcweir } 553cdf0e10cSrcweir 554cdf0e10cSrcweir if ( ( value( $p1 ) eq value( $p3 ) ) || ( value( $p2 ) eq value( $p3 ) ) ) { 555cdf0e10cSrcweir my $val = value( ( value( $p1 ) eq value( $p3 ) )? $p2: $p1 ); 556cdf0e10cSrcweir if ( $val =~ /^@([0-9]+)$/ ) { 557cdf0e10cSrcweir insert_formula( $name, $formulas[$1] ); 558cdf0e10cSrcweir } 559cdf0e10cSrcweir else { 560cdf0e10cSrcweir insert_formula( $name, "val $val" ); 561cdf0e10cSrcweir } 562cdf0e10cSrcweir } 563cdf0e10cSrcweir else { 564cdf0e10cSrcweir insert_formula_params( $name, "prod", $p1, $p2, $p3 ); 565cdf0e10cSrcweir } 566cdf0e10cSrcweir return; 567cdf0e10cSrcweir } 568cdf0e10cSrcweir elsif ( $command eq "+/" ) { 569cdf0e10cSrcweir # we have to split this into 2 formulas - 'sum' and 'prod' 570cdf0e10cSrcweir my $constructed = insert_formula_params( "", "sum", $p1, $p2, "0" ); 571cdf0e10cSrcweir insert_formula_params( $name, "prod", 1, $constructed, $p3); # references the 'sum' formula 572cdf0e10cSrcweir return; 573cdf0e10cSrcweir } 574cdf0e10cSrcweir elsif ( $command eq "?:" ) { 575cdf0e10cSrcweir insert_formula_params( $name, "if", $p1, $p2, $p3 ); 576cdf0e10cSrcweir return; 577cdf0e10cSrcweir } 578cdf0e10cSrcweir elsif ( $command eq "sin" || $command eq "cos" ) { 579cdf0e10cSrcweir if ( $p2 =~ /^[0-9-]+$/ && ( ( $p2 % 60000 ) == 0 ) ) { 580cdf0e10cSrcweir $p2 /= 60000; 581cdf0e10cSrcweir } 582cdf0e10cSrcweir else { 583cdf0e10cSrcweir $p2 = insert_formula_params( "", "prod", "1", $p2, "60000" ); 584cdf0e10cSrcweir } 585cdf0e10cSrcweir # we have to use 'sumangle' even for the case when $p2 is const 586cdf0e10cSrcweir # and theoretically could be written as such; but Word does not 587cdf0e10cSrcweir # accept it :-( 588cdf0e10cSrcweir my $conv = insert_formula_params( "", "sumangle", "0", $p2, "0" ); 589cdf0e10cSrcweir 590cdf0e10cSrcweir $p2 = $conv; 591cdf0e10cSrcweir 592cdf0e10cSrcweir insert_formula_params( $name, $command, $p1, $p2, "" ); 593cdf0e10cSrcweir return; 594cdf0e10cSrcweir } 595cdf0e10cSrcweir elsif ( $command eq "abs" ) { 596cdf0e10cSrcweir insert_formula_params( $name, $command, $p1, "", "" ); 597cdf0e10cSrcweir return; 598cdf0e10cSrcweir } 599cdf0e10cSrcweir elsif ( $command eq "max" || $command eq "min" ) { 600cdf0e10cSrcweir insert_formula_params( $name, $command, $p1, $p2, "" ); 601cdf0e10cSrcweir return; 602cdf0e10cSrcweir } 603cdf0e10cSrcweir elsif ( $command eq "at2" ) { 604cdf0e10cSrcweir insert_formula_params( $name, "atan2", $p1, $p2, "" ); 605cdf0e10cSrcweir return; 606cdf0e10cSrcweir } 607cdf0e10cSrcweir elsif ( $command eq "cat2" ) { 608cdf0e10cSrcweir insert_formula_params( $name, "cosatan2", $p1, $p2, $p3 ); 609cdf0e10cSrcweir return; 610cdf0e10cSrcweir } 611cdf0e10cSrcweir elsif ( $command eq "sat2" ) { 612cdf0e10cSrcweir insert_formula_params( $name, "sinatan2", $p1, $p2, $p3 ); 613cdf0e10cSrcweir return; 614cdf0e10cSrcweir } 615cdf0e10cSrcweir elsif ( $command eq "sqrt" ) { 616cdf0e10cSrcweir insert_formula_params( $name, "sqrt", $p1, "", "" ); 617cdf0e10cSrcweir return; 618cdf0e10cSrcweir } 619cdf0e10cSrcweir elsif ( $command eq "mod" ) { 620cdf0e10cSrcweir insert_formula_params( $name, "mod", $p1, $p2, $p3 ); 621cdf0e10cSrcweir return; 622cdf0e10cSrcweir } 623cdf0e10cSrcweir elsif ( $command eq "val" ) { 624cdf0e10cSrcweir insert_formula_params( $name, "val", value( $p1 ), "", "" ); 625cdf0e10cSrcweir return; 626cdf0e10cSrcweir } 627cdf0e10cSrcweir else { 628cdf0e10cSrcweir error( "Unknown formula '$name', '$fmla'." ); 629cdf0e10cSrcweir } 630cdf0e10cSrcweir } 631cdf0e10cSrcweir else { 632cdf0e10cSrcweir error( "Cannot convert formula's command '$name', '$fmla'." ); 633cdf0e10cSrcweir } 634cdf0e10cSrcweir} 635cdf0e10cSrcweir 636cdf0e10cSrcweir# There's no exact equivalent of 'arcTo' in VML, we have to do some special casing... 637cdf0e10cSrcweir%convert_arcTo = ( 638cdf0e10cSrcweir '0' => { 639cdf0e10cSrcweir '90' => { 640cdf0e10cSrcweir 'path' => 'qy', 641cdf0e10cSrcweir 'op' => [ 'sum 0 __last_x__ __wR__', 'sum __hR__ __last_y__ 0' ], 642cdf0e10cSrcweir }, 643cdf0e10cSrcweir '-90' => { 644cdf0e10cSrcweir 'path' => 'qy', 645cdf0e10cSrcweir 'op' => [ 'sum 0 __last_x__ __wR__', 'sum 0 __last_y__ __hR__' ], 646cdf0e10cSrcweir }, 647cdf0e10cSrcweir }, 648cdf0e10cSrcweir '90' => { 649cdf0e10cSrcweir '90' => { 650cdf0e10cSrcweir 'path' => 'qx', 651cdf0e10cSrcweir 'op' => [ 'sum 0 __last_x__ __wR__', 'sum 0 __last_y__ __hR__' ], 652cdf0e10cSrcweir }, 653cdf0e10cSrcweir '-90' => { 654cdf0e10cSrcweir 'path' => 'qx', 655cdf0e10cSrcweir 'op' => [ 'sum __wR__ __last_x__ 0', 'sum 0 __last_y__ __hR__' ], 656cdf0e10cSrcweir }, 657cdf0e10cSrcweir }, 658cdf0e10cSrcweir '180' => { 659cdf0e10cSrcweir '90' => { 660cdf0e10cSrcweir 'path' => 'qy', 661cdf0e10cSrcweir 'op' => [ 'sum __wR__ __last_x__ 0', 'sum 0 __last_y__ __hR__' ], 662cdf0e10cSrcweir }, 663cdf0e10cSrcweir '-90' => { 664cdf0e10cSrcweir 'path' => 'qy', 665cdf0e10cSrcweir 'op' => [ 'sum __wR__ __last_x__ 0', 'sum __hR__ __last_y__ 0' ], 666cdf0e10cSrcweir }, 667cdf0e10cSrcweir }, 668cdf0e10cSrcweir '270' => { 669cdf0e10cSrcweir '90' => { 670cdf0e10cSrcweir 'path' => 'qx', 671cdf0e10cSrcweir 'op' => [ 'sum __wR__ __last_x__ 0', 'sum __hR__ __last_y__ 0' ], 672cdf0e10cSrcweir }, 673cdf0e10cSrcweir '-90' => { 674cdf0e10cSrcweir 'path' => 'qx', 675cdf0e10cSrcweir 'op' => [ 'sum 0 __last_x__ __wR__', 'sum __hR__ __last_y__ 0' ], 676cdf0e10cSrcweir }, 677cdf0e10cSrcweir }, 678cdf0e10cSrcweir); 679cdf0e10cSrcweir 680cdf0e10cSrcweir# Elliptic quadrant 681cdf0e10cSrcweir# FIXME optimize so that we compute the const values when possible 682cdf0e10cSrcweirsub elliptic_quadrant( $$$$ ) 683cdf0e10cSrcweir{ 684cdf0e10cSrcweir my ( $wR, $hR, $stAng, $swAng ) = @_; 685cdf0e10cSrcweir 686cdf0e10cSrcweir if ( defined( $convert_arcTo{$stAng} ) && defined( $convert_arcTo{$stAng}{$swAng} ) ) { 687cdf0e10cSrcweir my $conv_path = $convert_arcTo{$stAng}{$swAng}{'path'}; 688cdf0e10cSrcweir my $conv_op_ref = $convert_arcTo{$stAng}{$swAng}{'op'}; 689cdf0e10cSrcweir 690cdf0e10cSrcweir $path .= "$conv_path"; 691cdf0e10cSrcweir 692cdf0e10cSrcweir my $pos_x = $last_pos_x; 693cdf0e10cSrcweir my $pos_y = $last_pos_y; 694cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$conv_op_ref}; ++$i ) { 695cdf0e10cSrcweir my $op = $conv_op_ref->[$i]; 696cdf0e10cSrcweir 697cdf0e10cSrcweir $op =~ s/__last_x__/$last_pos_x/g; 698cdf0e10cSrcweir $op =~ s/__last_y__/$last_pos_y/g; 699cdf0e10cSrcweir $op =~ s/__wR__/$wR/g; 700cdf0e10cSrcweir $op =~ s/__hR__/$hR/g; 701cdf0e10cSrcweir 702cdf0e10cSrcweir my $fmla = insert_formula( "", $op ); 703cdf0e10cSrcweir 704cdf0e10cSrcweir $path .= $fmla; 705cdf0e10cSrcweir 706cdf0e10cSrcweir # so far it's sufficient just to rotate the positions 707cdf0e10cSrcweir # FIXME if not ;-) 708cdf0e10cSrcweir $pos_x = $pos_y; 709cdf0e10cSrcweir $pos_y = $fmla; 710cdf0e10cSrcweir } 711cdf0e10cSrcweir $last_pos_x = $pos_x; 712cdf0e10cSrcweir $last_pos_y = $pos_y; 713cdf0e10cSrcweir } 714cdf0e10cSrcweir else { 715cdf0e10cSrcweir error( "Unhandled elliptic_quadrant(), input is ($wR, $hR, $stAng, $swAng)." ); 716cdf0e10cSrcweir } 717cdf0e10cSrcweir} 718cdf0e10cSrcweir 719cdf0e10cSrcweir# Convert the quadratic bezier to cubic (exact) 720cdf0e10cSrcweir# No idea why, but the 'qb' did not work for me :-( 721cdf0e10cSrcweirsub quadratic_to_cubic_bezier( $ ) 722cdf0e10cSrcweir{ 723cdf0e10cSrcweir my ( $axis ) = @_; 724cdf0e10cSrcweir 725cdf0e10cSrcweir my $a0 = $quadratic_bezier[0]->{$axis}; 726cdf0e10cSrcweir my $a1 = $quadratic_bezier[1]->{$axis}; 727cdf0e10cSrcweir my $a2 = $quadratic_bezier[2]->{$axis}; 728cdf0e10cSrcweir 729cdf0e10cSrcweir my $b0 = $a0; 730cdf0e10cSrcweir 731cdf0e10cSrcweir # $b1 = $a0 + 2/3 * ( $a1 - $a0 ), but in VML 732cdf0e10cSrcweir # FIXME optimize for constants - compute directly 733cdf0e10cSrcweir my $b1_1 = insert_formula_params( "", "sum", "0", $a1, $a0 ); 734cdf0e10cSrcweir my $b1_2 = insert_formula_params( "", "prod", "2", $b1_1, "3" ); 735cdf0e10cSrcweir my $b1 = insert_formula_params( "", "sum", $a0, $b1_2, "0" ); 736cdf0e10cSrcweir 737cdf0e10cSrcweir # $b2 = $b1 + 1/3 * ( $a2 - $a0 ); 738cdf0e10cSrcweir # FIXME optimize for constants - compute directly 739cdf0e10cSrcweir my $b2_1 = insert_formula_params( "", "sum", "0", $a2, $a0 ); 740cdf0e10cSrcweir my $b2_2 = insert_formula_params( "", "prod", "1", $b2_1, "3" ); 741cdf0e10cSrcweir my $b2 = insert_formula_params( "", "sum", $b1, $b2_2, "0" ); 742cdf0e10cSrcweir 743cdf0e10cSrcweir my $b3 = $a2; 744cdf0e10cSrcweir 745cdf0e10cSrcweir return ( $b0, $b1, $b2, $b3 ); 746cdf0e10cSrcweir} 747cdf0e10cSrcweir 748cdf0e10cSrcweir# Extend $path by one more point 749cdf0e10cSrcweirsub add_point_to_path( $$ ) 750cdf0e10cSrcweir{ 751cdf0e10cSrcweir my ( $x, $y ) = @_; 752cdf0e10cSrcweir 753cdf0e10cSrcweir if ( $path =~ /[0-9]$/ && $x =~ /^[0-9-]/ ) { 754cdf0e10cSrcweir $path .= ","; 755cdf0e10cSrcweir } 756cdf0e10cSrcweir $path .= $x; 757cdf0e10cSrcweir 758cdf0e10cSrcweir if ( $path =~ /[0-9]$/ && $y =~ /^[0-9-]/ ) { 759cdf0e10cSrcweir $path .= ","; 760cdf0e10cSrcweir } 761cdf0e10cSrcweir $path .= $y; 762cdf0e10cSrcweir} 763cdf0e10cSrcweir 764cdf0e10cSrcweir# Start of an element 765cdf0e10cSrcweirsub start_element( $% ) 766cdf0e10cSrcweir{ 767cdf0e10cSrcweir my ( $element, %attr ) = @_; 768cdf0e10cSrcweir 769cdf0e10cSrcweir push @levels, $element; 770cdf0e10cSrcweir 771cdf0e10cSrcweir #print "element: $element\n"; 772cdf0e10cSrcweir 773cdf0e10cSrcweir if ( is_level( -1, "presetShapeDefinitons" ) || is_level( -1, "presetTextWarpDefinitions" ) ) { 774cdf0e10cSrcweir $shape_name = $element; 775cdf0e10cSrcweir 776cdf0e10cSrcweir $state = ""; 777cdf0e10cSrcweir $ignore_this_shape = 0; 778cdf0e10cSrcweir $path = ""; 779cdf0e10cSrcweir $adjust = ""; 780cdf0e10cSrcweir $max_adj_no = 0; 781cdf0e10cSrcweir @formulas = (); 782cdf0e10cSrcweir $handles = ""; 783cdf0e10cSrcweir $textboxrect = ""; 784cdf0e10cSrcweir $last_pos_x = ""; 785cdf0e10cSrcweir $last_pos_y = ""; 786cdf0e10cSrcweir $no_stroke = 0; 787cdf0e10cSrcweir $no_fill = 0; 788cdf0e10cSrcweir @quadratic_bezier = (); 789cdf0e10cSrcweir 790cdf0e10cSrcweir setup_variables(); 791cdf0e10cSrcweir 792cdf0e10cSrcweir if ( $shape_name eq "sun" ) { 793cdf0e10cSrcweir # hack for this shape 794cdf0e10cSrcweir $variables{'100000'} = "21600"; 795cdf0e10cSrcweir $variables{'50000'} = "10800"; 796cdf0e10cSrcweir $variables{'25000'} = "5400"; 797cdf0e10cSrcweir $variables{'12500'} = "2700"; 798cdf0e10cSrcweir $variables{'3662'} = "791"; 799cdf0e10cSrcweir } 800cdf0e10cSrcweir 801cdf0e10cSrcweir my $found = 0; 802cdf0e10cSrcweir foreach my $name ( values( %shapes_ids ) ) { 803cdf0e10cSrcweir if ( $name eq $shape_name ) { 804cdf0e10cSrcweir $found = 1; 805cdf0e10cSrcweir last; 806cdf0e10cSrcweir } 807cdf0e10cSrcweir } 808cdf0e10cSrcweir if ( !$found ) { 809cdf0e10cSrcweir error( "Unknown shape '$shape_name'." ); 810cdf0e10cSrcweir } 811cdf0e10cSrcweir } 812cdf0e10cSrcweir elsif ( $element eq "pathLst" ) { 813cdf0e10cSrcweir $state = "path"; 814cdf0e10cSrcweir } 815cdf0e10cSrcweir elsif ( $element eq "avLst" ) { 816cdf0e10cSrcweir $state = "adjust"; 817cdf0e10cSrcweir } 818cdf0e10cSrcweir elsif ( $element eq "gdLst" ) { 819cdf0e10cSrcweir $state = "formulas"; 820cdf0e10cSrcweir } 821cdf0e10cSrcweir elsif ( $element eq "ahLst" ) { 822cdf0e10cSrcweir $state = "handles"; 823cdf0e10cSrcweir } 824cdf0e10cSrcweir elsif ( $element eq "rect" ) { 825cdf0e10cSrcweir $textboxrect = value( $attr{'l'} ) . "," . value( $attr{'t'} ) . "," . 826cdf0e10cSrcweir value( $attr{'r'} ) . "," . value( $attr{'b'} ); 827cdf0e10cSrcweir } 828cdf0e10cSrcweir elsif ( $state eq "path" ) { 829cdf0e10cSrcweir if ( $element eq "path" ) { 830cdf0e10cSrcweir $no_stroke = ( defined( $attr{'stroke'} ) && $attr{'stroke'} eq 'false' ); 831cdf0e10cSrcweir $no_fill = ( defined( $attr{'fill'} ) && $attr{'fill'} eq 'none' ); 832cdf0e10cSrcweir $path_w = $attr{'w'}; 833cdf0e10cSrcweir $path_h = $attr{'h'}; 834cdf0e10cSrcweir } 835cdf0e10cSrcweir elsif ( $element eq "moveTo" ) { 836cdf0e10cSrcweir $path .= "m"; 837cdf0e10cSrcweir } 838cdf0e10cSrcweir elsif ( $element eq "lnTo" ) { 839cdf0e10cSrcweir $path .= "l"; 840cdf0e10cSrcweir } 841cdf0e10cSrcweir elsif ( $element eq "cubicBezTo" ) { 842cdf0e10cSrcweir $path .= "c"; 843cdf0e10cSrcweir } 844cdf0e10cSrcweir elsif ( $element eq "quadBezTo" ) { 845cdf0e10cSrcweir my %points = ( 'x' => $last_pos_x, 'y' => $last_pos_y ); 846cdf0e10cSrcweir @quadratic_bezier = ( \%points ); 847cdf0e10cSrcweir } 848cdf0e10cSrcweir elsif ( $element eq "close" ) { 849cdf0e10cSrcweir $path .= "x"; 850cdf0e10cSrcweir } 851cdf0e10cSrcweir elsif ( $element eq "pt" ) { 852cdf0e10cSrcweir # rememeber the last position for the arcTo 853cdf0e10cSrcweir $last_pos_x = value( $attr{'x'} ); 854cdf0e10cSrcweir $last_pos_y = value( $attr{'y'} ); 855cdf0e10cSrcweir 856cdf0e10cSrcweir $last_pos_x *= ( value( 'w' ) / $path_w ) if ( defined( $path_w ) ); 857cdf0e10cSrcweir $last_pos_y *= ( value( 'h' ) / $path_h ) if ( defined( $path_h ) ); 858cdf0e10cSrcweir 859cdf0e10cSrcweir if ( $#quadratic_bezier >= 0 ) { 860cdf0e10cSrcweir my %points = ( 'x' => $last_pos_x, 'y' => $last_pos_y ); 861cdf0e10cSrcweir push( @quadratic_bezier, \%points ); 862cdf0e10cSrcweir } 863cdf0e10cSrcweir else { 864cdf0e10cSrcweir add_point_to_path( $last_pos_x, $last_pos_y ); 865cdf0e10cSrcweir } 866cdf0e10cSrcweir } 867cdf0e10cSrcweir elsif ( ( $element eq "arcTo" ) && ( $last_pos_x ne "" ) && ( $last_pos_y ne "" ) ) { 868cdf0e10cSrcweir # there's no exact equivalent of arcTo in VML, so we have to 869cdf0e10cSrcweir # compute here a bit... 870cdf0e10cSrcweir my $stAng = value( $attr{'stAng'} ); 871cdf0e10cSrcweir my $swAng = value( $attr{'swAng'} ); 872cdf0e10cSrcweir my $wR = value( $attr{'wR'} ); 873cdf0e10cSrcweir my $hR = value( $attr{'hR'} ); 874cdf0e10cSrcweir 875cdf0e10cSrcweir $wR *= ( value( 'w' ) / $path_w ) if ( defined( $path_w ) ); 876cdf0e10cSrcweir $hR *= ( value( 'h' ) / $path_h ) if ( defined( $path_h ) ); 877cdf0e10cSrcweir 878cdf0e10cSrcweir if ( ( $stAng =~ /^[0-9-]+$/ ) && ( $swAng =~ /^[0-9-]+$/ ) ) { 879cdf0e10cSrcweir if ( ( ( $stAng % 90 ) == 0 ) && ( ( $swAng % 90 ) == 0 ) && ( $swAng != 0 ) ) { 880cdf0e10cSrcweir my $end = $stAng + $swAng; 881cdf0e10cSrcweir my $step = ( $swAng > 0 )? 90: -90; 882cdf0e10cSrcweir 883cdf0e10cSrcweir for ( my $cur = $stAng; $cur != $end; $cur += $step ) { 884cdf0e10cSrcweir elliptic_quadrant( $wR, $hR, ( $cur % 360 ), $step ); 885cdf0e10cSrcweir } 886cdf0e10cSrcweir } 887cdf0e10cSrcweir else { 888cdf0e10cSrcweir error( "Unsupported numeric 'arcTo' ($attr{'wR'}, $attr{'hR'}, $stAng, $swAng)." ); 889cdf0e10cSrcweir } 890cdf0e10cSrcweir } 891cdf0e10cSrcweir else { 892cdf0e10cSrcweir error( "Unsupported 'arcTo' conversion ($attr{'wR'}, $attr{'hR'}, $stAng, $swAng)." ); 893cdf0e10cSrcweir } 894cdf0e10cSrcweir } 895cdf0e10cSrcweir else { 896cdf0e10cSrcweir error( "Unhandled path element '$element'." ); 897cdf0e10cSrcweir } 898cdf0e10cSrcweir } 899cdf0e10cSrcweir elsif ( $state eq "adjust" ) { 900cdf0e10cSrcweir if ( $element eq "gd" ) { 901cdf0e10cSrcweir my $adj_no = $attr{'name'}; 902cdf0e10cSrcweir my $is_const = 0; 903cdf0e10cSrcweir 904cdf0e10cSrcweir $adj_no =~ s/^adj//; 905cdf0e10cSrcweir if ( $adj_no eq "" ) { 906cdf0e10cSrcweir $max_adj_no = 0; 907cdf0e10cSrcweir } 908cdf0e10cSrcweir elsif ( !( $adj_no =~ /^[0-9]*$/ ) ) { 909cdf0e10cSrcweir ++$max_adj_no; 910cdf0e10cSrcweir $is_const = 1; 911cdf0e10cSrcweir } 912cdf0e10cSrcweir elsif ( $adj_no != $max_adj_no + 1 ) { 913cdf0e10cSrcweir error( "Wrong order of adj values." ); 914cdf0e10cSrcweir ++$max_adj_no; 915cdf0e10cSrcweir } 916cdf0e10cSrcweir else { 917cdf0e10cSrcweir $max_adj_no = $adj_no; 918cdf0e10cSrcweir } 919cdf0e10cSrcweir 920cdf0e10cSrcweir if ( $attr{'fmla'} =~ /^val ([0-9-]*)$/ ) { 921cdf0e10cSrcweir my $val = sprintf( "%.0f", ( 21600 * $1 ) / 100000 ); 922cdf0e10cSrcweir if ( $is_const ) { 923cdf0e10cSrcweir $variables{$adj_no} = $val; 924cdf0e10cSrcweir } 925cdf0e10cSrcweir elsif ( $adjust eq "" ) { 926cdf0e10cSrcweir $adjust = $val; 927cdf0e10cSrcweir } 928cdf0e10cSrcweir else { 929cdf0e10cSrcweir $adjust = "$val,$adjust"; 930cdf0e10cSrcweir } 931cdf0e10cSrcweir } 932cdf0e10cSrcweir else { 933cdf0e10cSrcweir error( "Wrong fmla '$attr{'fmla'}'." ); 934cdf0e10cSrcweir } 935cdf0e10cSrcweir } 936cdf0e10cSrcweir else { 937cdf0e10cSrcweir error( "Unhandled adjust element '$element'." ); 938cdf0e10cSrcweir } 939cdf0e10cSrcweir } 940cdf0e10cSrcweir elsif ( $state eq "formulas" ) { 941cdf0e10cSrcweir if ( $element eq "gd" ) { 942cdf0e10cSrcweir if ( $attr{'fmla'} =~ /^\*\/ (h|w|ss) adj([0-9]+) 100000$/ ) { 943cdf0e10cSrcweir insert_formula( $attr{'name'}, "val #" . ( $max_adj_no - $2 ) ); 944cdf0e10cSrcweir } 945cdf0e10cSrcweir elsif ( $attr{'fmla'} =~ /^pin [^ ]+ ([^ ]+) / ) { 946cdf0e10cSrcweir print STDERR "TODO Map 'pin' to VML as xrange for handles.\n"; 947cdf0e10cSrcweir my $pin_val = $1; 948cdf0e10cSrcweir if ( $pin_val eq "adj" ) { 949cdf0e10cSrcweir insert_formula( $attr{'name'}, "val #0" ); 950cdf0e10cSrcweir } 951cdf0e10cSrcweir elsif ( $pin_val =~ /^adj([0-9]+)/ ) { 952cdf0e10cSrcweir insert_formula( $attr{'name'}, "val #" . ( $max_adj_no - $1 ) ); 953cdf0e10cSrcweir } 954cdf0e10cSrcweir else { 955cdf0e10cSrcweir insert_formula( $attr{'name'}, "val " . value( $pin_val ) ); 956cdf0e10cSrcweir } 957cdf0e10cSrcweir } 958cdf0e10cSrcweir elsif ( $attr{'fmla'} =~ /adj/ ) { 959cdf0e10cSrcweir error( "Non-standard usage of adj in '$attr{'fmla'}'." ); 960cdf0e10cSrcweir } 961cdf0e10cSrcweir else { 962cdf0e10cSrcweir convert_formula( $attr{'name'}, $attr{'fmla'} ); 963cdf0e10cSrcweir } 964cdf0e10cSrcweir } 965cdf0e10cSrcweir } 966cdf0e10cSrcweir elsif ( $state eq "handles" ) { 967cdf0e10cSrcweir if ( $element eq "pos" ) { 968cdf0e10cSrcweir $handles .= "<v:h position=\"" . value( $attr{'x'} ) . "," . value( $attr{'y'} ) . "\"/>\n"; 969cdf0e10cSrcweir } 970cdf0e10cSrcweir } 971cdf0e10cSrcweir} 972cdf0e10cSrcweir 973cdf0e10cSrcweir# End of an element 974cdf0e10cSrcweirsub end_element( $ ) 975cdf0e10cSrcweir{ 976cdf0e10cSrcweir my ( $element ) = @_; 977cdf0e10cSrcweir 978cdf0e10cSrcweir pop @levels; 979cdf0e10cSrcweir 980cdf0e10cSrcweir if ( $element eq $shape_name ) { 981cdf0e10cSrcweir if ( !$ignore_this_shape ) { 982cdf0e10cSrcweir # we have all the info, generate the shape now 983cdf0e10cSrcweir $state = ""; 984cdf0e10cSrcweir 985cdf0e10cSrcweir # shape path 986cdf0e10cSrcweir my $out = "<v:shapetype id=\"shapetype___ID__\" coordsize=\"21600,21600\" o:spt=\"__ID__\" "; 987cdf0e10cSrcweir if ( $adjust ne "" ) { 988cdf0e10cSrcweir $out .= "adj=\"$adjust\" "; 989cdf0e10cSrcweir } 990cdf0e10cSrcweir 991cdf0e10cSrcweir # optimize it [yes, we need this twice ;-)] 992cdf0e10cSrcweir $path =~ s/([^0-9-@])0([^0-9-@])/$1$2/g; 993cdf0e10cSrcweir $path =~ s/([^0-9-@])0([^0-9-@])/$1$2/g; 994cdf0e10cSrcweir 995cdf0e10cSrcweir $out .= "path=\"$path\">\n"; 996cdf0e10cSrcweir 997cdf0e10cSrcweir # stroke 998cdf0e10cSrcweir $out .= "<v:stroke joinstyle=\"miter\"/>\n"; 999cdf0e10cSrcweir 1000cdf0e10cSrcweir # formulas 1001cdf0e10cSrcweir if ( $#formulas >= 0 ) 1002cdf0e10cSrcweir { 1003cdf0e10cSrcweir $out .= "<v:formulas>\n"; 1004cdf0e10cSrcweir foreach $fmla ( @formulas ) { 1005cdf0e10cSrcweir $out .= "<v:f eqn=\"$fmla\"/>\n" 1006cdf0e10cSrcweir } 1007cdf0e10cSrcweir $out .= "</v:formulas>\n"; 1008cdf0e10cSrcweir } 1009cdf0e10cSrcweir 1010cdf0e10cSrcweir # path 1011cdf0e10cSrcweir if ( $textboxrect ne "" ) { # TODO connectlocs, connectangles 1012cdf0e10cSrcweir $out .= "<v:path gradientshapeok=\"t\" o:connecttype=\"rect\" textboxrect=\"$textboxrect\"/>\n"; 1013cdf0e10cSrcweir } 1014cdf0e10cSrcweir 1015cdf0e10cSrcweir # handles 1016cdf0e10cSrcweir if ( $handles ne "" ) { 1017cdf0e10cSrcweir $out .= "<v:handles>\n$handles</v:handles>\n"; 1018cdf0e10cSrcweir } 1019cdf0e10cSrcweir 1020cdf0e10cSrcweir $out .="</v:shapetype>"; 1021cdf0e10cSrcweir 1022cdf0e10cSrcweir # hooray! :-) 1023cdf0e10cSrcweir $result_shapes{$shape_name} = $out; 1024cdf0e10cSrcweir } 1025cdf0e10cSrcweir else { 1026cdf0e10cSrcweir print STDERR "Shape '$shape_name' ignored; see the above error(s) for the reason.\n"; 1027cdf0e10cSrcweir } 1028cdf0e10cSrcweir $shape_name = ""; 1029cdf0e10cSrcweir } 1030cdf0e10cSrcweir elsif ( $state eq "path" ) { 1031cdf0e10cSrcweir if ( $element eq "path" ) { 1032cdf0e10cSrcweir $path .= "ns" if ( $no_stroke ); 1033cdf0e10cSrcweir $path .= "nf" if ( $no_fill ); 1034cdf0e10cSrcweir $path .= "e"; 1035cdf0e10cSrcweir } 1036cdf0e10cSrcweir elsif ( $element eq "quadBezTo" ) { 1037cdf0e10cSrcweir # we have to convert the quadratic bezier to cubic 1038cdf0e10cSrcweir if ( $#quadratic_bezier == 2 ) { 1039cdf0e10cSrcweir my @points_x = quadratic_to_cubic_bezier( 'x' ); 1040cdf0e10cSrcweir my @points_y = quadratic_to_cubic_bezier( 'y' ); 1041cdf0e10cSrcweir 1042cdf0e10cSrcweir $path .= "c"; 1043cdf0e10cSrcweir # ignore the starting point 1044cdf0e10cSrcweir for ( my $i = 1; $i < 4; ++$i ) { 1045cdf0e10cSrcweir add_point_to_path( $points_x[$i], $points_y[$i] ); 1046cdf0e10cSrcweir } 1047cdf0e10cSrcweir } 1048cdf0e10cSrcweir else { 1049cdf0e10cSrcweir error( "Wrong number of points of the quadratic bezier." ); 1050cdf0e10cSrcweir } 1051cdf0e10cSrcweir @quadratic_bezier = (); 1052cdf0e10cSrcweir } 1053cdf0e10cSrcweir } 1054cdf0e10cSrcweir elsif ( $element eq "avLst" ) { 1055cdf0e10cSrcweir $state = ""; 1056cdf0e10cSrcweir } 1057cdf0e10cSrcweir elsif ( $element eq "gdLst" ) { 1058cdf0e10cSrcweir $state = ""; 1059cdf0e10cSrcweir } 1060cdf0e10cSrcweir elsif ( $element eq "ahLst" ) { 1061cdf0e10cSrcweir $state = ""; 1062cdf0e10cSrcweir } 1063cdf0e10cSrcweir} 1064cdf0e10cSrcweir 1065cdf0e10cSrcweir# Text inside an element 1066cdf0e10cSrcweirsub characters( $ ) 1067cdf0e10cSrcweir{ 1068cdf0e10cSrcweir #my ( $text ) = @_; 1069cdf0e10cSrcweir} 1070cdf0e10cSrcweir 1071cdf0e10cSrcweir#################### A trivial XML parser #################### 1072cdf0e10cSrcweir 1073cdf0e10cSrcweir# Parse the attributes 1074cdf0e10cSrcweirsub parse_start_element( $ ) 1075cdf0e10cSrcweir{ 1076cdf0e10cSrcweir # split the string containing both the elements and attributes 1077cdf0e10cSrcweir my ( $element_tmp ) = @_; 1078cdf0e10cSrcweir 1079cdf0e10cSrcweir $element_tmp =~ s/\s*$//; 1080cdf0e10cSrcweir $element_tmp =~ s/^\s*//; 1081cdf0e10cSrcweir 1082cdf0e10cSrcweir ( my $element = $element_tmp ) =~ s/\s.*$//; 1083cdf0e10cSrcweir if ( $element_tmp =~ /\s/ ) { 1084cdf0e10cSrcweir $element_tmp =~ s/^[^\s]*\s//; 1085cdf0e10cSrcweir } 1086cdf0e10cSrcweir else { 1087cdf0e10cSrcweir $element_tmp = ""; 1088cdf0e10cSrcweir } 1089cdf0e10cSrcweir 1090cdf0e10cSrcweir # we have the element, now the attributes 1091cdf0e10cSrcweir my %attr; 1092cdf0e10cSrcweir my $is_key = 1; 1093cdf0e10cSrcweir my $key = ""; 1094cdf0e10cSrcweir foreach my $tmp ( split( /"/, $element_tmp ) ) { 1095cdf0e10cSrcweir if ( $is_key ) { 1096cdf0e10cSrcweir $key = $tmp; 1097cdf0e10cSrcweir $key =~ s/^\s*//; 1098cdf0e10cSrcweir $key =~ s/\s*=\s*$//; 1099cdf0e10cSrcweir } 1100cdf0e10cSrcweir else { 1101cdf0e10cSrcweir $attr{$key} = $tmp; 1102cdf0e10cSrcweir } 1103cdf0e10cSrcweir $is_key = !$is_key; 1104cdf0e10cSrcweir } 1105cdf0e10cSrcweir 1106cdf0e10cSrcweir if ( $element ne "" ) { 1107cdf0e10cSrcweir start_element( $element, %attr ); 1108cdf0e10cSrcweir } 1109cdf0e10cSrcweir} 1110cdf0e10cSrcweir 1111cdf0e10cSrcweir# Parse the file 1112cdf0e10cSrcweirsub parse( $ ) 1113cdf0e10cSrcweir{ 1114cdf0e10cSrcweir my ( $file ) = @_; 1115cdf0e10cSrcweir 1116cdf0e10cSrcweir my $in_comment = 0; 1117cdf0e10cSrcweir my $line = ""; 1118cdf0e10cSrcweir while (<$file>) { 1119cdf0e10cSrcweir # ignore comments 1120cdf0e10cSrcweir s/<\?[^>]*\?>//g; 1121cdf0e10cSrcweir s/<!--[^>]*-->//g; 1122cdf0e10cSrcweir if ( /<!--/ ) { 1123cdf0e10cSrcweir $in_comment = 1; 1124cdf0e10cSrcweir s/<!--.*//; 1125cdf0e10cSrcweir } 1126cdf0e10cSrcweir elsif ( /-->/ && $in_comment ) { 1127cdf0e10cSrcweir $in_comment = 0; 1128cdf0e10cSrcweir s/.*-->//; 1129cdf0e10cSrcweir } 1130cdf0e10cSrcweir elsif ( $in_comment ) { 1131cdf0e10cSrcweir next; 1132cdf0e10cSrcweir } 1133cdf0e10cSrcweir # ignore empty lines 1134cdf0e10cSrcweir chomp; 1135cdf0e10cSrcweir s/^\s*//; 1136cdf0e10cSrcweir s/\s*$//; 1137cdf0e10cSrcweir next if ( $_ eq "" ); 1138cdf0e10cSrcweir 1139cdf0e10cSrcweir # take care of lines where element continues 1140cdf0e10cSrcweir if ( $line ne "" ) { 1141cdf0e10cSrcweir $line .= " " . $_; 1142cdf0e10cSrcweir } 1143cdf0e10cSrcweir else { 1144cdf0e10cSrcweir $line = $_; 1145cdf0e10cSrcweir } 1146cdf0e10cSrcweir next if ( !/>$/ ); 1147cdf0e10cSrcweir 1148cdf0e10cSrcweir # the actual parsing 1149cdf0e10cSrcweir my @starts = split( /</, $line ); 1150cdf0e10cSrcweir $line = ""; 1151cdf0e10cSrcweir foreach $start ( @starts ) { 1152cdf0e10cSrcweir next if ( $start eq "" ); 1153cdf0e10cSrcweir 1154cdf0e10cSrcweir @ends = split( />/, $start ); 1155cdf0e10cSrcweir my $element = $ends[0]; 1156cdf0e10cSrcweir my $data = $ends[1]; 1157cdf0e10cSrcweir 1158cdf0e10cSrcweir # start or end element 1159cdf0e10cSrcweir if ( $element =~ /^\/(.*)/ ) { 1160cdf0e10cSrcweir end_element( $1 ); 1161cdf0e10cSrcweir } 1162cdf0e10cSrcweir elsif ( $element =~ /^(.*)\/$/ ) { 1163cdf0e10cSrcweir parse_start_element( $1 ); 1164cdf0e10cSrcweir ( my $end = $1 ) =~ s/\s.*$//; 1165cdf0e10cSrcweir end_element( $end ); 1166cdf0e10cSrcweir } 1167cdf0e10cSrcweir else { 1168cdf0e10cSrcweir parse_start_element( $element ); 1169cdf0e10cSrcweir } 1170cdf0e10cSrcweir 1171cdf0e10cSrcweir # the data 1172cdf0e10cSrcweir characters( $data ) if ( defined( $data ) && $data ne "" ); 1173cdf0e10cSrcweir } 1174cdf0e10cSrcweir } 1175cdf0e10cSrcweir} 1176cdf0e10cSrcweir 1177cdf0e10cSrcweir# Do the real work 1178cdf0e10cSrcweiropen( IN, "<$src_shapes" ) || die "Cannot open $src_shapes."; 1179cdf0e10cSrcweirparse( IN ); 1180cdf0e10cSrcweirclose( IN ); 1181cdf0e10cSrcweir 1182cdf0e10cSrcweiropen( IN, "<$src_text" ) || die "Cannot open $src_text."; 1183cdf0e10cSrcweirparse( IN ); 1184cdf0e10cSrcweirclose( IN ); 1185cdf0e10cSrcweir 1186cdf0e10cSrcweirif ( !defined( $result_shapes{'textBox'} ) ) { 1187cdf0e10cSrcweir $result_shapes{'textBox'} = 1188cdf0e10cSrcweir "<v:shapetype id=\"shapetype___ID__\" coordsize=\"21600,21600\" " . 1189cdf0e10cSrcweir "o:spt=\"__ID__\" path=\"m,l,21600l21600,21600l21600,xe\">\n" . 1190cdf0e10cSrcweir "<v:stroke joinstyle=\"miter\"/>\n" . 1191cdf0e10cSrcweir "<v:path gradientshapeok=\"t\" o:connecttype=\"rect\"/>\n" . 1192cdf0e10cSrcweir "</v:shapetype>"; 1193cdf0e10cSrcweir} 1194cdf0e10cSrcweir 1195cdf0e10cSrcweir# Generate the code 1196cdf0e10cSrcweirprint <<EOF; 1197cdf0e10cSrcweir// Shape types generated from 1198cdf0e10cSrcweir// '$src_shapes' 1199cdf0e10cSrcweir// and 1200cdf0e10cSrcweir// '$src_text' 1201cdf0e10cSrcweir// which are part of the OOXML documentation 1202cdf0e10cSrcweir 1203cdf0e10cSrcweir#include <svx/escherex.hxx> 1204cdf0e10cSrcweir 1205cdf0e10cSrcweirconst char* pShapeTypes[ ESCHER_ShpInst_COUNT ] = 1206cdf0e10cSrcweir{ 1207cdf0e10cSrcweirEOF 1208cdf0e10cSrcweir 1209cdf0e10cSrcweirfor ( $i = 0; $i < 203; ++$i ) { 1210cdf0e10cSrcweir if ( $i < 4 ) { 1211cdf0e10cSrcweir print " /* $i - $shapes_ids{$i} - handled separately */\n NULL,\n"; 1212cdf0e10cSrcweir } 1213cdf0e10cSrcweir else { 1214cdf0e10cSrcweir print " /* $i - $shapes_ids{$i} */\n"; 1215cdf0e10cSrcweir my $out = $result_shapes{$shapes_ids{$i}}; 1216cdf0e10cSrcweir if ( defined( $out ) ) { 1217cdf0e10cSrcweir # set the id 1218cdf0e10cSrcweir $out =~ s/__ID__/$i/g; 1219cdf0e10cSrcweir 1220cdf0e10cSrcweir # escape the '"'s 1221cdf0e10cSrcweir $out =~ s/"/\\"/g; 1222cdf0e10cSrcweir 1223cdf0e10cSrcweir # output as string 1224cdf0e10cSrcweir $out =~ s/^/ "/; 1225cdf0e10cSrcweir $out =~ s/\n/"\n "/g; 1226cdf0e10cSrcweir $out =~ s/$/"/; 1227cdf0e10cSrcweir 1228cdf0e10cSrcweir print "$out,\n"; 1229cdf0e10cSrcweir } 1230cdf0e10cSrcweir else { 1231cdf0e10cSrcweir print " NULL,\n"; 1232cdf0e10cSrcweir } 1233cdf0e10cSrcweir } 1234cdf0e10cSrcweir} 1235cdf0e10cSrcweir 1236cdf0e10cSrcweirprint <<EOF; 1237cdf0e10cSrcweir}; 1238cdf0e10cSrcweirEOF 1239