2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
5 Desc: Obtain the best pen available for a given color
9 #include "graphics_intern.h"
10 #include <proto/utility.h>
11 #include <utility/tagitem.h>
12 #include <graphics/view.h>
14 /*****************************************************************************
17 #include <proto/graphics.h>
19 AROS_LH5(LONG
, ObtainBestPenA
,
22 AROS_LHA(struct ColorMap
*, cm
, A0
),
23 AROS_LHA(ULONG
, r
, D1
),
24 AROS_LHA(ULONG
, g
, D2
),
25 AROS_LHA(ULONG
, b
, D3
),
26 AROS_LHA(struct TagItem
* , tags
, A1
),
29 struct GfxBase
*, GfxBase
, 140, Graphics
)
32 Try to find a pen which matches the given parameters.
36 r - red value (32 bit left justified fraction)
37 g - green value (32 bit left justified fraction)
38 b - blue value (32 bit left justified fraction)
40 OBP_Precision - PRECISION_GUI, PRECISION_ICON, PRECISION_IMAGE or PRECISION_EXACT.
41 Defaults to PRECISION_IMAGE.
43 OBP_FailIfBad - if TRUE ObtainBestPen returns an error when there
44 is no color in the given tolerance.
47 A pen value or -1 if no pen could be found.
50 You must call ReleasePen() when you're done with the pen.
62 *****************************************************************************/
66 struct PaletteExtra
*pe
= cm
->PalExtra
;
68 PalExtra_AllocList_Type index
;
72 struct TagItem defaults
[] =
74 {OBP_Precision
, PRECISION_IMAGE
},
75 {OBP_FailIfBad
, FALSE
}
77 ULONG best_distance
= (ULONG
)-1;
81 ** override the defaults if necessary
83 defaults
[0].ti_Data
= GetTagData(OBP_Precision
,
87 defaults
[1].ti_Data
= GetTagData(OBP_FailIfBad
,
92 ** let nobody else play with the PalExtra structure
94 ObtainSemaphore(&pe
->pe_Semaphore
);
97 ** Walk through the list of shared pens and search
98 ** for the closest color.
100 index
= (PalExtra_AllocList_Type
)pe
->pe_FirstShared
;
101 while ((PalExtra_AllocList_Type
)-1 != index
)
103 ULONG distance
= color_distance(cm
,r
,g
,b
,index
);
105 if (distance
< best_distance
)
107 best_distance
= distance
;
111 index
= PALEXTRA_ALLOCLIST(pe
, index
);
114 /* FIXME: The color distance calc might be different than in AmigaOS. */
117 ** If the best distance to an available color is greater than
118 ** the square of the tolerance, try to allocate a better
119 ** color, otherwise increase the shared counter for that color.
120 ** If only a little amount of colors is free for allocation in the
121 ** colormap the restrictions towards color matching should be
122 ** much looser than if the amount of allocated colors is close to 0.
123 ** The autodocs say that.
127 (PRECISION_EXACT
== defaults
[0].ti_Data
&& 0 != best_distance
) ||
128 (best_distance
* pe
->pe_NFree
>
129 (defaults
[0].ti_Data
* defaults
[0].ti_Data
) * pe
->pe_SharableColors
134 ** The given tolerance could not be accomplished.
135 ** Try to allocate a pen. If that fails we
136 ** return -1 if the user specified OBP_FailIfBad = TRUE.
138 LONG tmp
= ObtainPen(cm
,-1,r
,g
,b
,0);
143 ** Return -1 if the user is strict with color matching.
144 ** In the other case retval is not changed.
146 if (defaults
[1].ti_Data
)
150 else if (retval
!= -1)
153 ** One more application is using this color
156 PALEXTRA_REFCNT(pe
, retval
)++;
165 ** One more application is using this color
167 PALEXTRA_REFCNT(pe
, retval
)++;
170 ReleaseSemaphore(&pe
->pe_Semaphore
);
172 } /* if (NULL != pe) */
178 } /* ObtainBestPenA */