Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
CLUTBuilder.c
/* |
File: CLUTBuilder.c |
Contains: this file contains functions used to pull colors from a PICT. You activate it by |
calling CollectColors(PicHandle) with PicHandle set to a PICT that you have already |
loaded into memory. It will almost invariably return a (handle to a) color table |
(that contains at least black and white) however the color table is not at all clean |
in the current implementation. It is probably ok if you run it through NewPalette. |
If it runs across a direct pixmap it won't bomb but it won't add any colors to the |
color table. |
WARNING: This code has been tested but it has not been tested thoroughly; |
USE AT YOUR OWN RISK! |
Written by: Jon Zap |
Copyright: Copyright © 1989-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/8/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include "CLUTBuilder.h" |
#define applec |
/* Add a color to the color table. */ |
void AddRGBColor(RGBColor * rgb) |
{ |
long numSpecs,sizeInBytes; |
int i,ctSize; |
CTabPtr TablePtr; |
RGBColor rgbx; |
if (gColorError) |
return; |
TablePtr = (*gColorTable); |
ctSize = TablePtr -> ctSize; |
for (i = 0; i <= ctSize; i++) { |
rgbx = TablePtr->ctTable[i].rgb; |
if (rgbx.red==(*rgb).red && |
rgbx.green==(*rgb).green && |
rgbx.blue==(*rgb).blue) |
return; /* if already there, done */ |
} |
numSpecs = (long) (++(**gColorTable).ctSize); /* add a colorspec to table */ |
sizeInBytes = (numSpecs * sizeof(ColorSpec)) + sizeof(ColorTable); |
SetHandleSize((Handle)gColorTable, sizeInBytes); |
if ((gColorError = MemError()) == noErr) { |
(**gColorTable).ctTable[numSpecs].rgb = *rgb; |
(**gColorTable).ctTable[numSpecs].value = 0; |
} |
} |
/* Add the contents of another color table to our color table.*/ |
void AddColorTable(CTabHandle cTab) |
{ |
short index,size; |
RGBColor color; |
size = (**cTab).ctSize; |
for (index= 0; index <= size; index++) { |
color = (**cTab).ctTable[index].rgb; |
AddRGBColor(&color); |
} |
} |
/* Add the foreground color of the current port to the color table. */ |
void AddRGBForeColor() |
{ |
#ifdef applec |
AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbFgColor)); |
#else |
AddRGBColor(&((*(CGrafPtr)thePort).rgbFgColor)); |
#endif |
} |
/* Add the background color of the current port to the color table. */ |
void AddRGBBackColor() |
{ |
#ifdef applec |
AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbBkColor)); |
#else |
AddRGBColor(&((*(CGrafPtr)thePort).rgbBkColor)); |
#endif |
} |
/* Add colors from a PixPat to a color table. */ |
void AddPixPat(PixPatHandle pPat) |
{ |
switch ((**pPat).patType) { |
case 0: /* one-bit patterns are drawn in the foreground and background color. */ |
AddRGBForeColor(); |
AddRGBBackColor(); |
break; |
case 1: /* Type 1 PixPats have a color table. */ |
AddColorTable((**(**pPat).patMap).pmTable); |
break; |
} |
} |
/* Add colors from the pen PixPat to the color table. */ |
void AddPenPixPat() |
{ |
#ifdef applec |
AddPixPat((*(CGrafPtr)qd.thePort).pnPixPat); |
#else |
AddPixPat((*(CGrafPtr)thePort).pnPixPat); |
#endif |
} |
/* Add colors from the fill PixPat to the color table. */ |
void AddFillPixPat() |
{ |
#ifdef applec |
AddPixPat((*(CGrafPtr)qd.thePort).fillPixPat); |
#else |
AddPixPat((*(CGrafPtr)thePort).fillPixPat); |
#endif |
} |
/* Add colors because we are about to draw an object. */ |
void AddVerb(GrafVerb verb) |
{ |
switch (verb) { |
case kQDGrafVerbFrame: |
case kQDGrafVerbPaint: /* Framed and painted objects are drawn in the pen PixPat. */ |
AddPenPixPat(); |
break; |
case kQDGrafVerbErase: /* Erased objects are drawn in the background color. */ |
AddRGBBackColor(); |
break; |
case kQDGrafVerbFill: |
/* Filled objects are drawn in the fill PixPat. The fillPixPat is |
a pattern used to record fill commands for pictures. First, a |
command to set the fillPixPat is recorded, then the fill command |
is recorded. */ |
AddFillPixPat(); |
} |
} |
/* bottleneck routines follow . . . */ |
pascal void ColorTextProc(short byteCount, Ptr textBuf, Point numer, Point denom) |
{ /* Text is drawn with the foreground and background colors.*/ |
#ifdef applec |
#pragma unused (byteCount, textBuf, numer, denom) |
#endif |
AddRGBForeColor(); |
AddRGBBackColor(); |
} |
pascal void ColorLineProc(Point newPt) |
{ /* Lines are drawn with the pen PixPat. */ |
#ifdef applec |
#pragma unused (newPt) |
#endif |
AddPenPixPat(); |
} |
pascal void ColorRectProc(GrafVerb verb,Rect* r) |
{ |
#ifdef applec |
#pragma unused (r) |
#endif |
AddVerb(verb); |
} |
pascal void ColorRRectProc(GrafVerb verb,Rect* r, short ovalWidth,short ovalHeight) |
{ |
#ifdef applec |
#pragma unused (r, ovalWidth, ovalHeight) |
#endif |
AddVerb(verb); |
} |
pascal void ColorOvalProc(GrafVerb verb,Rect r) |
{ |
#ifdef applec |
#pragma unused (r) |
#endif |
AddVerb(verb); |
} |
pascal void ColorArcProc(GrafVerb verb,Rect* r,short startAngle,short arcAngle) |
{ |
#ifdef applec |
#pragma unused (r, startAngle, arcAngle) |
#endif |
AddVerb(verb); |
} |
pascal void ColorPolyProc(GrafVerb verb, PolyHandle poly) |
{ |
#ifdef applec |
#pragma unused (poly) |
#endif |
AddVerb(verb); |
} |
pascal void ColorRgnProc(GrafVerb verb,RgnHandle rgn) |
{ |
#ifdef applec |
#pragma unused (rgn) |
#endif |
AddVerb(verb); |
} |
pascal void ColorBitsProc(BitMap* BitsPtr,Rect srcRect, Rect dstRect,short mode,RgnHandle maskRgn) |
{ |
#ifdef applec |
#pragma unused (srcRect, dstRect, mode, maskRgn) |
#endif |
PixMapPtr aPixMap; |
short tempRB; |
/* Get the PixMap that we are about to draw. SrcBits might be a BitMap, or |
one of two different kinds of PixMap pointers. */ |
tempRB = BitsPtr->rowBytes; /* local copy of rowBytes */ |
if (tempRB < 0) { /* high bit set? */ |
if ((tempRB<<1) < 0) /* next to high bit set? */ |
aPixMap = (PixMapPtr)BitsPtr; /* ptr to PixMap handle */ |
else |
aPixMap = (PixMapPtr) BitsPtr; /* pointer to a PixMap */ |
if ((*aPixMap).pixelSize > maxPixDepth) /* deepest pixmap so far? */ |
maxPixDepth = (*aPixMap).pixelSize; |
if ((*aPixMap).pixelType==16) { |
foundDirect = true; |
return; /* direct pixmap? eek! */ |
} |
AddColorTable((*aPixMap).pmTable); /* it has its own color table. */ |
} |
else { |
/* It's just a BitMap; it will use the background and foreground colors. */ |
AddRGBBackColor(); |
AddRGBForeColor(); |
} |
} |
RGBColor whiteRGB = { 0xFFFF,0xFFFF,0xFFFF }; |
RGBColor blackRGB = { 0,0,0 }; |
CTabHandle CollectColors(PicHandle fromPicture,short * depthPtr,short * directFlagPtr) |
{ |
CTabHandle colors; |
CQDProcs bottlenecks; |
/* Set the bottlenecks. These bottlenecks will figure out what colors are in |
a picture, but won't draw anything. |
Note: the bottlenecks are installed in thePort, which must be a color port. |
*/ |
SetStdCProcs(&bottlenecks); |
bottlenecks.textProc = NewQDTextProc(ColorTextProc); |
bottlenecks.lineProc = NewQDLineProc(ColorLineProc); |
bottlenecks.rectProc = NewQDRectProc(ColorRectProc); |
bottlenecks.rRectProc = NewQDRRectProc(ColorRRectProc); |
bottlenecks.ovalProc = NewQDOvalProc(ColorOvalProc); |
bottlenecks.arcProc = NewQDArcProc(ColorArcProc); |
bottlenecks.polyProc = NewQDPolyProc(ColorPolyProc); |
bottlenecks.rgnProc = NewQDRgnProc(ColorRgnProc); |
bottlenecks.bitsProc =NewQDBitsProc(ColorBitsProc); |
/* Create a color table containing black and white. */ |
foundDirect = false; /* haven't found a direct pixmap yet */ |
maxPixDepth = 1; /* assume we will find a bitmap */ |
colors = (CTabHandle) NewHandle( sizeof(ColorTable) + sizeof(ColorSpec) ); |
if (colors) { |
(**colors).ctSize = 1; /* 2 entries */ |
#ifdef applec |
(**colors).ctFlags = 0x8000; |
#else |
(**colors).transIndex = 0x8000; |
#endif |
(**colors).ctSeed = GetCTSeed(); |
(**colors).ctTable[0].rgb = whiteRGB; /*first entry is white*/ |
(**colors).ctTable[1].rgb = blackRGB; /*second entry is black*/ |
/* Now play back the picture to get the colors. The dstRect doesn't |
matter since our bottlenecks will never actually draw. We use global |
variables (gColorError and gColorTable) to communicate with the |
bottlenecks. */ |
#ifdef applec |
(*(qd.thePort)).grafProcs = (QDProcs *) &bottlenecks; |
#else |
(*thePort).grafProcs = (QDProcs *) &bottlenecks; |
#endif |
gColorError = noErr; |
gColorTable = colors; |
DrawPicture(fromPicture, &((**fromPicture).picFrame)); |
#ifdef applec |
(*(qd.thePort)).grafProcs = 0L; |
#else |
(*thePort).grafProcs = 0L; |
#endif |
*depthPtr = maxPixDepth; |
*directFlagPtr = foundDirect; |
/* Fail if error occurred while within the color bottlenecks. */ |
if (gColorError != noErr) { |
DisposeHandle((Handle)colors); |
colors = 0L; |
} |
} |
return colors; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-10