/** Converts the passed custom dash to API dash. rCustomDash should not be empty. *Weassume,thatthereexistonlytwolengthvaluesandthedistanceisthesame *foralldashes.Otherkindofdashstopsequencescannotberepresented,neither *inmodelnorinODF.
*/ void lclConvertCustomDash(LineDash& orLineDash, const LineProperties::DashStopVector& rCustomDash)
{
OSL_ASSERT(!rCustomDash.empty()); // Assume all dash stops have the same sp values.
orLineDash.Distance = rCustomDash[0].second; // First kind of dashes go to "Dots"
orLineDash.DotLen = rCustomDash[0].first;
orLineDash.Dots = 0; for(constauto& rIt : rCustomDash)
{ if (rIt.first != orLineDash.DotLen) break;
++orLineDash.Dots;
} // All others go to "Dashes", we cannot handle more than two kinds.
orLineDash.Dashes = rCustomDash.size() - orLineDash.Dots; if (orLineDash.Dashes > 0)
orLineDash.DashLen = rCustomDash[orLineDash.Dots].first; else
orLineDash.DashLen = 0;
// convert to API, e.g. 123% is 123000 in MS Office and 123 in our API
orLineDash.DotLen = orLineDash.DotLen / 1000;
orLineDash.DashLen = orLineDash.DashLen / 1000;
orLineDash.Distance = orLineDash.Distance / 1000;
}
DashStyle lclGetDashStyle( sal_Int32 nToken )
{
OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0); // MS Office dashing is always relative to line width switch( nToken )
{ case XML_rnd: return DashStyle_ROUNDRELATIVE; case XML_sq: return DashStyle_RECTRELATIVE; // default in OOXML case XML_flat: return DashStyle_RECTRELATIVE; // default in MS Office
} return DashStyle_RECTRELATIVE;
}
LineCap lclGetLineCap( sal_Int32 nToken )
{
OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0); switch( nToken )
{ case XML_rnd: return LineCap_ROUND; case XML_sq: return LineCap_SQUARE; // default in OOXML case XML_flat: return LineCap_BUTT; // default in MS Office
} return LineCap_BUTT;
}
LineJoint lclGetLineJoint( sal_Int32 nToken )
{
OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0); switch( nToken )
{ case XML_round: return LineJoint_ROUND; case XML_bevel: return LineJoint_BEVEL; case XML_miter: return LineJoint_MITER;
} return LineJoint_ROUND;
}
sal_Int32 lclGetArrowSize( sal_Int32 nToken )
{
OSL_ASSERT((nToken & sal_Int32(0xFFFF0000))==0); switch( nToken )
{ case XML_sm: return OOX_ARROWSIZE_SMALL; case XML_med: return OOX_ARROWSIZE_MEDIUM; case XML_lg: return OOX_ARROWSIZE_LARGE;
} return OOX_ARROWSIZE_MEDIUM;
}
void lclPushMarkerProperties( ShapePropertyMap& rPropMap, const LineArrowProperties& rArrowProps, sal_Int32 nLineWidth, bool bLineEnd )
{ /* Store the marker polygon and the marker name in a single value, to be
able to pass both to the ShapePropertyMap::setProperty() function. */
NamedValue aNamedMarker;
/* Test if the marker already exists in the marker table, do not createitagaininthiscase.Ifmarkersareinsertedexplicitly insteadbytheirname,thepolygonwillbecreatedalways.
TODO: this can be optimized by using a map. */ if( !rPropMap.hasNamedLineMarkerInTable( aMarkerName ) )
{ // pass X and Y as percentage to OOX_ARROW_POINT auto OOX_ARROW_POINT = [fArrowLength, fArrowWidth]( double x, double y ) { return awt::Point( static_cast< sal_Int32 >( fArrowWidth * x ), static_cast< sal_Int32 >( fArrowLength * y ) ); }; // tdf#100491 Arrow line marker, unlike other markers, depends on line width. // So calculate width of half line (more convenient during drawing) taking into account // further conversions/scaling done in OOX_ARROW_POINT and scaling to nMarkerWidth. constdouble fArrowLineHalfWidth = ::std::max< double >( 100.0 * 0.5 * nLineWidth / nMarkerWidth, 1 );
aNamedMarker.Name = aMarkerName;
aNamedMarker.Value <<= aMarkerCoords;
}
} else
{ /* Named marker object exists already in the marker table, pass itsnameonly.Thiswillsetthenameaspropertyvalue,but
does not create a new object in the marker table. */
aNamedMarker.Name = aMarkerName;
}
}
void LineProperties::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper& rGraphicHelper, ::Color nPhClr, sal_Int16 nPhClrTheme) const
{ // line fill type must exist, otherwise ignore other properties if( !maLineFill.moFillType.has_value() ) return;
// line style (our core only supports none and solid)
drawing::LineStyle eLineStyle = (maLineFill.moFillType.value() == XML_noFill) ? drawing::LineStyle_NONE : drawing::LineStyle_SOLID;
// line width in 1/100mm
sal_Int32 nLineWidth = getLineWidth(); // includes conversion from EMUs to 1/100mm
rPropMap.setProperty( ShapeProperty::LineWidth, nLineWidth );
// line cap type
LineCap eLineCap = moLineCap.has_value() ? lclGetLineCap( moLineCap.value() ) : LineCap_BUTT; if( moLineCap.has_value() )
rPropMap.setProperty( ShapeProperty::LineCap, eLineCap );
// create line dash from preset dash token or dash stop vector (not for invisible line) if( (eLineStyle != drawing::LineStyle_NONE) &&
((moPresetDash.has_value() && moPresetDash.value() != XML_solid) || !maCustomDash.empty()) )
{
LineDash aLineDash;
aLineDash.Style = lclGetDashStyle( moLineCap.value_or( XML_flat ) );
// In MS Office (2020) for preset dash style line caps round and square are included in dash length. // For custom dash style round line cap is included, square line cap is added. In ODF line caps are // always added to dash length. Tweak the length accordingly. if (eLineCap == LineCap_ROUND || (eLineCap == LineCap_SQUARE && maCustomDash.empty()))
{ // Cannot use -100 because that results in 0 length in some cases and // LibreOffice interprets 0 length as 100%. if (aLineDash.DotLen >= 100 || aLineDash.DashLen >= 100)
aLineDash.Distance += 99; if (aLineDash.DotLen >= 100)
aLineDash.DotLen -= 99; if (aLineDash.DashLen >= 100)
aLineDash.DashLen -= 99;
}
drawing::LineStyle LineProperties::getLineStyle() const
{ // rules to calculate the line style inferred from the code in LineProperties::pushToPropMap if (maLineFill.moFillType.value() == XML_noFill) return drawing::LineStyle_NONE; if ((moPresetDash.has_value() && moPresetDash.value() != XML_solid) ||
(!moPresetDash && !maCustomDash.empty())) return drawing::LineStyle_DASH; return drawing::LineStyle_SOLID;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.