1 /*
2 * Copyright 2012, 2013 Thomas Schöps
3 * Copyright 2013-2020 Kai Pastor
4 *
5 * This file is part of OpenOrienteering.
6 *
7 * OpenOrienteering is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenOrienteering is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with OpenOrienteering. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21
22 #ifndef OPENORIENTEERING_MAP_COLOR_H
23 #define OPENORIENTEERING_MAP_COLOR_H
24
25 #include <vector>
26
27 #include <QtGlobal>
28 #include <QtMath>
29 #include <QColor>
30 #include <QHash>
31 #include <QMetaType>
32 #include <QRgb>
33 #include <QString>
34
35 namespace OpenOrienteering {
36
37 class MapColor;
38
39 /**
40 * The MapColorCmyk class provides a datatype for storing and transferring
41 * opaque CMYK colors.
42 *
43 * Components (c, m, y, k) are floats in the range [0.0; 1.0].
44 */
45 struct MapColorCmyk
46 {
47 /** The cyan component. */
48 float c = 0;
49 /** The magenta component. */
50 float m = 0;
51 /** The yellow component. */
52 float y = 0;
53 /** The black component (aka key). */
54 float k = 1;
55
56 /** Constructs a black color. */
57 MapColorCmyk() noexcept = default;
58
59 /** Constructs a color with the given components. */
60 MapColorCmyk(float c, float m, float y, float k) noexcept;
61
62 /** Constructs a copy of the given CMYK color. */
63 MapColorCmyk(const MapColorCmyk& other) noexcept = default;
64
65 /** Constructs a CMYK color of the given QColor. Used for type conversions. */
66 MapColorCmyk(const QColor& other) noexcept;
67
68 /** Assigns another color's value to this color. */
69 MapColorCmyk& operator=(const MapColorCmyk& other) = default;
70
71 /** Converts this color to a QColor. */
72 operator QColor() const;
73
74 /** Returns true if this color is black. */
75 bool isBlack() const;
76
77 /** Returns true if this color is white. */
78 bool isWhite() const;
79 };
80
81 /** Returns true iff the MapColorCmyk are equal in all components. */
82 bool operator==(const MapColorCmyk& lhs, const MapColorCmyk& rhs);
83
84 /** Returns true iff the MapColorCmyk differ in at least one components. */
85 bool operator!=(const MapColorCmyk& lhs, const MapColorCmyk& rhs);
86
87
88 /**
89 * The MapColorRgb class provides a datatype for storing and transferring
90 * opaque RGB colors.
91 *
92 * Components (r, g, b) are floats in the range [0.0; 1.0].
93 */
94 struct MapColorRgb
95 {
96 /** The red component. */
97 float r = 0;
98 /** The green component. */
99 float g = 0;
100 /** The blue component. */
101 float b = 0;
102
103 /** Constructs a black color. */
104 MapColorRgb() noexcept = default;
105
106 /** Constructs a color with the given components. */
107 MapColorRgb(float r, float g, float b) noexcept;
108
109 /** Constructs a copy of the given RGB color. */
110 MapColorRgb(const MapColorRgb& other) noexcept = default;
111
112 /** Constructs a RGB color of the given QColor. Used for type conversions. */
113 MapColorRgb(const QColor& other) noexcept;
114
115 /** Assigns another color's value to this color. */
116 MapColorRgb& operator=(const MapColorRgb& other) noexcept = default;
117
118 /** Converts this color to a QColor. */
119 operator QColor() const;
120
121 /** Returns true if this color is black. */
122 bool isBlack() const;
123
124 /** Returns true if this color is white. */
125 bool isWhite() const;
126 };
127
128 /** Returns true if both MapColorRgb are equal in all components. */
129 bool operator==(const MapColorRgb& lhs, const MapColorRgb& rhs);
130
131 /** Returns true iff the MapColorRgb differ in at least one components. */
132 bool operator!=(const MapColorRgb& lhs, const MapColorRgb& rhs);
133
134
135 /**
136 * The SpotColorComponent datatype describes the use of a spot color in a
137 * screen or overprint to create another color.
138 */
139 struct SpotColorComponent
140 {
141 /** A map color which is a spot color. */
142 const MapColor* spot_color;
143
144 /** The factor describes the halftoning (screen).
145 * It is a value in the range [0.0; 1.0]. */
146 float factor;
147
148 /** Constructs a component with an undefined spot color and halftoning. */
149 SpotColorComponent();
150
151 /** Constructs a component for the given spot color and halftoning. */
152 SpotColorComponent(const MapColor* spot_color, float factor);
153
154 /** Returns true iff the spot color is defined. */
155 bool isValid() const;
156 };
157
158
159 /**
160 * The SpotColorComponents type is a STL container that stores all
161 * SpotColorComponent elements which make up a particular map color.
162 */
163 typedef std::vector<SpotColorComponent> SpotColorComponents;
164
165 /**
166 * Returns true if for each element in lhs, there is an element of equal color
167 * and factor in rhs. */
168 bool operator==(const SpotColorComponents &lhs, const SpotColorComponents& rhs);
169
170
171 /**
172 * The MapColor class provides colors which may be used by symbols (and
173 * objects). Apart from the mere color, it specifies how to output the color
174 * to different type of devices and optionally how the color was composed
175 * from other colors.
176 */
177 class MapColor
178 {
179 public:
180 /**
181 * SpecialProperties provides identifiers for (pseudo-)colors serving
182 * particular purposes in the program.
183 */
184 enum SpecialPriorities
185 {
186 CoveringRed = -1005, ///< Foreground color for tool helper lines
187 CoveringWhite = -1000, ///< Background color for tool helper lines
188 Registration = -900, ///< Registration Black: all printed colors
189 Undefined = -500, ///< Color for objects with undefined symbol
190 Reserved = -1 ///< Never drawn
191 };
192
193 /**
194 * ColorMethod provides identifiers for methods on how to determine a
195 * particular realization of a color.
196 */
197 enum ColorMethod
198 {
199 UndefinedMethod = 0,
200 CustomColor = 1,
201 SpotColor = 2,
202 CmykColor = 4,
203 RgbColor = 8,
204 Knockout = 16
205 };
206
207 /** Constructs a black CMYK map color of undefined priority.*/
208 MapColor();
209
210 /** Constructs a black CMYK map color with the given priority. */
211 MapColor(int priority);
212
213 /** Constructs a black CMYK map color with the given name and priority. */
214 MapColor(const QString& name, int priority);
215
216 /** Returns a copy of the color. */
217 MapColor* duplicate() const;
218
219
220 /** Returns a QColor representation (reference) of the map color.
221 *
222 * This color is based on the CMYK color unless the CMYK color method is
223 * RGB: In that case, the returned value is based on the RGB color.
224 */
225 operator const QColor&() const;
226
227 /** Converts the current RGB values to a QRgb. */
228 operator QRgb() const;
229
230
231 /** Returns the color's name for the mapping context. */
232 const QString& getName() const;
233
234 /** Sets the color's name for the mapping context. */
235 void setName(const QString& name);
236
237 /** Returns the color's priority. */
238 int getPriority() const;
239
240 /**
241 * Sets the color's priority.
242 * Normally you don't want to call this directly.
243 */
244 void setPriority(int priority);
245
246 /** @deprecated Returns the color's opacity. */
247 float getOpacity() const;
248
249 /** @deprecated Sets the color's opacity. */
250 void setOpacity(float opacity);
251
252
253 /**
254 * Returns how the spot color is to be created.
255 *
256 * Returns UndefinedMethod, SpotColor (for a full tone single color
257 * referenced by name), or CustomColor (for a color created from named
258 * colors using halftoning (screens) and overprint.
259 */
260 ColorMethod getSpotColorMethod() const;
261
262 /**
263 * Returns the name for the single spot color or a label for the spot color
264 * composition which realizes this map color.
265 * Returns an empty string for an UndefinedMethod.
266 */
267 const QString& getSpotColorName() const;
268
269 /**
270 * Sets the name of a single spot color which realizes this map color,
271 * and sets the spot color method to SpotColor.
272 */
273 void setSpotColorName(const QString& spot_color_id);
274
275 /**
276 * Returns the spot color halftone screen frequency in lines per inch.
277 *
278 * This value is undefined for spot color methods other than SpotColor.
279 */
getScreenFrequency()280 double getScreenFrequency() const { return screen_frequency; }
281
282 /**
283 * Sets the spot color halftone screen frequency in lines per inch.
284 *
285 * A negative or zero value indicates that the halftone screen is undefined.
286 *
287 * This function does nothing for spot color methods other than SpotColor.
288 */
289 void setScreenFrequency(double value);
290
291 /**
292 * Returns the spot color halftone screen angle in lines per inch.
293 *
294 * This value is undefined for spot color methods other than SpotColor.
295 */
getScreenAngle()296 double getScreenAngle() const { return screen_angle; }
297
298 /**
299 * Sets the spot color halftone screen angle in lines per inch.
300 *
301 * This function does nothing for spot color methods other than SpotColor.
302 */
303 void setScreenAngle(double value);
304
305 /**
306 * Sets the given components (i.e. screens and/or overprint) for the color,
307 * and sets the spot color method to CustomColor.
308 */
309 void setSpotColorComposition(const SpotColorComponents& components);
310
311 /**
312 * Returns the components of the spot color realization of this color.
313 * Returns an empty list if the spot color method is not CustomColor.
314 */
315 const SpotColorComponents& getComponents() const;
316
317 /**
318 * Removes a component color.
319 *
320 * Returns true if components were removed.
321 * Returns false if the color was not part of the composition before.
322 */
323 bool removeSpotColorComponent(const MapColor* color);
324
325 /**
326 * Sets the value of knockout flag for spot color printing.
327 *
328 * The color must have a spot color definition, or no change will be done.
329 */
330 void setKnockout(bool flag);
331
332 /**
333 * Returns the value of the knockout flag.
334 */
335 bool getKnockout() const;
336
337
338 /**
339 * Returns how the CMYK color value is determined.
340 *
341 * Returns CustomColor (for custom CMYK values, e.g. for named spot colors),
342 * SpotColor (for values determined from evaluation the spot color composition),
343 * or RgbColor (for values directly derived from the current RGB values).
344 */
345 ColorMethod getCmykColorMethod() const;
346
347 /** Returns the map color's CMYK values. */
348 const MapColorCmyk& getCmyk() const;
349
350 /** Sets the CMYK values, and sets the CMYK color method to CustomColor. */
351 void setCmyk(const MapColorCmyk& cmyk);
352
353 /**
354 * Determines the CMYK values from the spot color composition,
355 * and sets the CMYK color method to SpotColor.
356 *
357 * The spot color method must be CustomColor.
358 * If the spot color composition is empty, the spot color method is
359 * changed to CustomColor, and the CMYK color method is changed to
360 * CustomColor.
361 */
362 void setCmykFromSpotColors();
363
364 /**
365 * Determines the CMYK from the current RGB value,
366 * and sets the CMYK color method to RgbColor.
367 *
368 * If the RGB color method is CmykColor, it is changed to CustomColor.
369 */
370 void setCmykFromRgb();
371
372
373 /**
374 * Returns how the RGB color value is determined.
375 *
376 * Returns CustomColor (for custom RGB values),
377 * SpotColor (for values determined from evaluation the spot color composition),
378 * or CmykColor (for values directly derived from the current CMYK value).
379 */
380 ColorMethod getRgbColorMethod() const;
381
382 /** Returns the map color's RGB values. */
383 const MapColorRgb& getRgb() const;
384
385 /** Sets the RGB values, and sets the RGB color method to CustomColor. */
386 void setRgb(const MapColorRgb& rgb);
387
388 /**
389 * Determines the RGB values from the spot color composition,
390 * and sets the RGB color method to SpotColor.
391 *
392 * The spot color method must be CustomColor.
393 * If the spot color composition is empty, the spot color method is
394 * changed to CustomColor, and the RGB color method is changed to
395 * CustomColor.
396 */
397 void setRgbFromSpotColors();
398
399 /**
400 * Determines the RGB from the current CMYK value,
401 * and sets the RGB color method to CmykColor.
402 *
403 * If the CMYK color method is RgbColor, it is changed to CustomColor.
404 */
405 void setRgbFromCmyk();
406
407
408 /** Returns true if this color is black. */
409 bool isBlack() const;
410
411 /** Returns true if this color is white. */
412 bool isWhite() const;
413
414
415 /** Compares this color and another, without looking at priorities. */
416 bool equals(const MapColor& other) const;
417
418 /**
419 * Compares two colors given by pointers, without looking at priorities.
420 *
421 * This functions adds handling of `nullptr`:
422 * It returns true if the colors are equal or if both pointers are nullptr.
423 */
424 static bool equal(const MapColor* color, const MapColor* other);
425
426 /** Returns true if this color's priority is less than the other's. */
427 bool comparePriority(const MapColor& other) const;
428
429 protected:
430 friend bool operator==(const MapColor& lhs, const MapColor& rhs);
431
432 /** Compares this color and another. */
433 bool equals(const MapColor& other, bool compare_priority) const;
434
435 /** Compares this color's components and another. */
436 bool componentsEqual(const MapColor& other, bool compare_priority) const;
437
438 /**
439 * Determines the composition name from the components.
440 *
441 * Does nothing it the spot color method is not CustomColor.
442 */
443 void updateCompositionName();
444
445 /**
446 * Updates all calculated color values.
447 *
448 * If the spot color method is different from CustomColor, resets CMYK and
449 * RGB methods from SpotColor tp CustomColor.
450 */
451 void updateCalculatedColors();
452
453 /**
454 * Returns a CMYK color determined from the cmyk color of the spot color
455 * components.
456 */
457 MapColorCmyk cmykFromSpotColors() const;
458
459 /**
460 * Returns a RGB color determined from the cmyk color of the spot color
461 * components.
462 */
463 MapColorRgb rgbFromSpotColors() const;
464
465
466 QString name;
467 int priority;
468
469 MapColorCmyk cmyk;
470 MapColorRgb rgb;
471 float opacity;
472
473 QColor q_color;
474
475 char spot_color_method;
476 char cmyk_color_method;
477 char rgb_color_method;
478 char flags;
479
480 QString spot_color_name;
481 double screen_frequency = -1; ///< Halftone screen frequency in lines per inch.
482 double screen_angle = 0; ///< Halftone screen angle in degrees.
483 SpotColorComponents components;
484 };
485
486 /** Returns true if both MapColor are equal in all components. */
487 bool operator==(const MapColor& lhs, const MapColor& rhs);
488
489 /** Returns true iff the MapColor differ in at least one components. */
490 bool operator!=(const MapColor& lhs, const MapColor& rhs);
491
492
493 /**
494 * MapColorMap provides a mapping from one map color to another.
495 *
496 * In addition to explicitly user-defined key-value pairs of colors, it will
497 * (in const contexts) map colors with reserved priorities to themselves,
498 * assuming that there is only a single static instance of these colors.
499 */
500 class MapColorMap
501 {
502 public:
503 /** Constructs a new MapColorMap. */
504 MapColorMap();
505
506 /** Returns the size, i.e. the number of user-defined key-value pairs. */
507 int size() const;
508
509 /** Clears the user-defined key-value pairs. */
510 void clear();
511
512 /** Returns true if there is a user-defined value for the key color */
513 bool contains(const MapColor* key) const;
514
515 /** Returns the mapped value for the key color.
516 *
517 * Returns the user-defined value for the key color if it is defined.
518 * Otherwise, if the key color's priority is from the RESERVED domain,
519 * returns key. Otherwise returns nullptr.
520 */
521 const MapColor* value(const MapColor* key) const;
522
523 /** Returns the mapped value for the key color. Same as value().
524 *
525 * Returns the user-defined value for the key color if it is defined.
526 * Otherwise, if the key color's priority is from the RESERVED domain,
527 * returns key. Otherwise returns nullptr.
528 */
529 const MapColor* operator[](const MapColor* key) const;
530
531 /** Returns a reference to pointer to the mapped value for the key color.
532 * If a user-defined mapped value does not exist yet, a default-
533 * constructed mapped value is created first.
534 */
535 const MapColor* & operator[](const MapColor* key);
536
537 private:
538 /** The low-level mapping. */
539 QHash<const MapColor*, const MapColor*> mapping;
540 };
541
542
543 /**
544 * Constructs a QColor with the alpha given by opacity from the prototype c.
545 *
546 * A QColor object must be constructible from c.
547 */
548 template <class T>
549 QColor colorWithOpacity(T c, float opacity);
550
551 /**
552 * Constructs a QColor with opacity from the given MapColor.
553 */
554 QColor colorWithOpacity(const MapColor& c);
555
556
557
558 // ### MapColorCmyk inline code ###
559
560 inline
MapColorCmyk(float c,float m,float y,float k)561 MapColorCmyk::MapColorCmyk(float c, float m, float y, float k) noexcept
562 : c(c), m(m), y(y), k(k)
563 {
564 // Nothing
565 }
566
567 inline
MapColorCmyk(const QColor & other)568 MapColorCmyk::MapColorCmyk(const QColor& other) noexcept
569 : c(other.cyanF()), m(other.magentaF()), y(other.yellowF()), k(other.blackF())
570 {
571 // Nothing
572 }
573
574 inline
QColor()575 MapColorCmyk::operator QColor() const
576 {
577 return QColor::fromCmykF(c, m, y, k);
578 }
579
580 inline
isBlack()581 bool MapColorCmyk::isBlack() const
582 {
583 return (1.0 == k) || (1.0 == c && 1.0 == m && 1.0 == y);
584 }
585
586 inline
isWhite()587 bool MapColorCmyk::isWhite() const
588 {
589 return (0.0 == c && 0.0 == m && 0.0 == y && 0.0 == k);
590 }
591
592 inline
593 bool operator==(const MapColorCmyk& lhs, const MapColorCmyk& rhs)
594 {
595 // The maximum difference of two floating point member values
596 // which are regarded as *equal*.
597 static const float epsilon = 0.0005f;
598 return ( qAbs(lhs.c - rhs.c) <= epsilon &&
599 qAbs(lhs.m - rhs.m) <= epsilon &&
600 qAbs(lhs.y - rhs.y) <= epsilon &&
601 qAbs(lhs.k - rhs.k) <= epsilon );
602 }
603
604 inline
605 bool operator!=(const MapColorCmyk& lhs, const MapColorCmyk& rhs)
606 {
607 return !(lhs == rhs);
608 }
609
610
611 // ### MapColorRgb inline code ###
612
613 inline
MapColorRgb(float r,float g,float b)614 MapColorRgb::MapColorRgb(float r, float g, float b) noexcept
615 : r(r), g(g), b(b)
616 {
617 // Nothing
618 }
619
620 inline
MapColorRgb(const QColor & other)621 MapColorRgb::MapColorRgb(const QColor& other) noexcept
622 : r(other.redF()), g(other.greenF()), b(other.blueF())
623 {
624 // Nothing
625 }
626
627 inline
QColor()628 MapColorRgb::operator QColor() const
629 {
630 return QColor::fromRgbF(r, g, b);
631 }
632
633 inline
isBlack()634 bool MapColorRgb::isBlack() const
635 {
636 return (0.0 == r && 0.0 == g && 0.0 == b);
637 }
638
639 inline
isWhite()640 bool MapColorRgb::isWhite() const
641 {
642 return (1.0 == r && 1.0 == g && 1.0 == b);
643 }
644
645 inline
646 bool operator==(const MapColorRgb& lhs, const MapColorRgb& rhs)
647 {
648 // The maximum difference of two floating point member values
649 // which are regarded as *equal*.
650 static const float epsilon = 0.0005f;
651 return ( qAbs(lhs.r - rhs.r) <= epsilon &&
652 qAbs(lhs.g - rhs.g) <= epsilon &&
653 qAbs(lhs.b - rhs.b) <= epsilon );
654 }
655
656 inline
657 bool operator!=(const MapColorRgb& lhs, const MapColorRgb& rhs)
658 {
659 return !(lhs == rhs);
660 }
661
662
663 // ### SpotColorComponent inline code ###
664
665 inline
SpotColorComponent()666 SpotColorComponent::SpotColorComponent()
667 : spot_color(nullptr),
668 factor(0.0f)
669 {
670 // Nothing
671 }
672
673 inline
SpotColorComponent(const MapColor * spot_color,float factor)674 SpotColorComponent::SpotColorComponent(const MapColor* spot_color, float factor)
675 : spot_color(spot_color),
676 factor(factor)
677 {
678 // Nothing
679 }
680
681 inline
isValid()682 bool SpotColorComponent::isValid() const
683 {
684 return spot_color;
685 }
686
687
688 // ### MapColor inline code ###
689
690 inline
691 MapColor::operator const QColor&() const
692 {
693 return q_color;
694 }
695
696 inline
QRgb()697 MapColor::operator QRgb() const
698 {
699 return qRgba(qFloor(255.9 * rgb.r), qFloor(255.9 * rgb.g), qFloor(255.9 * rgb.b), qFloor(255.9 * opacity));
700 }
701
702 inline
getName()703 const QString& MapColor::getName() const
704 {
705 return name;
706 }
707
708 inline
setName(const QString & name)709 void MapColor::setName(const QString& name)
710 {
711 this->name = name;
712 }
713
714 inline
getPriority()715 int MapColor::getPriority() const
716 {
717 return priority;
718 }
719
720 inline
setPriority(int priority)721 void MapColor::setPriority(int priority)
722 {
723 this->priority = priority;
724 }
725
726 inline
getOpacity()727 float MapColor::getOpacity() const
728 {
729 return opacity;
730 }
731
732 inline
setOpacity(float opacity)733 void MapColor::setOpacity(float opacity)
734 {
735 this->opacity = opacity;
736 }
737
738 inline
getSpotColorMethod()739 MapColor::ColorMethod MapColor::getSpotColorMethod() const
740 {
741 return (ColorMethod)spot_color_method;
742 }
743
744 inline
getSpotColorName()745 const QString& MapColor::getSpotColorName() const
746 {
747 return spot_color_name;
748 }
749
750 inline
getComponents()751 const SpotColorComponents& MapColor::getComponents() const
752 {
753 return components;
754 }
755
756 inline
getCmykColorMethod()757 MapColor::ColorMethod MapColor::getCmykColorMethod() const
758 {
759 return (ColorMethod)cmyk_color_method;
760 }
761
762 inline
getCmyk()763 const MapColorCmyk& MapColor::getCmyk() const
764 {
765 return cmyk;
766 }
767
768 inline
getRgbColorMethod()769 MapColor::ColorMethod MapColor::getRgbColorMethod() const
770 {
771 return (ColorMethod)rgb_color_method;
772 }
773
774 inline
getRgb()775 const MapColorRgb& MapColor::getRgb() const
776 {
777 return rgb;
778 }
779
780 inline
comparePriority(const MapColor & other)781 bool MapColor::comparePriority(const MapColor& other) const
782 {
783 return priority < other.priority;
784 }
785
786 inline
equal(const MapColor * color,const MapColor * other)787 bool MapColor::equal(const MapColor* color, const MapColor* other)
788 {
789 if (color == other)
790 return true;
791 else if (color && other)
792 return color->equals(*other, false);
793 else
794 return false;
795 }
796
797 inline
798 bool operator==(const MapColor& lhs, const MapColor& rhs)
799 {
800 return lhs.equals(rhs, true);
801 }
802
803 inline
804 bool operator!=(const MapColor& lhs, const MapColor& rhs)
805 {
806 return !(lhs == rhs);
807 }
808
809
810 // ### MapColorMap inline code ###
811
812 inline
MapColorMap()813 MapColorMap::MapColorMap()
814 : mapping()
815 {
816 // Nothing.
817 }
818
819 inline
size()820 int MapColorMap::size() const
821 {
822 return mapping.size();
823 }
824
825 inline
clear()826 void MapColorMap::clear()
827 {
828 mapping.clear();
829 }
830
831 inline
contains(const MapColor * key)832 bool MapColorMap::contains(const MapColor* key) const
833 {
834 return mapping.contains(key);
835 }
836
837 inline
value(const MapColor * key)838 const MapColor* MapColorMap::value(const MapColor* key) const
839 {
840 if (mapping.contains(key))
841 {
842 return mapping.value(key);
843 }
844 else if (key && key->getPriority() < 0)
845 {
846 return key;
847 }
848 else
849 {
850 return nullptr;
851 }
852 }
853
854 inline
855 const MapColor* MapColorMap::operator[](const MapColor* key) const
856 {
857 return value(key);
858 }
859
860 inline
861 const MapColor* & MapColorMap::operator[](const MapColor* key)
862 {
863 return mapping[key];
864 }
865
866 template <class T>
colorWithOpacity(T c,float opacity)867 QColor colorWithOpacity(T c, float opacity)
868 {
869 auto color = static_cast<QColor>(c);
870 color.setAlphaF(opacity);
871 return color;
872 }
873
874 inline
colorWithOpacity(const MapColor & c)875 QColor colorWithOpacity(const MapColor& c)
876 {
877 return colorWithOpacity(static_cast<const QColor&>(c), c.getOpacity());
878 }
879
880
881 } // namespace OpenOrienteering
882
883
884 // Allow explicit use of MapColor pointers in QVariant
885 Q_DECLARE_METATYPE(const OpenOrienteering::MapColor*)
886
887
888 #endif
889