1 line
13 KiB
C
Executable File
1 line
13 KiB
C
Executable File
/* Copyright (c) 2017, Computer History Museum
|
|
All rights reserved.
|
|
Redistribution and use in source and binary forms, with or without modification, are permitted (subject to
|
|
the limitations in the disclaimer below) provided that the following conditions are met:
|
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
|
|
disclaimer in the documentation and/or other materials provided with the distribution.
|
|
* Neither the name of Computer History Museum nor the names of its contributors may be used to endorse or promote products
|
|
derived from this software without specific prior written permission.
|
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
|
|
COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
DAMAGE. */
|
|
|
|
#include "color.h"
|
|
#define FILE_NUM 59
|
|
/* Copyright (c) 1994 by QUALCOMM Incorporated */
|
|
|
|
#ifdef TWO
|
|
#pragma segment Color
|
|
|
|
uShort ChangeByPercent(uShort value,short percent);
|
|
|
|
/************************************************************************
|
|
* SetMenuColor - set the color of a menu item
|
|
************************************************************************/
|
|
void SetMenuColor(MenuHandle menu, short item, RGBColor *color)
|
|
{
|
|
MCEntry mcEntry;
|
|
MCEntry *defaultMC;
|
|
|
|
defaultMC = GetMCEntry(0,0);
|
|
if (defaultMC)
|
|
mcEntry.mctRGB4 = defaultMC->mctRGB4;
|
|
else
|
|
mcEntry.mctRGB4.red = mcEntry.mctRGB4.blue = mcEntry.mctRGB4.green = 0xffff;
|
|
mcEntry.mctID = GetMenuID(menu);
|
|
mcEntry.mctItem = item;
|
|
mcEntry.mctRGB1 = mcEntry.mctRGB2 = mcEntry.mctRGB3 = *color;
|
|
SetMCEntries(1,&mcEntry);
|
|
}
|
|
|
|
/************************************************************************
|
|
* GetLabelColor - return the color of a label
|
|
************************************************************************/
|
|
RGBColor *GetLabelColor(short index,RGBColor *color)
|
|
{
|
|
Str255 label;
|
|
|
|
MyGetLabel(index,color,label);
|
|
return(color);
|
|
}
|
|
|
|
/************************************************************************
|
|
* MyGetLabel - get a label description from the Finder
|
|
************************************************************************/
|
|
OSErr MyGetLabel(short index,RGBColor *color,PStr label)
|
|
{
|
|
OSErr err;
|
|
|
|
if (index<8)
|
|
{
|
|
short fIndex = index ? 8-index:0;
|
|
err = GetLabel(fIndex,color,label);
|
|
// ComposeLogS(-1,nil,"\pindex %d RGB %d.%d.%d Name %p",
|
|
// fIndex, color->red/256, color->green/256, color->blue/256, label);
|
|
}
|
|
else
|
|
{
|
|
GetRString(label,PrivLabelsStrn+index-7);
|
|
GetRColor(color,PrivColorsStrn+index-7);
|
|
err = noErr;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/************************************************************************
|
|
* LightenColor - make a color lighter
|
|
************************************************************************/
|
|
RGBColor *LightenColor(RGBColor *color,short percent)
|
|
{
|
|
HSVColor hsv;
|
|
|
|
RGB2HSV(color,&hsv);
|
|
hsv.value = ChangeByPercent(hsv.value,percent);
|
|
hsv.saturation = ChangeByPercent(hsv.saturation,-percent);
|
|
HSV2RGB(&hsv,color);
|
|
return(color);
|
|
}
|
|
|
|
/************************************************************************
|
|
* ColorIsLight - is a color light?
|
|
************************************************************************/
|
|
Boolean ColorIsLight(RGBColor *color)
|
|
{
|
|
long light = GetRLong(LIGHT_COLOR);
|
|
|
|
return(color->red>light && color->blue>light && color->green>light);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* Color3DRect - color a 3D rectangle, based on some color
|
|
**********************************************************************/
|
|
void Color3DRect(Rect *inRect, RGBColor *color, D3EffectEnum howMuch, Boolean raised)
|
|
{
|
|
RGBColor colors[2];
|
|
RGBColor *light, *dark;
|
|
Rect r = *inRect;
|
|
|
|
if (raised)
|
|
{
|
|
light = &colors[0];
|
|
dark = &colors[1];
|
|
}
|
|
else
|
|
{
|
|
light = &colors[1];
|
|
dark = &colors[0];
|
|
}
|
|
*light = *dark = *color;
|
|
|
|
switch (howMuch)
|
|
{
|
|
case e3DNone: break; /* none of that crap */
|
|
|
|
case e3DSlight:
|
|
LightenColor(&colors[0],30); DarkenColor(&colors[1],60);
|
|
TwoToneFrame(&r,light,dark);
|
|
InsetRect(&r,1,1);
|
|
break;
|
|
|
|
case e3DOverBearing:
|
|
LightenColor(&colors[0],40); DarkenColor(&colors[1],60);
|
|
TwoToneFrame(&r,light,dark);
|
|
InsetRect(&r,1,1);
|
|
*light = *dark = *color;
|
|
LightenColor(&colors[0],20); DarkenColor(&colors[1],20);
|
|
TwoToneFrame(&r,light,dark);
|
|
InsetRect(&r,1,1);
|
|
break;
|
|
}
|
|
|
|
if (raised)
|
|
{
|
|
RGBColor oldColor;
|
|
|
|
GetForeColor(&oldColor);
|
|
RGBForeColor(color);
|
|
PaintRect(&r);
|
|
RGBForeColor(&oldColor);
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* Frame3DOrNot - frame something, possibly in 3D
|
|
**********************************************************************/
|
|
void Frame3DOrNot(Rect *r, RGBColor *baseColor,Boolean erase)
|
|
{
|
|
short depth;
|
|
RGBColor color;
|
|
|
|
InsetRect(r,-2,-2);
|
|
|
|
if (D3 && (depth=RectDepth(r))>=4)
|
|
{
|
|
if (baseColor) color = *baseColor;
|
|
else SetRGBGrey(&color,depth==4?k4Grey1:k8Grey1);
|
|
Color3DRect(r,&color,e3DSlight,False);
|
|
}
|
|
|
|
InsetRect(r,1,1);
|
|
FrameRect(r);
|
|
|
|
if (erase)
|
|
{
|
|
InsetRect(r,1,1);
|
|
EraseRect(r);
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* WinGreyBG - set the right grey for a window's background
|
|
**********************************************************************/
|
|
void WinGreyBG(MyWindowPtr win)
|
|
{
|
|
short depth;
|
|
RGBColor color;
|
|
|
|
if (D3 && (depth=RectDepth(&win->contR))>=4)
|
|
RGBBackColor(SetRGBGrey(&color,depth>4?k8Grey1:k4Grey1));
|
|
else if (ThereIsColor)
|
|
RGBBackColor(SetRGBGrey(&color,0xffff));
|
|
}
|
|
|
|
/**********************************************************************
|
|
* DrawDivider - draw a divider, possibly 3D
|
|
**********************************************************************/
|
|
void DrawDivider(Rect *r,Boolean raised)
|
|
{
|
|
WindowPtr portWP = GetQDGlobalsThePort();
|
|
MyWindowPtr win = GetWindowMyWindowPtr(portWP);
|
|
Boolean isActive = IsMyWindow(portWP) && win && win->isActive && !InBG;
|
|
|
|
DrawThemeSeparator(r,isActive?kThemeStateActive:kThemeStateInactive);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ColorParam - return a color
|
|
**********************************************************************/
|
|
OSErr ColorParam(RGBColor *color,PStr text)
|
|
{
|
|
MCEntryPtr mc;
|
|
short item;
|
|
Str255 red, green, blue;
|
|
UPtr spot;
|
|
|
|
if (item=FindItemByName(GetMHandle(COLOR_HIER_MENU),text))
|
|
{
|
|
if (item==1 || !(mc = GetMCEntry(COLOR_HIER_MENU,item)))
|
|
GetForeColor(color);
|
|
else
|
|
*color = mc->mctRGB2;
|
|
}
|
|
else
|
|
{
|
|
spot = text+1;
|
|
if (PToken(text,red,&spot,",") && PToken(text,green,&spot,",") &&
|
|
PToken(text,blue,&spot,","))
|
|
{
|
|
item = 1;
|
|
Hex2Bytes(red+1,4,(void*)&color->red);
|
|
Hex2Bytes(green+1,4,(void*)&color->green);
|
|
Hex2Bytes(blue+1,4,(void*)&color->blue);
|
|
}
|
|
}
|
|
return(item?noErr:fnfErr);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* LightestGrey - the lightest appropriate grey
|
|
**********************************************************************/
|
|
short LightestGrey(Rect *r)
|
|
{
|
|
short depth = RectDepth(r);
|
|
if (depth<4) return(0xffff);
|
|
else if (depth==4) return(k4Grey1);
|
|
else return(k8Grey1);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TwoToneFrame - a two-tone frame for a rectangle
|
|
**********************************************************************/
|
|
void TwoToneFrame(Rect *r, RGBColor *topLeft, RGBColor *botRight)
|
|
{
|
|
RGBColor oldColor;
|
|
GetForeColor(&oldColor);
|
|
|
|
//top
|
|
RGBForeColor(topLeft);
|
|
MoveTo(r->left,r->top);
|
|
LineTo(r->right-1,r->top);
|
|
|
|
//left
|
|
MoveTo(r->left,r->top);
|
|
LineTo(r->left,r->bottom-1);
|
|
|
|
//right
|
|
RGBForeColor(botRight);
|
|
MoveTo(r->right-1,r->bottom-1);
|
|
LineTo(r->right-1,r->top+1);
|
|
|
|
//bottom
|
|
MoveTo(r->right-1,r->bottom-1);
|
|
LineTo(r->left+1,r->bottom-1);
|
|
|
|
RGBForeColor(&oldColor);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* LimitColorRange - make sure a color is not too light or too dark
|
|
**********************************************************************/
|
|
RGBColor *LimitColorRange(RGBColor *color)
|
|
{
|
|
HSVColor hsv;
|
|
uShort min, max;
|
|
|
|
max = GetRLong(MAX_COLOR_LIGHT)*(0xffff/100);
|
|
min = GetRLong(MIN_COLOR_LIGHT)*(0xffff/100);
|
|
|
|
RGB2HSV(color,&hsv);
|
|
hsv.value = MIN(hsv.value,max);
|
|
hsv.value = MAX(hsv.value,min);
|
|
HSV2RGB(&hsv,color);
|
|
return color;
|
|
}
|
|
|
|
/************************************************************************
|
|
* PastelColor - make a color pastel
|
|
************************************************************************/
|
|
RGBColor *PastelColor(RGBColor *color)
|
|
{
|
|
HSVColor hsv;
|
|
long val;
|
|
|
|
RGB2HSV(color,&hsv);
|
|
if (val=GetRLong(PASTEL_LIGHT)) hsv.value = val;
|
|
if (val=GetRLong(PASTEL_SATUR8)) hsv.saturation = val;
|
|
HSV2RGB(&hsv,color);
|
|
return(color);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DarkenColor - make a color darker
|
|
************************************************************************/
|
|
RGBColor *DarkenColor(RGBColor *color,short percent)
|
|
{
|
|
return(LightenColor(color,-percent));
|
|
}
|
|
|
|
/************************************************************************
|
|
* ChangeByPercent - change a vlue by a percentage
|
|
************************************************************************/
|
|
uShort ChangeByPercent(uShort value,short percent)
|
|
{
|
|
long newValue = value;
|
|
|
|
newValue += (newValue*percent)/100;
|
|
if (newValue<0) newValue = 0;
|
|
if (newValue>0xffff) newValue = 0xffff;
|
|
return(newValue);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SetRGBGrey - set a grey color
|
|
**********************************************************************/
|
|
RGBColor *SetRGBGrey(RGBColor *color,short greyValue)
|
|
{
|
|
color->red = color->green = color->blue = greyValue;
|
|
return(color);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* BlackWhite - is a color pure black or pure white?
|
|
**********************************************************************/
|
|
#define CTOL 100
|
|
Boolean Black(RGBColor *color)
|
|
{
|
|
if (color->red < CTOL && color->green < CTOL && color->blue < CTOL) return(True);
|
|
return(False);
|
|
}
|
|
Boolean White(RGBColor *color)
|
|
{
|
|
if (color->red > 0xffff-CTOL && color->green > 0xffff-CTOL && color->blue > 0xffff-CTOL) return(True);
|
|
return(False);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SetForeGrey - set the foreground grey
|
|
**********************************************************************/
|
|
void SetForeGrey(short greyValue)
|
|
{
|
|
RGBColor color;
|
|
RGBForeColor(SetRGBGrey(&color,greyValue));
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SetBGGrey - set the background grey
|
|
**********************************************************************/
|
|
void SetBGGrey(short greyValue)
|
|
{
|
|
RGBColor color;
|
|
RGBBackColor(SetRGBGrey(&color,greyValue));
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ColCtlPicker - call the color picker
|
|
**********************************************************************/
|
|
Boolean ColCtlPicker(ControlHandle cntl)
|
|
{
|
|
RGBColor oldC, newC;
|
|
Point where;
|
|
Boolean result;
|
|
|
|
if (ThereIsColor)
|
|
{
|
|
ColCtlGet(cntl,&oldC);
|
|
where.h = where.v = -1;
|
|
|
|
result = GetColor(where,"",&oldC,&newC);
|
|
SetPort(GetWindowPort(GetControlOwner(cntl)));
|
|
|
|
if (result)
|
|
{
|
|
ColCtlSet(cntl,&newC);
|
|
return(True);
|
|
}
|
|
}
|
|
|
|
return(False);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ColCtlSet - set color in the color cdef
|
|
**********************************************************************/
|
|
void ColCtlSet(ControlHandle cntl, RGBColor *color)
|
|
{
|
|
SetControl32BitMinimum(cntl,-70000);
|
|
SetControl32BitMaximum(cntl,70000);
|
|
SetControl32BitValue(cntl,color->red);
|
|
SetControlReference(cntl,((uLong)color->green<<16) | (uLong)color->blue);
|
|
Draw1Control(cntl);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ColCtlGet - get the color from the color cdef
|
|
**********************************************************************/
|
|
RGBColor *ColCtlGet(ControlHandle cntl, RGBColor *color)
|
|
{
|
|
color->red = GetControl32BitValue(cntl);
|
|
color->green = (short) 0xffff&(GetControlReference(cntl)>>16);
|
|
color->blue = (short) 0xffff&GetControlReference(cntl);
|
|
return(color);
|
|
}
|
|
|
|
#endif
|