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; }
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; }
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; }