calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / editeng / source / items / borderline.cxx
blob05742eb95131e78bf42e994a601745dcae292f4e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <algorithm>
24 #include <basegfx/color/bcolor.hxx>
25 #include <basegfx/color/bcolortools.hxx>
27 #include <editeng/borderline.hxx>
28 #include <editeng/itemtype.hxx>
29 #include <editeng/editrids.hrc>
30 #include <editeng/eerdll.hxx>
31 #include <tools/bigint.hxx>
33 #include <docmodel/uno/UnoComplexColor.hxx>
34 #include <com/sun/star/util/XComplexColor.hpp>
36 using namespace ::com::sun::star::table::BorderLineStyle;
37 using namespace css;
39 // class SvxBorderLine --------------------------------------------------
41 namespace {
43 Color lcl_compute3DColor( Color aMain, int nLight, int nMedium, int nDark )
45 basegfx::BColor color = aMain.getBColor( );
46 basegfx::BColor hsl = basegfx::utils::rgb2hsl( color );
48 int nCoef = 0;
49 if ( hsl.getZ( ) >= 0.5 )
50 nCoef = nLight;
51 else if ( 0.5 > hsl.getZ() && hsl.getZ() >= 0.25 )
52 nCoef = nMedium;
53 else
54 nCoef = nDark;
56 double L = std::min(hsl.getZ() * 255.0 + nCoef, 255.0);
57 hsl.setZ( L / 255.0 );
58 color = basegfx::utils::hsl2rgb( hsl );
60 return Color( color );
62 } // Anonymous namespace
64 namespace editeng
67 bool SvxBorderLine::setComplexColorFromAny(css::uno::Any const& rValue)
69 css::uno::Reference<css::util::XComplexColor> xComplexColor;
70 if (!(rValue >>= xComplexColor))
71 return false;
73 if (xComplexColor.is())
75 auto aComplexColor = model::color::getFromXComplexColor(xComplexColor);
76 setComplexColor(aComplexColor);
78 return true;
81 Color SvxBorderLine::darkColor( Color aMain )
83 return aMain;
86 Color SvxBorderLine::lightColor( Color aMain )
89 // Divide Luminance by 2
90 basegfx::BColor color = aMain.getBColor( );
91 basegfx::BColor hsl = basegfx::utils::rgb2hsl( color );
92 hsl.setZ( hsl.getZ() * 0.5 );
93 color = basegfx::utils::hsl2rgb( hsl );
95 return Color( color );
99 Color SvxBorderLine::threeDLightColor( Color aMain )
101 // These values have been defined in an empirical way
102 return lcl_compute3DColor( aMain, 3, 40, 83 );
105 Color SvxBorderLine::threeDDarkColor( Color aMain )
107 // These values have been defined in an empirical way
108 return lcl_compute3DColor( aMain, -85, -43, -1 );
111 Color SvxBorderLine::threeDMediumColor( Color aMain )
113 // These values have been defined in an empirical way
114 return lcl_compute3DColor( aMain, -42, -0, 42 );
117 SvxBorderLine::SvxBorderLine( const Color *pCol, tools::Long nWidth,
118 SvxBorderLineStyle nStyle,
119 Color (*pColorOutFn)( Color ), Color (*pColorInFn)( Color ) )
120 : m_nWidth(nWidth)
121 , m_nMult(1)
122 , m_nDiv(1)
123 , m_pColorOutFn(pColorOutFn)
124 , m_pColorInFn(pColorInFn)
125 , m_pColorGapFn(nullptr)
126 , m_aWidthImpl(SvxBorderLine::getWidthImpl(nStyle))
127 , m_nStyle(nStyle)
128 , m_bMirrorWidths(false)
129 , m_bUseLeftTop(false)
131 if (pCol)
132 m_aColor = *pCol;
135 SvxBorderLineStyle
136 ConvertBorderStyleFromWord(int const nWordLineStyle)
138 switch (nWordLineStyle)
140 // First the single lines
141 case 1:
142 case 2: // thick line
143 case 5: // hairline
144 // and the unsupported special cases which we map to a single line
145 case 20:
146 return SvxBorderLineStyle::SOLID;
147 case 6:
148 return SvxBorderLineStyle::DOTTED;
149 case 7:
150 return SvxBorderLineStyle::DASHED;
151 case 22:
152 return SvxBorderLineStyle::FINE_DASHED;
153 case 8:
154 return SvxBorderLineStyle::DASH_DOT;
155 case 9:
156 return SvxBorderLineStyle::DASH_DOT_DOT;
157 // then the shading beams which we represent by a double line
158 case 23:
159 return SvxBorderLineStyle::DOUBLE;
160 // then the double lines, for which we have good matches
161 case 3:
162 case 10: // Don't have triple so use double
163 case 21: // Don't have double wave: use double instead
164 return SvxBorderLineStyle::DOUBLE;
165 case 11:
166 return SvxBorderLineStyle::THINTHICK_SMALLGAP;
167 case 12:
168 case 13: // Don't have thin thick thin, so use thick thin
169 return SvxBorderLineStyle::THICKTHIN_SMALLGAP;
170 case 14:
171 return SvxBorderLineStyle::THINTHICK_MEDIUMGAP;
172 case 15:
173 case 16: // Don't have thin thick thin, so use thick thin
174 return SvxBorderLineStyle::THICKTHIN_MEDIUMGAP;
175 case 17:
176 return SvxBorderLineStyle::THINTHICK_LARGEGAP;
177 case 18:
178 case 19: // Don't have thin thick thin, so use thick thin
179 return SvxBorderLineStyle::THICKTHIN_LARGEGAP;
180 case 24:
181 return SvxBorderLineStyle::EMBOSSED;
182 case 25:
183 return SvxBorderLineStyle::ENGRAVED;
184 case 26:
185 return SvxBorderLineStyle::OUTSET;
186 case 27:
187 return SvxBorderLineStyle::INSET;
188 default:
189 return SvxBorderLineStyle::NONE;
193 const double THINTHICK_SMALLGAP_line2 = 15.0;
194 const double THINTHICK_SMALLGAP_gap = 15.0;
195 const double THINTHICK_LARGEGAP_line1 = 30.0;
196 const double THINTHICK_LARGEGAP_line2 = 15.0;
197 const double THICKTHIN_SMALLGAP_line1 = 15.0;
198 const double THICKTHIN_SMALLGAP_gap = 15.0;
199 const double THICKTHIN_LARGEGAP_line1 = 15.0;
200 const double THICKTHIN_LARGEGAP_line2 = 30.0;
201 const double OUTSET_line1 = 15.0;
202 const double INSET_line2 = 15.0;
204 double
205 ConvertBorderWidthFromWord(SvxBorderLineStyle const eStyle, double const i_fWidth,
206 int const nWordLineStyle)
208 // fdo#68779: at least for RTF, 0.75pt is the default if width is missing
209 double const fWidth((i_fWidth == 0.0) ? 15.0 : i_fWidth);
210 switch (eStyle)
212 // Single lines
213 case SvxBorderLineStyle::SOLID:
214 switch (nWordLineStyle)
216 case 2:
217 return (fWidth * 2.0); // thick
218 case 5: // fdo#55526: map 0 hairline width to > 0
219 return std::max(fWidth, 1.0);
220 default:
221 return fWidth;
223 break;
225 case SvxBorderLineStyle::DOTTED:
226 case SvxBorderLineStyle::DASHED:
227 case SvxBorderLineStyle::DASH_DOT:
228 case SvxBorderLineStyle::DASH_DOT_DOT:
229 return fWidth;
231 // Display a minimum effective border width of 1pt
232 case SvxBorderLineStyle::FINE_DASHED:
233 return (fWidth > 0 && fWidth < 20) ? 20 : fWidth;
235 // Double lines
236 case SvxBorderLineStyle::DOUBLE:
237 return fWidth * 3.0;
239 case SvxBorderLineStyle::THINTHICK_MEDIUMGAP:
240 case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP:
241 case SvxBorderLineStyle::EMBOSSED:
242 case SvxBorderLineStyle::ENGRAVED:
243 return fWidth * 2.0;
245 case SvxBorderLineStyle::THINTHICK_SMALLGAP:
246 return fWidth + THINTHICK_SMALLGAP_line2 + THINTHICK_SMALLGAP_gap;
248 case SvxBorderLineStyle::THINTHICK_LARGEGAP:
249 return fWidth + THINTHICK_LARGEGAP_line1 + THINTHICK_LARGEGAP_line2;
251 case SvxBorderLineStyle::THICKTHIN_SMALLGAP:
252 return fWidth + THICKTHIN_SMALLGAP_line1 + THICKTHIN_SMALLGAP_gap;
254 case SvxBorderLineStyle::THICKTHIN_LARGEGAP:
255 return fWidth + THICKTHIN_LARGEGAP_line1 + THICKTHIN_LARGEGAP_line2;
257 case SvxBorderLineStyle::OUTSET:
258 return (fWidth * 2.0) + OUTSET_line1;
260 case SvxBorderLineStyle::INSET:
261 return (fWidth * 2.0) + INSET_line2;
263 default:
264 assert(false); // should only be called for known border style
266 return 0;
269 double
270 ConvertBorderWidthToWord(SvxBorderLineStyle const eStyle, double const fWidth)
272 if ( !fWidth )
273 return 0;
275 switch (eStyle)
277 // Single lines
278 case SvxBorderLineStyle::SOLID:
279 case SvxBorderLineStyle::DOTTED:
280 case SvxBorderLineStyle::DASHED:
281 case SvxBorderLineStyle::FINE_DASHED:
282 case SvxBorderLineStyle::DASH_DOT:
283 case SvxBorderLineStyle::DASH_DOT_DOT:
284 return fWidth;
286 // Double lines
287 case SvxBorderLineStyle::DOUBLE:
288 case SvxBorderLineStyle::DOUBLE_THIN:
289 return std::max(1.0, fWidth / 3.0);
291 case SvxBorderLineStyle::THINTHICK_MEDIUMGAP:
292 case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP:
293 case SvxBorderLineStyle::EMBOSSED:
294 case SvxBorderLineStyle::ENGRAVED:
295 return std::max(1.0, fWidth / 2.0);
297 case SvxBorderLineStyle::THINTHICK_SMALLGAP:
298 return std::max(1.0, fWidth - THINTHICK_SMALLGAP_line2 - THINTHICK_SMALLGAP_gap);
300 case SvxBorderLineStyle::THINTHICK_LARGEGAP:
301 return std::max(1.0, fWidth - THINTHICK_LARGEGAP_line1 - THINTHICK_LARGEGAP_line2);
303 case SvxBorderLineStyle::THICKTHIN_SMALLGAP:
304 return std::max(1.0, fWidth - THICKTHIN_SMALLGAP_line1 - THICKTHIN_SMALLGAP_gap);
306 case SvxBorderLineStyle::THICKTHIN_LARGEGAP:
307 return std::max(1.0, fWidth - THICKTHIN_LARGEGAP_line1 - THICKTHIN_LARGEGAP_line2);
309 case SvxBorderLineStyle::OUTSET:
310 return std::max(1.0, (fWidth - OUTSET_line1) / 2.0);
312 case SvxBorderLineStyle::INSET:
313 return std::max(1.0, (fWidth - INSET_line2) / 2.0);
315 case SvxBorderLineStyle::NONE:
316 return 0;
318 default:
319 assert(false); // should only be called for known border style
320 return 0;
324 /** Get the BorderWithImpl object corresponding to the given #nStyle, all the
325 units handled by the resulting object are Twips and the
326 BorderWidthImpl::GetLine1() corresponds to the Outer Line.
328 BorderWidthImpl SvxBorderLine::getWidthImpl( SvxBorderLineStyle nStyle )
330 BorderWidthImpl aImpl;
332 switch ( nStyle )
334 // No line: no width
335 case SvxBorderLineStyle::NONE:
336 aImpl = BorderWidthImpl( BorderWidthImplFlags::FIXED, 0.0 );
337 break;
339 // Single lines
340 case SvxBorderLineStyle::SOLID:
341 case SvxBorderLineStyle::DOTTED:
342 case SvxBorderLineStyle::DASHED:
343 case SvxBorderLineStyle::FINE_DASHED:
344 case SvxBorderLineStyle::DASH_DOT:
345 case SvxBorderLineStyle::DASH_DOT_DOT:
346 aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_LINE1, 1.0 );
347 break;
349 // Double lines
351 case SvxBorderLineStyle::DOUBLE:
352 aImpl = BorderWidthImpl(
353 BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST,
354 // fdo#46112 fdo#38542 fdo#43249:
355 // non-constant widths must sum to 1
356 1.0/3.0, 1.0/3.0, 1.0/3.0 );
357 break;
359 case SvxBorderLineStyle::DOUBLE_THIN:
360 aImpl = BorderWidthImpl(BorderWidthImplFlags::CHANGE_DIST, 10.0, 10.0, 1.0);
361 break;
363 case SvxBorderLineStyle::THINTHICK_SMALLGAP:
364 aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_LINE1, 1.0,
365 THINTHICK_SMALLGAP_line2, THINTHICK_SMALLGAP_gap );
366 break;
368 case SvxBorderLineStyle::THINTHICK_MEDIUMGAP:
369 aImpl = BorderWidthImpl(
370 BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST,
371 0.5, 0.25, 0.25 );
372 break;
374 case SvxBorderLineStyle::THINTHICK_LARGEGAP:
375 aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_DIST,
376 THINTHICK_LARGEGAP_line1, THINTHICK_LARGEGAP_line2, 1.0 );
377 break;
379 case SvxBorderLineStyle::THICKTHIN_SMALLGAP:
380 aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_LINE2, THICKTHIN_SMALLGAP_line1,
381 1.0, THICKTHIN_SMALLGAP_gap );
382 break;
384 case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP:
385 aImpl = BorderWidthImpl(
386 BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST,
387 0.25, 0.5, 0.25 );
388 break;
390 case SvxBorderLineStyle::THICKTHIN_LARGEGAP:
391 aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_DIST, THICKTHIN_LARGEGAP_line1,
392 THICKTHIN_LARGEGAP_line2, 1.0 );
393 break;
395 // Engraved / Embossed
397 * Word compat: the lines widths are exactly following this rule, should be:
398 * 0.75pt up to 3pt and then 3pt
401 case SvxBorderLineStyle::EMBOSSED:
402 case SvxBorderLineStyle::ENGRAVED:
403 aImpl = BorderWidthImpl(
404 BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST,
405 0.25, 0.25, 0.5 );
406 break;
408 // Inset / Outset
410 * Word compat: the gap width should be measured relatively to the biggest width for the
411 * row or column.
413 case SvxBorderLineStyle::OUTSET:
414 aImpl = BorderWidthImpl(
415 BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST,
416 OUTSET_line1, 0.5, 0.5 );
417 break;
419 case SvxBorderLineStyle::INSET:
420 aImpl = BorderWidthImpl(
421 BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_DIST,
422 0.5, INSET_line2, 0.5 );
423 break;
426 return aImpl;
429 void SvxBorderLine::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
431 m_nMult = nMult;
432 m_nDiv = nDiv;
435 void SvxBorderLine::GuessLinesWidths( SvxBorderLineStyle nStyle, sal_uInt16 nOut, sal_uInt16 nIn, sal_uInt16 nDist )
437 if (SvxBorderLineStyle::NONE == nStyle)
439 nStyle = SvxBorderLineStyle::SOLID;
440 if ( nOut > 0 && nIn > 0 )
441 nStyle = SvxBorderLineStyle::DOUBLE;
444 if ( nStyle == SvxBorderLineStyle::DOUBLE )
446 static const SvxBorderLineStyle aDoubleStyles[] =
448 SvxBorderLineStyle::DOUBLE,
449 SvxBorderLineStyle::DOUBLE_THIN,
450 SvxBorderLineStyle::THINTHICK_SMALLGAP,
451 SvxBorderLineStyle::THINTHICK_MEDIUMGAP,
452 SvxBorderLineStyle::THINTHICK_LARGEGAP,
453 SvxBorderLineStyle::THICKTHIN_SMALLGAP,
454 SvxBorderLineStyle::THICKTHIN_MEDIUMGAP,
455 SvxBorderLineStyle::THICKTHIN_LARGEGAP
458 static size_t const len = SAL_N_ELEMENTS(aDoubleStyles);
459 tools::Long nWidth = 0;
460 SvxBorderLineStyle nTestStyle(SvxBorderLineStyle::NONE);
461 for (size_t i = 0; i < len && nWidth == 0; ++i)
463 nTestStyle = aDoubleStyles[i];
464 BorderWidthImpl aWidthImpl = getWidthImpl( nTestStyle );
465 nWidth = aWidthImpl.GuessWidth( nOut, nIn, nDist );
468 // If anything matched, then set it
469 if ( nWidth > 0 )
471 nStyle = nTestStyle;
472 SetBorderLineStyle(nStyle);
473 m_nWidth = nWidth;
475 else
477 // fdo#38542: not a known double, default to something custom...
478 SetBorderLineStyle(nStyle);
479 m_nWidth = nOut + nIn + nDist;
480 if (m_nWidth)
482 m_aWidthImpl = BorderWidthImpl(
483 BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST,
484 static_cast<double>(nOut ) / static_cast<double>(m_nWidth),
485 static_cast<double>(nIn ) / static_cast<double>(m_nWidth),
486 static_cast<double>(nDist) / static_cast<double>(m_nWidth));
490 else
492 SetBorderLineStyle(nStyle);
493 if (nOut == 0 && nIn > 0)
495 // If only inner width is given swap inner and outer widths for
496 // single line styles, otherwise GuessWidth() marks this as invalid
497 // and returns a 0 width.
498 switch (nStyle)
500 case SvxBorderLineStyle::SOLID:
501 case SvxBorderLineStyle::DOTTED:
502 case SvxBorderLineStyle::DASHED:
503 case SvxBorderLineStyle::FINE_DASHED:
504 case SvxBorderLineStyle::DASH_DOT:
505 case SvxBorderLineStyle::DASH_DOT_DOT:
506 std::swap( nOut, nIn);
507 break;
508 default:
509 ; // nothing
512 m_nWidth = m_aWidthImpl.GuessWidth( nOut, nIn, nDist );
516 sal_uInt16 SvxBorderLine::GetOutWidth() const
518 sal_uInt16 nOut = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine1( m_nWidth ), m_nMult, m_nDiv ));
519 if ( m_bMirrorWidths )
520 nOut = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine2( m_nWidth ), m_nMult, m_nDiv ));
521 return nOut;
524 sal_uInt16 SvxBorderLine::GetInWidth() const
526 sal_uInt16 nIn = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine2( m_nWidth ), m_nMult, m_nDiv ));
527 if ( m_bMirrorWidths )
528 nIn = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine1( m_nWidth ), m_nMult, m_nDiv ));
529 return nIn;
532 sal_uInt16 SvxBorderLine::GetDistance() const
534 return static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetGap( m_nWidth ), m_nMult, m_nDiv ));
538 bool SvxBorderLine::operator==( const SvxBorderLine& rCmp ) const
540 return (m_aColor == rCmp.m_aColor &&
541 m_aComplexColor == rCmp.m_aComplexColor &&
542 m_nWidth == rCmp.m_nWidth &&
543 m_bMirrorWidths == rCmp.m_bMirrorWidths &&
544 m_aWidthImpl == rCmp.m_aWidthImpl &&
545 m_nStyle == rCmp.GetBorderLineStyle() &&
546 m_bUseLeftTop == rCmp.m_bUseLeftTop &&
547 m_pColorOutFn == rCmp.m_pColorOutFn &&
548 m_pColorInFn == rCmp.m_pColorInFn &&
549 m_pColorGapFn == rCmp.m_pColorGapFn);
552 void SvxBorderLine::SetBorderLineStyle( SvxBorderLineStyle nNew )
554 m_nStyle = nNew;
555 m_aWidthImpl = getWidthImpl( m_nStyle );
557 switch ( nNew )
559 case SvxBorderLineStyle::EMBOSSED:
560 m_pColorOutFn = threeDLightColor;
561 m_pColorInFn = threeDDarkColor;
562 m_pColorGapFn = threeDMediumColor;
563 m_bUseLeftTop = true;
564 break;
565 case SvxBorderLineStyle::ENGRAVED:
566 m_pColorOutFn = threeDDarkColor;
567 m_pColorInFn = threeDLightColor;
568 m_pColorGapFn = threeDMediumColor;
569 m_bUseLeftTop = true;
570 break;
571 case SvxBorderLineStyle::OUTSET:
572 m_pColorOutFn = lightColor;
573 m_pColorInFn = darkColor;
574 m_bUseLeftTop = true;
575 m_pColorGapFn = nullptr;
576 break;
577 case SvxBorderLineStyle::INSET:
578 m_pColorOutFn = darkColor;
579 m_pColorInFn = lightColor;
580 m_bUseLeftTop = true;
581 m_pColorGapFn = nullptr;
582 break;
583 default:
584 m_pColorOutFn = darkColor;
585 m_pColorInFn = darkColor;
586 m_bUseLeftTop = false;
587 m_pColorGapFn = nullptr;
588 break;
592 Color SvxBorderLine::GetColorOut( bool bLeftOrTop ) const
594 Color aResult = m_aColor;
596 if ( m_aWidthImpl.IsDouble() && m_pColorOutFn != nullptr )
598 if ( !bLeftOrTop && m_bUseLeftTop )
599 aResult = (*m_pColorInFn)(m_aColor);
600 else
601 aResult = (*m_pColorOutFn)(m_aColor);
604 return aResult;
607 Color SvxBorderLine::GetColorIn( bool bLeftOrTop ) const
609 Color aResult = m_aColor;
611 if ( m_aWidthImpl.IsDouble() && m_pColorInFn != nullptr )
613 if ( !bLeftOrTop && m_bUseLeftTop )
614 aResult = (*m_pColorOutFn)(m_aColor);
615 else
616 aResult = (*m_pColorInFn)(m_aColor);
619 return aResult;
622 Color SvxBorderLine::GetColorGap( ) const
624 Color aResult = m_aColor;
626 if ( m_aWidthImpl.IsDouble() && m_pColorGapFn != nullptr )
628 aResult = (*m_pColorGapFn)(m_aColor);
631 return aResult;
634 void SvxBorderLine::SetWidth( tools::Long nWidth )
636 m_nWidth = nWidth;
639 OUString SvxBorderLine::GetValueString(MapUnit eSrcUnit,
640 MapUnit eDestUnit,
641 const IntlWrapper* pIntl,
642 bool bMetricStr) const
644 static TranslateId aStyleIds[] =
646 RID_SOLID,
647 RID_DOTTED,
648 RID_DASHED,
649 RID_DOUBLE,
650 RID_THINTHICK_SMALLGAP,
651 RID_THINTHICK_MEDIUMGAP,
652 RID_THINTHICK_LARGEGAP,
653 RID_THICKTHIN_SMALLGAP,
654 RID_THICKTHIN_MEDIUMGAP,
655 RID_THICKTHIN_LARGEGAP,
656 RID_EMBOSSED,
657 RID_ENGRAVED,
658 RID_OUTSET,
659 RID_INSET,
660 RID_FINE_DASHED,
661 RID_DOUBLE_THIN,
662 RID_DASH_DOT,
663 RID_DASH_DOT_DOT
665 OUString aStr = "(" + ::GetColorString(m_aColor) + cpDelim;
667 if ( static_cast<int>(m_nStyle) < int(SAL_N_ELEMENTS(aStyleIds)) )
669 TranslateId pResId = aStyleIds[static_cast<int>(m_nStyle)];
670 aStr += EditResId(pResId);
672 else
674 OUString sMetric = EditResId(GetMetricId( eDestUnit ));
675 aStr += GetMetricText( static_cast<tools::Long>(GetInWidth()), eSrcUnit, eDestUnit, pIntl );
676 if ( bMetricStr )
677 aStr += sMetric;
678 aStr += cpDelim +
679 GetMetricText( static_cast<tools::Long>(GetOutWidth()), eSrcUnit, eDestUnit, pIntl );
680 if ( bMetricStr )
681 aStr += sMetric;
682 aStr += cpDelim +
683 GetMetricText( static_cast<tools::Long>(GetDistance()), eSrcUnit, eDestUnit, pIntl );
684 if ( bMetricStr )
685 aStr += sMetric;
687 aStr += ")";
688 return aStr;
691 bool SvxBorderLine::HasPriority( const SvxBorderLine& rOtherLine ) const
693 const sal_uInt16 nThisSize = GetScaledWidth();
694 const sal_uInt16 nOtherSize = rOtherLine.GetScaledWidth();
696 if ( nThisSize > nOtherSize )
698 return true;
700 else if ( nThisSize < nOtherSize )
702 return false;
704 else if ( rOtherLine.GetInWidth() && !GetInWidth() )
706 return true;
709 return false;
712 bool operator!=( const SvxBorderLine& rLeft, const SvxBorderLine& rRight )
714 return !(rLeft == rRight);
717 } // namespace editeng
719 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */