Пример #1
0
  void
  SVGStylable::pickTraverse(svgl::Context * svglContext, svgl::GLInfo* glinfo)
  {

    const css::CSSStyleDeclaration& style = getStyle().getValue();

    const css::Color * fill = style.getFill();
    const css::Color * stroke = style.getStroke();
    svg::SVGLength strokeWidth = style.getStrokeWidth();
    float sw = svglContext->computeWidthLength(strokeWidth);
    SVGElement * e = dynamic_cast<SVGElement*>(this);
    if(!e) {
      std::cerr << "SVGStylable must be an SVGElement in pickTraverse" __FL__;
      return;
    }

    //FIXME
    if(fill==css::Color::getNoneColor())
      fill = 0; // as if it wasn't there...
    if(stroke==css::Color::getNoneColor())
      stroke = 0; // as if it wasn't there...

		computeGeometryForDrawing(svglContext,glinfo);
		
    dom::Document * currentDoc = e->getOwnerDocument();

    svg::SVGClipPathElement *clippath_element=0;
    clippath_element = getSVGClipPathElement(svglContext->externalEntityManager, currentDoc);
    if(clippath_element)
      clippath_element->pickTraverse(svglContext, glinfo);

    glinfo->pushPickInfo(e);
    if(fill) {
      glTraverseFill(svglContext, glinfo);
    }
    if(stroke) {
      glTraverseStroke(svglContext, glinfo, sw);
    }
    glinfo->popPickInfo();
  }
Пример #2
0
  void
  SVGStylable::glTraverse(svgl::Context * svglContext,
			  svgl::GLInfo* glinfo,
			  bool stencilStrokeHint,
			  bool traverseEvenIfNonVisible)
  {

    const css::CSSStyleDeclaration& style = GET_SIMPLE_VAL(Style);

    const css::Color * fill = style.getFill();
    const css::Color * stroke = style.getStroke();
    float fillOpacity = style.getFillOpacity();
    float strokeOpacity = style.getStrokeOpacity();
    float opacity = style.getOpacity();
    svg::SVGLength strokeWidth = style.getStrokeWidth();
    float sw = svglContext->computeWidthLength(strokeWidth);
    css::CSSStyle::DisplayType display = style.getDisplay();
		
		//FIXME
    if(fill==css::Color::getNoneColor())
      fill = 0; // as if it wasn't there...
    if(stroke==css::Color::getNoneColor())
      stroke = 0; // as if it wasn't there...

    if(!display) {
      return;
    }

		computeGeometryForDrawing(svglContext,glinfo);
		
    SVGElement * meAsElement = dynamic_cast<SVGElement*>(this);
    dom::Document * currentDoc = meAsElement->getOwnerDocument();

    svg::SVGClipPathElement *clippath_element=0;
    clippath_element = getSVGClipPathElement(svglContext->externalEntityManager, currentDoc);
    if(clippath_element) {
      clippath_element->glPreTraverse(svglContext, glinfo);
    }

    SVGFilterElement* filter_element = 0;
#if 1
    filter_element = getSVGFilterElement(svglContext->externalEntityManager, currentDoc);
    if(filter_element)
      filter_element->glPreTraverse(svglContext, glinfo, dynamic_cast<SVGElement*>(this));
#endif

    if(fill && stroke && opacity<1) {
      glTraverseOpacity(svglContext,
			glinfo,
			fill,
			stroke,
			fillOpacity,
			strokeOpacity,
			opacity,
			sw,
			stencilStrokeHint
			//,
			//bbx,bby,bbwidth,bbheight
			);
    }
    else {
      float alpha_save = glinfo->alpha;
      glinfo->alpha *= opacity;

#define AA 1

#if AA
//#define AA_PRIMITIVE GL_POLYGON_SMOOTH
//#define AA_PRIMITIVE GL_MULTISAMPLE_ARB
#define AA_PRIMITIVE glinfo->aa_primitive
#define AA_PRIMITIVE_HINT GL_POLYGON_SMOOTH_HINT
#endif

      if(fill) {
	float alpha_save = glinfo->alpha;
	glinfo->alpha *= fillOpacity;

	fill->glPreTraverse(svglContext, glinfo, this);
	if(!stroke && glinfo->doAntiAliasing()) {
	  bool opaque = false;
	  if(glinfo->alpha==1) opaque = true;
	  glinfo->enableAntiAliasing(opaque);
	}

	glTraverseFill(svglContext, glinfo);
	fill->glPostTraverse(svglContext, glinfo, this);

	if(!stroke && glinfo->doAntiAliasing()) {
	  glinfo->disableAntiAliasing();
	}
	glinfo->alpha = alpha_save;
      }

      if(stroke && sw > 0) {
	float alpha_save = glinfo->alpha;
	float swon2 = sw/2.;
	float bbx,bby,bbwidth,bbheight;

	stencilStrokeHint=1;
	if(stencilStrokeHint && strokeOpacity<1) {
	  // since stroke pathes may recover themselves (think "8") , we must use stencil
#if 1
	  glinfo->stencilEnableTopAndPush();
#else
	  glinfo->stencilEnableTest();
	  int& stencil = glinfo->stencil;
	  glStencilFunc(GL_EQUAL, stencil, static_cast<GLuint>(-1));
	  glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
	  ++stencil;
#endif
	}

	glinfo->alpha *= strokeOpacity;
	stroke->glPreTraverse(svglContext, glinfo, this, sw);

	if(glinfo->doAntiAliasing()) {
	  bool opaque = false;
	  if(glinfo->alpha==1) opaque = true;
	  glinfo->enableAntiAliasing(opaque);
	}

	glTraverseStroke(svglContext, glinfo, sw);

	if(glinfo->doAntiAliasing()) {
	  glinfo->disableAntiAliasing();
	}

	// remove stencil
	if(stencilStrokeHint && strokeOpacity<1) {
	  // FIXME, not necessary if stroke is a gradient...
	  // not sure though...
	  getBoundingBox(svglContext, glinfo, &bbx, &bby, &bbwidth, &bbheight);
	  glinfo->stencilPop();
	  glBegin(GL_QUAD_STRIP);
	  glVertex2f(bbx-swon2,bby-swon2);
	  glVertex2f(bbx-swon2, bby+bbheight+sw);
	  glVertex2f(bbx+bbwidth+sw, bby-swon2);
	  glVertex2f(bbx+bbwidth+sw, bby+bbheight+sw);
	  glEnd();
	  glinfo->stencilEnableTop();
	}

	stroke->glPostTraverse(svglContext, glinfo, this, sw);
	glinfo->alpha = alpha_save;
	
	

#if AA
#undef AA_PRIMITIVE
#undef AA_PRIMITIVE_HINT
#undef AA
#endif
      }

      glinfo->alpha = alpha_save;
    }

    SVGStylable::glTraverseMarker(svglContext, glinfo, sw);

    if(filter_element) {
      filter_element->glPostTraverse(svglContext, glinfo, dynamic_cast<SVGElement*>(this));
    }

    if(clippath_element) {
      clippath_element->glPostTraverse(svglContext, glinfo);
    }

#if 0
		// draw bbox
		//if(glinfo->_has_GL_ARB_imaging) {
		if(1) {
			float swon2 = sw/2.;
			float bbx,bby,bbwidth,bbheight;
			getBoundingBox(svglContext, glinfo, &bbx, &bby, &bbwidth, &bbheight);

			glinfo->stencilDisableTest();
			glColor4d(0,0,0,1);
			glBegin(GL_LINE_LOOP);
			glVertex2f(bbx-swon2,bby-swon2);
			glVertex2f(bbx-swon2, bby+bbheight+swon2);
			glVertex2f(bbx+bbwidth+swon2, bby+bbheight+swon2);
			glVertex2f(bbx+bbwidth+swon2, bby-swon2);
			glEnd();
			glinfo->stencilEnableTest();
		}
		// --
#endif
		

  }
Пример #3
0
  void
  SVGStylable::glTraverseMarker(svgl::Context* svglContext, svgl::GLInfo* glinfo, float shapeStrokeWidth)
  {
    SVGElement * meAsElement = dynamic_cast<SVGElement*>(this);
    dom::Document * currentDoc = meAsElement->getOwnerDocument();
    SVGMarkerElement* marker = getSVGMarkerElement(svglContext->externalEntityManager, currentDoc);
    SVGMarkerElement *marker_start=marker, *marker_end=marker, *marker_mid=marker;
    marker_start = getSVGMarkerStartElement(svglContext->externalEntityManager, currentDoc);
    marker_end = getSVGMarkerEndElement(svglContext->externalEntityManager, currentDoc);
    marker_mid = getSVGMarkerMidElement(svglContext->externalEntityManager, currentDoc);

    if( !(marker || marker_start || marker_end || marker_mid) )
      return;

    BezierPath bezierpath;
    asBezier(svglContext, glinfo, &bezierpath);

#if 0
    SVGStylable* stylable = dynamic_cast<SVGStylable*>(shape);
    if(!stylable) {
      std::cerr << "unstylable referring shape for marker " __FL__;
      return;
    }
#endif
    
    SVGStylable* stylable = this;

    if(!marker_start) {
      marker_start=marker;
    } else {
      css::CSSStyleDeclaration& style = marker_start->getStyle().getValue();
      style.setParent(stylable->getStyle().getValue().getParent());
    }

    if(!marker_end) {
      marker_end=marker;
    } else {
      css::CSSStyleDeclaration& style = marker_end->getStyle().getValue();
      style.setParent(stylable->getStyle().getValue().getParent());
    }

    if(!marker_mid) {
      marker_mid=marker;
    } else {
      css::CSSStyleDeclaration& style = marker_mid->getStyle().getValue();
      style.setParent(stylable->getStyle().getValue().getParent());
    }

    if(marker) {
      css::CSSStyleDeclaration& style = marker->getStyle().getValue();
      style.setParent(stylable->getStyle().getValue().getParent());
    }
    
    marker=0;


    glPushMatrix();
    for (BezierPath::const_iterator i = bezierpath.begin();
	 i!=bezierpath.end();
	 ++i) {

      if(marker)
	marker->glTraverseFromUse(svglContext, glinfo, shapeStrokeWidth, 0);

      switch ( (*i).type() ) {

      case BezierPath::move: {
	const BezierPath::Point& p0 = (*i)[0];
	glTranslatef(p0.x(), p0.y(), 0);
	marker = marker_start;
      }
      break;

      case BezierPath::line: {
	const BezierPath::Point& p0 = (*i)[0];
	const BezierPath::Point& p1 = (*i)[1];
	BezierPath::Coord dx = p1.x()-p0.x();
	BezierPath::Coord dy = p1.y()-p0.y();
	glTranslatef(dx, dy, 0);
	marker = marker_mid;
      }
      break;
      
      case BezierPath::close: {
	const BezierPath::Point& p0 = (*i)[0];
	const BezierPath::Point& p1 = (*i)[1];
	BezierPath::Coord dx = p1.x()-p0.x();
	BezierPath::Coord dy = p1.y()-p0.y();
	glTranslatef(dx, dy, 0);
	marker = marker_end;
      }
      break;
      default:
	STDDBG;
	break;
      }
    }

    marker=marker_end;
    if(marker)
      marker->glTraverseFromUse(svglContext, glinfo, shapeStrokeWidth, 0);

    glPopMatrix();
  }