예제 #1
0
bool XARGenerator::OutputPathEntity(const Style& style, const Transformation& trans, PathDataVector& pathVector)
{
	bool ok = true;
	CXaraFileRecord Rec(0);

	if (style.IsFillColourDefined() || style.IsFillGradientDefined()) {
		if (style.IsStrokeColourDefined())
			Rec.Reinit(TAG_PATH_FILLED_STROKED, TAG_PATH_SIZE);
		else
			Rec.Reinit(TAG_PATH_FILLED, TAG_PATH_SIZE);
	} else // if (style.IsStrokeColourDefined())
		Rec.Reinit(TAG_PATH_STROKED, TAG_PATH_SIZE);

	Rec.WriteUINT32(pathVector.GetCount());
	for (unsigned int i = 0; i < pathVector.GetCount(); ++i)
		Rec.WriteBYTE(pathVector[i].m_verb);
	for (unsigned int i = 0; i < pathVector.GetCount(); ++i) {
		PointD p = pathVector[i].m_coord;
		Rec.WriteCoord(DocCoord((INT32)p.x, m_docSize.y - (INT32)p.y));
	}
	ok = m_pExporter->WriteRecord(&Rec);

	RectD boundings = GetMaximumBoundings(pathVector);
	/***/ ok = m_pExporter->WriteZeroSizedRecord(TAG_DOWN);
	OutputStyles(style, trans, boundings, STYLE_FILL_ALL|STYLE_STROKE_ALL|STYLE_OPACITY);
	/***/ ok = m_pExporter->WriteZeroSizedRecord(TAG_UP);

	return ok;
}
예제 #2
0
bool XARGenerator::OutputPolygonEntity(const Style& style, const Transformation& trans, const PointDVector& coordVector)
{
	bool ok = true;
	CXaraFileRecord Rec(0);

	if (style.IsFillColourDefined() || style.IsFillGradientDefined()) {
		if (style.IsStrokeColourDefined())
			Rec.Reinit(TAG_PATH_FILLED_STROKED, TAG_PATH_SIZE);
		else
			Rec.Reinit(TAG_PATH_FILLED, TAG_PATH_SIZE);
	} else // if (style.IsStrokeColourDefined())
		Rec.Reinit(TAG_PATH_STROKED, TAG_PATH_SIZE);
	Rec.WriteUINT32(coordVector.GetCount());
	Rec.WriteBYTE(0x06); // moveto
	for (unsigned int i = 1; i < coordVector.GetCount() - 1; ++i)
		Rec.WriteBYTE(0x02); // lineto
	Rec.WriteBYTE(0x03); // lineto + closepath
	for (unsigned int i = 0; i < coordVector.GetCount(); ++i) {
		PointD p = coordVector[i];
		Rec.WriteCoord(DocCoord((INT32)p.x, m_docSize.y - (INT32)p.y));
	}
	ok = m_pExporter->WriteRecord(&Rec);

	RectD boundings = GetMaximumBoundings(coordVector);
	/***/ ok = m_pExporter->WriteZeroSizedRecord(TAG_DOWN);
	OutputStyles(style, trans, boundings, STYLE_FILL_ALL|STYLE_STROKE_ALL|STYLE_OPACITY);
	/***/ ok = m_pExporter->WriteZeroSizedRecord(TAG_UP);

	return ok;
}
예제 #3
0
bool XARGenerator::OutputStyles(const Style& style, const Transformation& trans, const RectD& boundings, UINT32 witch)
{
	bool ok = true;
	CXaraFileRecord Rec(0);

	wxString sXmlId = style.GetXmlId();
	if (!sXmlId.IsEmpty()) {
		// XXX how to output object labels in XAR?

#if SVGDEBUG
		svgtrace(DBGTRACE_SHAPES, "object id: %s\n", (const char *)sXmlId.mb_str(wxConvUTF8));
#endif
	}

	// XXX TODO to avoid XAR redundancy, we should look
	// if the styles we are outputting are already the default
	// in Xara's stack

	if (witch & STYLE_FILL_COLOUR) {
		if (style.IsFillColourDefined()) {
			wxColour col = style.GetFillColour();
			if (col.Ok()) {
				UINT32 iRecNo = DefineColour(col);

				Rec.Reinit(TAG_FLATFILL, TAG_FLATFILL_SIZE);
				ok = Rec.WriteReference(iRecNo);
				ok = m_pExporter->WriteRecord(&Rec);

#if SVGDEBUG
				svgtrace(DBGTRACE_STYLES, "fill colour %d,%d,%d\n", col.Red(), col.Green(), col.Blue());
#endif
			} else {
				m_pExporter->WriteZeroSizedRecord(TAG_FLATFILL_NONE);
#if SVGDEBUG
				svgtrace(DBGTRACE_STYLES, "no fill colour\n");
#endif
			}
		} else if (!style.IsFillGradientDefined()) {
			m_pExporter->WriteZeroSizedRecord(TAG_FLATFILL_NONE);
#if SVGDEBUG
			svgtrace(DBGTRACE_STYLES, "no fill colour\n");
#endif
		}
	}

	if (witch & STYLE_FILL_GRADIENT && style.IsFillGradientDefined()) {
		Gradient* pGradient = style.GetFillGradient();

		if (pGradient->type == Gradient::Linear) {
			OutputFillLinearGradient(style, trans, boundings);
		} else if (pGradient->type == Gradient::Radial) {
			OutputFillRadialGradient(style, trans, boundings);
		}
	}

	if (witch & STYLE_FILL_OPACITY && style.IsFillOpacityDefined()) {
		double opacity = style.GetFillOpacity();
		if (opacity < 1.0) {
			BYTE bOpacity = (BYTE)((1.0-opacity)*255.0);

			Rec.Reinit(TAG_FLATTRANSPARENTFILL, TAG_FLATTRANSPARENTFILL_SIZE);
			ok = Rec.WriteBYTE(bOpacity);
			ok = Rec.WriteBYTE(0x01);
			ok = m_pExporter->WriteRecord(&Rec);
		}
	}

	if (witch & STYLE_STROKE_COLOUR) {
		if (style.IsStrokeColourDefined()) {
			wxColour col = style.GetStrokeColour();
			if (col.Ok()) {
				UINT32 iRecNo = DefineColour(col);

				Rec.Reinit(TAG_LINECOLOUR, TAG_LINECOLOUR_SIZE);
				ok = Rec.WriteReference(iRecNo);
				ok = m_pExporter->WriteRecord(&Rec);

#if SVGDEBUG
				svgtrace(DBGTRACE_STYLES, "stroke colour %d,%d,%d\n", col.Red(), col.Green(), col.Blue());
#endif
			} else {
				m_pExporter->WriteZeroSizedRecord(TAG_LINECOLOUR_NONE);
#if SVGDEBUG
				svgtrace(DBGTRACE_STYLES, "no stroke colour\n");
#endif
			}
		} else {
			m_pExporter->WriteZeroSizedRecord(TAG_LINECOLOUR_NONE);
#if SVGDEBUG
			svgtrace(DBGTRACE_STYLES, "no stroke colour\n");
#endif
		}
	}

	if (witch & STYLE_STROKE_WIDTH && style.IsStrokeWidthDefined()) {
		UINT32 iStrokeWidth = style.GetStrokeWidth();
		Rec.Reinit(TAG_LINEWIDTH, TAG_LINEWIDTH_SIZE);
		ok = Rec.WriteINT32(iStrokeWidth);
		ok = m_pExporter->WriteRecord(&Rec);
	}

	if (witch & STYLE_STROKE_LINEJOIN )
	{
		JointType jt;
		if (style.IsStrokeLineJoinDefined()) {
			jt=style.GetStrokeLineJoin();

#if SVGDEBUG
			switch(jt)
			{
				case MitreJoin:
					svgtrace(DBGTRACE_STYLES, "stroke join mitre\n");
				break;
				case BevelledJoin:
					svgtrace(DBGTRACE_STYLES, "stroke join bevel\n");
				break;
				case RoundJoin:
					svgtrace(DBGTRACE_STYLES, "stroke join round\n");
				break;
			}
#endif
		} else {
			jt=MitreJoin;

#if SVGDEBUG
			svgtrace(DBGTRACE_STYLES, "no stroke specified, using mitre\n");
#endif

		}

		Rec.Reinit(TAG_JOINSTYLE, TAG_JOINSTYLE_SIZE);
		ok = Rec.WriteBYTE(BYTE(jt));
		ok = m_pExporter->WriteRecord(&Rec);

	}

	if (witch & STYLE_STROKE_LINECAP && style.IsStrokeLineCapDefined()) {
		LineCapType lct=style.GetStrokeLineCap();
		Rec.Reinit(TAG_STARTCAP, TAG_STARTCAP_SIZE);
		ok = Rec.WriteBYTE(BYTE(lct));
		ok = m_pExporter->WriteRecord(&Rec);

		Rec.Reinit(TAG_ENDCAP, TAG_ENDCAP_SIZE);
		ok = Rec.WriteBYTE(BYTE(lct));
		ok = m_pExporter->WriteRecord(&Rec);

#if SVGDEBUG
		switch(lct)
		{
			case LineCapButt:
				svgtrace(DBGTRACE_STYLES, "stroke cap butt\n");
			break;
			case LineCapRound:
				svgtrace(DBGTRACE_STYLES, "stroke cap round\n");
			break;
			case LineCapSquare:
				svgtrace(DBGTRACE_STYLES, "stroke cap square\n");
			break;
		}
#endif

	}

	if (witch & STYLE_STROKE_OPACITY && style.IsStrokeOpacityDefined()) {
		double opacity = style.GetStrokeOpacity();
		if (opacity < 1.0) {
			BYTE bOpacity = (BYTE)((1.0-opacity)*255.0);
			Rec.Reinit(TAG_LINETRANSPARENCY, TAG_LINETRANSPARENCY_SIZE);
			ok = Rec.WriteBYTE(bOpacity);
			ok = Rec.WriteBYTE(0x01); // mix
			ok = m_pExporter->WriteRecord(&Rec);
		}
	}

	if (witch & STYLE_OPACITY && style.IsOpacityDefined()) {
		double fOpacity = style.GetOpacity();
		if (fOpacity < 1.0) {
			double fFillOpacity = fOpacity;
			double fStrokeOpacity = fOpacity;

			if (style.IsFillOpacityDefined())
				fFillOpacity *= style.GetFillOpacity();
			if (style.IsStrokeOpacityDefined())
				fStrokeOpacity *= style.GetStrokeOpacity();

			BYTE bFillOpacity   = (BYTE)((1.0-fFillOpacity)*255.0);
			BYTE bStrokeOpacity = (BYTE)((1.0-fStrokeOpacity)*255.0);

			Rec.Reinit(TAG_FLATTRANSPARENTFILL, TAG_FLATTRANSPARENTFILL_SIZE);
			ok = Rec.WriteBYTE(bFillOpacity);
			ok = Rec.WriteBYTE(0x01); // mix
			ok = m_pExporter->WriteRecord(&Rec);
			Rec.Reinit(TAG_LINETRANSPARENCY, TAG_LINETRANSPARENCY_SIZE);
			ok = Rec.WriteBYTE(bStrokeOpacity);
			ok = Rec.WriteBYTE(0x01); // mix
			ok = m_pExporter->WriteRecord(&Rec);
		}
	}

	return ok;
}