protected function createStyleList($style, &$elements = array()) { $styleList = new Media_SWF_Tag_DefineShape_StyleList(); $fillStyles = $style['FillStyles']['FillStyles']; $lineStyles = $style['LineStyles']['LineStyles']; $spreadMode = array('pad', 'reflect', 'repeat'); foreach ($fillStyles as $f) { if (isset($f['Color'])) { $svgFillStyle = Media_SVG::newElement('Path'); $svgFillStyle->set('fill', "#" . sprintf("%02x%02x%02x", $f['Color']['Red'], $f['Color']['Green'], $f['Color']['Blue'])); if (isset($f['Color']['Alpha'])) { $svgFillStyle->set('fill-opacity', $f['Color']['Alpha'] / 255); } } elseif (isset($f['Gradient'])) { $gradient = $f['Gradient']; $gid = sprintf("g_%s_%s", $this->characterId, count($elements)); $svgFillStyle = Media_SVG::newElement('Path'); $svgFillStyle->set('fill', "url(#{$gid})"); $g = Media_SVG::newElement($f['FillStyleType'] === 0x10 ? 'linearGradient' : 'radialGradient'); $g->set('id', $gid); $g->set('spreadMethod', $spreadMode[$gradient['SpreadMode']]); // TODO GradientMatrixの対応を実装 //$g->set('transform', Media_SWF_SVGUtill::matrixToSVGTransform($f['GradientMatrix'])); foreach ($gradient['GradientRecords'] as $gr) { $g->addNode(Media_SVG::newElement('stop')->set('offset', $gr['Ratio'] / 255 * 100 . "%")->set('stop-color', '#' . sprintf("%02x%02x%02x", $gr['Color']['Red'], $gr['Color']['Green'], $gr['Color']['Blue']))); } $elements[] = $g; } elseif (isset($f['BitmapId']) && $f['BitmapId'] !== 0xffff) { $id = $this->root->getTagByCharacterId($f['BitmapId'])->getElementIdString(); $svgFillStyle = Media_SVG::newElement('use')->set('href', "#{$id}")->set('transform', Media_SWF_SVGUtill::matrixToSVGTransform($f['BitmapMatrix'])); } else { $svgFillStyle = new Media_SVG_Null(); } $styleList->addFillStyle($svgFillStyle); } // fillStyles foreach ($lineStyles as $l) { $svgLineStyle = Media_SVG::newElement('Path')->set('fill', 'none'); if ($this->code !== Media_SWF_Tag::DEFINE_SHAPE4) { $svgLineStyle->set('stroke-linejoin', 'round')->set('stroke-linecap', 'round'); } if (isset($l['Color'])) { $svgLineStyle->set('stroke', '#' . sprintf("%02x%02x%02x", $l['Color']['Red'], $l['Color']['Green'], $l['Color']['Blue'])); if (isset($l['Color']['Alpha'])) { $svgLineStyle->set('stroke-opacity', $l['Color']['Alpha'] / 255); } } if (isset($l['Width'])) { $svgLineStyle->set('stroke-width', $l['Width']); } $styleList->addLineStyle($svgLineStyle); } // lineStyles return $styleList; }
public function convertSVG() { $id = $this->getElementIdString(); $svg = Media_SVG::newElement('Group'); $svg->set('id', $id); $frame = 0; $display_stack = array(); foreach ($this->_tags as $tag) { switch ($tag->getCode()) { case Media_SWF_Tag::PLACE_OBJECT: case Media_SWF_Tag::PLACE_OBJECT2: case Media_SWF_Tag::PLACE_OBJECT3: $depth = $tag->getField('Depth'); $characterId = $tag->getField('CharacterId'); if ($characterId) { $id = $this->root->getTagByCharacterId($characterId)->getElementIdString(); $node = Media_SVG::newElement('use'); $node->set('href', "url(#{$id})"); } else { $node = $display_stack[$depth]; } if ($tag->hasField('Matrix')) { $node->set('transform', Media_SWF_SVGUtill::matrixToSVGTransform($tag->getField('Matrix'))); } if ($tag->hasField('ColorTransform')) { $cxform = $tag->getField('ColorTransform'); if (isset($cxform['AlphaMultTerm'])) { $node->set('opacity', $cxform['AlphaMultTerm'] / 256); } } $display_stack[$depth] = $node; break; case Media_SWF_Tag::REMOVE_OBJECT: case Media_SWF_Tag::REMOVE_OBJECT2: // SVGでは何もしない $depth = $tag->getField('Depth'); unset($display_stack[$depth]); break; case Media_SWF_Tag::SHOW_FRAME: $frame++; ksort($display_stack); $f = Media_SVG::newElement('Group')->set('id', $id . '_f_' . $frame); foreach ($display_stack as $depth => $node) { $f->addNode(clone $node); } $svg->addNode($f); break 2; // SVGでは1フレームのみ } } return $svg; }