PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/svg/charge.inc

http://drawshield.googlecode.com/
PHP | 184 lines | 145 code | 14 blank | 25 comment | 32 complexity | f401b0225de839cf2100c6c36d129c41 MD5 | raw file
  1. <?php /* Copyright 2010 Karl R. Wilcox
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License. */
  11. $chg_data_cache = array();
  12. function get_chg_data() {
  13. global $dom;
  14. global $chg_data_cache;
  15. $xpath = new DOMXPath($dom);
  16. foreach ( $xpath->query("//charge") as $chg ) {
  17. $chg_ref = unique('chg');
  18. $chg_data_cache[$chg_ref] = read_chg_file($chg);
  19. // Add a modifier to link to the cached charge data
  20. $chg->appendChild(make_mod('chg_data', $chg_ref ));
  21. }
  22. }
  23. function read_chg_file($node) {
  24. if ( $node->nodeName == 'missing' ) {
  25. $title = 'missing';
  26. $chg_data = array();
  27. } else {
  28. $charge_key = 'charges/' . $node->getAttribute('type') . '/' . $node->getAttribute('subtype');
  29. if ( ($title = $node->getAttribute('tokens')) == null ) $title = $node->getAttribute('subtype');
  30. $chg_data = includeCharge( $node, $charge_key );
  31. if ( array_key_exists('file', $chg_data )) { // Need to extract body and features from inkscape file
  32. $chg_data = array_merge_recursive($chg_data, ink2chg('charges/' . $node->getAttribute('type') . '/' . $chg_data['file']));
  33. }
  34. }
  35. if ( !array_key_exists('body', $chg_data) ) {
  36. draw_message('internal',"Cannot draw $title");
  37. $chg_data = array ( 'width' => 100, 'height' => 100,
  38. 'body' => '<g stroke="none"><path fill-rule="evenodd" d="M0,0h100v100h-100zM10,10h80v80h-80z" />' .
  39. '<text x="50" y="55" font-size="15" text-anchor="middle">' . $title . '</text></g>',
  40. 'wflex' => 2, 'hflex' => 2 );
  41. }
  42. if ( array_key_exists('licence', $chg_data) and $chg_data['licence'] != null ) {
  43. $title .= ': ' . $chg_data['licence'];
  44. draw_message('licence', $title);
  45. }
  46. $chg_data['title'] = $title;
  47. return $chg_data;
  48. }
  49. function makeCharge($charge) {
  50. $placements = get_placement($charge);
  51. $retval = '';
  52. foreach ( explode('*',$placements) as $placement ) {
  53. $retval .= place_charges ( $charge, $placement );
  54. }
  55. return $retval;
  56. }
  57. function includeCharge( $node, $charge_key ) {
  58. $charge = array ();
  59. include ( $charge_key . '.inc' );
  60. return $charge;
  61. }
  62. function getCharge( $node ) {
  63. global $chg_data_cache;
  64. $chg_ref = get_mod($node, 'chg_data');
  65. if ( !array_key_exists($chg_ref, $chg_data_cache) )
  66. $chg_data = read_chg_file($node);
  67. else
  68. $chg_data = $chg_data_cache[$chg_ref];
  69. $body = $chg_data['body'];
  70. // Process charge features and modifiers
  71. $charges_on = null;
  72. $feat_cols = array();
  73. $charge_col = null;
  74. $demi = null;
  75. $charge_is_proper = false;
  76. foreach ( $node->childNodes as $child ) {
  77. switch ( $child->nodeName ) {
  78. case 'feature':
  79. $feat_cols[$child->getAttribute('name')] = $child->firstChild;
  80. break;
  81. case 'tincture':
  82. $charge_col = $child;
  83. break;
  84. case 'modifier':
  85. switch ($child->getAttribute('name')) {
  86. case 'demi':
  87. $demi = true;
  88. break;
  89. case 'charged-with':
  90. $charges_on = $child->firstChild;
  91. break;
  92. }
  93. break;
  94. }
  95. }
  96. $col_type = $charge_col->firstChild;
  97. if ( $col_type->nodeName == 'default' and array_key_exists('default', $chg_data) ) {
  98. $col_type->setAttribute('spec', $chg_data['default']);
  99. }
  100. // Apply proper colour (if there is one)
  101. if ( $col_type->nodeName == 'proper' and array_key_exists('proper', $chg_data) )
  102. {
  103. $col_type->setAttribute('spec', $chg_data['proper']);
  104. $charge_is_proper = true;
  105. }
  106. // Apply colours to features and append to the body
  107. if ( array_key_exists('features',$chg_data) and count($chg_data['features']) > 0 ) {
  108. foreach ( array_reverse($chg_data['features']) as $key => $data ) {
  109. if ( !array_key_exists('body', $data) ) $data['body'] = '<g />';
  110. // Find if there is a proper colour
  111. if ( array_key_exists('proper', $data) )
  112. $proper_spec = $data['proper'];
  113. elseif ( array_key_exists('proper', $chg_data) )
  114. $proper_spec = $chg_data['proper'];
  115. // if ( ! array_key_exists('body', $data) ) continue; // No body, so no colour to apply
  116. if ( array_key_exists($key, $feat_cols) and ($feat_col = $feat_cols[$key]) != null ) { // we have an explicitly coloured feature
  117. $col_type = $feat_col->firstChild;
  118. if ( $col_type->nodeName == 'proper' ) $col_type->setAttribute('spec', $proper_spec);
  119. $feature = apply_tincture( $feat_col, $data['body'] );
  120. } else { // colour not given in blazon
  121. if ( array_key_exists('notpresent', $data) and !array_key_exists($key,$feat_cols) ) {
  122. $feature= $data['notpresent']; // Use the notpresent data
  123. } elseif ( array_key_exists('colour', $data )) {
  124. // if given, use a default colour
  125. $feature= '<g fill="' . $data['colour'] . '">' . $data['body'] . '</g>';
  126. } elseif ( $charge_is_proper and array_key_exists('proper', $data )) {
  127. // if given, use a proper colour
  128. $feature= '<g fill="' . $data['proper'] . '">' . $data['body'] . '</g>';
  129. } else {
  130. // else just add the feature to the main body
  131. $feature= $data['body'];
  132. }
  133. }
  134. if ( array_key_exists('behind', $data ))
  135. $body = $feature . $body;
  136. else
  137. $body .= $feature;
  138. }
  139. }
  140. if ( $demi!= null ) {
  141. if ( array_key_exists('demi', $chg_data) and $chg_data['demi'] == 'top' ) {
  142. $half = $chg_data['height'] / 2;
  143. $clip = add_def ( 'clipPath', '<rect x="0" y="0" width="' . $chg_data['width'] . '" height="' . $half . '" />' );
  144. $body = '<g clip-path="url(#' . $clip . ')">' . $body . '</g>';
  145. $chg_data['height'] = $half;
  146. } else {
  147. $half = $chg_data['width'] / 2;
  148. $clip = add_def ( 'clipPath', '<rect x="0" y="0" width="' . $half . '" height="' . $chg_data['height'] . '" />' );
  149. $body = '<g clip-path="url(#' . $clip . ')">' . $body . '</g>';
  150. $chg_data['width'] = $half;
  151. }
  152. }
  153. if ( $charges_on ) {
  154. // Turn off flexible scaling (as on charges could be distorted by flexing) ???
  155. // $chg_data['hflex'] = $chg_data['wflex'] = 1;
  156. $scale = min ( $chg_data['width']/1000, $chg_data['height']/1000);
  157. $charges = makeCharge($charges_on);
  158. // scale to fit onto charge - then move so charges are central
  159. $charges = sprintf('<g transform="translate(%2f,%2f) scale(%4f)">%s</g>', (($chg_data['width']/2)-(1000*$scale)/2), (($chg_data['height']/2)-(1000*$scale)/2),
  160. $scale, $charges);
  161. $body .= $charges;
  162. }
  163. // Set the stroke colour for all charges
  164. $chg_data['body'] = '<g stroke="#696969">' . $body . '</g>';
  165. return $chg_data;
  166. }
  167. ?>