diff --git a/confscreen.cpp b/confscreen.cpp
index 30229f5..705518a 100644
--- a/confscreen.cpp
+++ b/confscreen.cpp
@@ -172,13 +172,13 @@ void TextWindow::ShowConfiguration(void) {
Printf(true, "%Ft user color (r, g, b)");
for(i = 0; i < SS.MODEL_COLORS; i++) {
- Printf(false, "%Bp #%d: %Bp %Bp (%@, %@, %@) %f%D%Ll%Fl[change]%E",
+ Printf(false, "%Bp #%d: %Bz %Bp (%@, %@, %@) %f%D%Ll%Fl[change]%E",
(i & 1) ? 'd' : 'a',
- i, 0x80000000 | SS.modelColor[i],
+ i, &SS.modelColor[i],
(i & 1) ? 'd' : 'a',
- REDf(SS.modelColor[i]),
- GREENf(SS.modelColor[i]),
- BLUEf(SS.modelColor[i]),
+ SS.modelColor[i].redF(),
+ SS.modelColor[i].greenF(),
+ SS.modelColor[i].blueF(),
&ScreenChangeColor, i);
}
diff --git a/draw.cpp b/draw.cpp
index 0296e33..b011dc8 100644
--- a/draw.cpp
+++ b/draw.cpp
@@ -61,8 +61,8 @@ void GraphicsWindow::Selection::Draw(void) {
topLeft = topLeft.Minus(SS.GW.offset);
glLineWidth(40);
- uint32_t rgb = Style::Color(Style::HOVERED);
- glColor4d(REDf(rgb), GREENf(rgb), BLUEf(rgb), 0.2);
+ RgbColor rgb = Style::Color(Style::HOVERED);
+ glColor4d(rgb.redF(), rgb.greenF(), rgb.blueF(), 0.2);
glBegin(GL_LINES);
glxVertex3v(topLeft);
glxVertex3v(refp);
@@ -512,13 +512,13 @@ void GraphicsWindow::Paint(void) {
glDepthFunc(GL_LEQUAL);
if(SS.AllGroupsOkay()) {
- glClearColor(REDf(SS.backgroundColor),
- GREENf(SS.backgroundColor),
- BLUEf(SS.backgroundColor), 1.0f);
+ glClearColor(SS.backgroundColor.redF(),
+ SS.backgroundColor.greenF(),
+ SS.backgroundColor.blueF(), 1.0f);
} else {
// Draw a different background whenever we're having solve problems.
- uint32_t rgb = Style::Color(Style::DRAW_ERROR);
- glClearColor(0.4f*REDf(rgb), 0.4f*GREENf(rgb), 0.4f*BLUEf(rgb), 1.0f);
+ RgbColor rgb = Style::Color(Style::DRAW_ERROR);
+ glClearColor(0.4f*rgb.redF(), 0.4f*rgb.greenF(), 0.4f*rgb.blueF(), 1.0f);
// And show the text window, which has info to debug it
ForceTextWindowShown();
}
diff --git a/drawconstraint.cpp b/drawconstraint.cpp
index 81e230c..7c01a0a 100644
--- a/drawconstraint.cpp
+++ b/drawconstraint.cpp
@@ -562,11 +562,11 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
// Let's adjust the color of this constraint to have the same
// rough luma as the point color, so that the constraint does not
// stand out in an ugly way.
- uint32_t cd = Style::Color(Style::DATUM),
+ RgbColor cd = Style::Color(Style::DATUM),
cc = Style::Color(Style::CONSTRAINT);
// convert from 8-bit color to a vector
- Vector vd = Vector::From(REDf(cd), GREENf(cd), BLUEf(cd)),
- vc = Vector::From(REDf(cc), GREENf(cc), BLUEf(cc));
+ Vector vd = Vector::From(cd.redF(), cd.greenF(), cd.blueF()),
+ vc = Vector::From(cc.redF(), cc.greenF(), cc.blueF());
// and scale the constraint color to have the same magnitude as
// the datum color, maybe a bit dimmer
vc = vc.WithMagnitude(vd.Magnitude()*0.9);
diff --git a/dsc.h b/dsc.h
index 433b22b..7f3bafb 100644
--- a/dsc.h
+++ b/dsc.h
@@ -395,4 +395,70 @@ public:
void Solve(void);
};
+#undef RGB
+#define RGB(r, g, b) RgbColor::From((r), (g), (b))
+#define RGBf(r, g, b) RgbColor::FromFloat((float)(r), (float)(g), (float)(b))
+#define NULL_COLOR RgbColor::Default()
+
+// Note: sizeof(class RgbColor) should be exactly 4
+//
+class RgbColor {
+ uint8_t useDefault;
+public:
+ uint8_t red, green, blue;
+
+ float redF(void) const { return (float)red / 255.0f; }
+ float greenF(void) const { return (float)green / 255.0f; }
+ float blueF(void) const { return (float)blue / 255.0f; }
+
+ bool UseDefault(void) const { return useDefault != 0; }
+
+ bool Equals(RgbColor c) const {
+ switch(c.useDefault + useDefault) {
+ case 0: return
+ c.red == red &&
+ c.green == green &&
+ c.blue == blue;
+ case 1: return false;
+ case 2: return true;
+ }
+ return false;
+ }
+
+ uint32_t ToPackedInt(void) const {
+ return red | (uint32_t)(green << 8) | (uint32_t)(blue << 16);
+ }
+
+ static RgbColor Default(void) {
+ RgbColor c;
+ c.useDefault = 1;
+ // Leave r, g, b uninitialized so that Valgrind will notice
+ // if they are used inadvertently
+ return c;
+ }
+
+ static RgbColor From(int r, int g, int b) {
+ RgbColor c;
+ c.useDefault = 0;
+ c.red = (uint8_t)r;
+ c.green = (uint8_t)g;
+ c.blue = (uint8_t)b;
+ return c;
+ }
+
+ static RgbColor FromFloat(float r, float g, float b) {
+ return From(
+ (int)(255.1f * r),
+ (int)(255.1f * g),
+ (int)(255.1f * b));
+ }
+
+ static RgbColor FromPackedInt(uint32_t bgr) {
+ return From(
+ (int)((bgr) & 0xff),
+ (int)((bgr >> 8) & 0xff),
+ (int)((bgr >> 16) & 0xff));
+ }
+};
+
#endif
diff --git a/export.cpp b/export.cpp
index 369fca6..6a3c1b3 100644
--- a/export.cpp
+++ b/export.cpp
@@ -282,9 +282,9 @@ void SolveSpace::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm,
double lighting = SS.ambientIntensity +
max(0, (SS.lightIntensity[0])*(n.Dot(l0))) +
max(0, (SS.lightIntensity[1])*(n.Dot(l1)));
- double r = min(1, REDf (tt.meta.color)*lighting),
- g = min(1, GREENf(tt.meta.color)*lighting),
- b = min(1, BLUEf (tt.meta.color)*lighting);
+ double r = min(1, tt.meta.color.redF() *lighting),
+ g = min(1, tt.meta.color.greenF()*lighting),
+ b = min(1, tt.meta.color.blueF() *lighting);
tt.meta.color = RGBf(r, g, b);
smp.AddTriangle(&tt);
}
@@ -505,9 +505,9 @@ void VectorFileWriter::Output(SBezierLoopSetSet *sblss, SMesh *sm) {
hStyle hs = { (uint32_t)b->auxA };
Style *stl = Style::Get(hs);
- double lineWidth = Style::WidthMm(b->auxA)*s;
- uint32_t strokeRgb = Style::Color(hs, true);
- uint32_t fillRgb = Style::FillColor(hs, true);
+ double lineWidth = Style::WidthMm(b->auxA)*s;
+ RgbColor strokeRgb = Style::Color(hs, true);
+ RgbColor fillRgb = Style::FillColor(hs, true);
StartPath(strokeRgb, lineWidth, stl->filled, fillRgb);
for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
diff --git a/exportvector.cpp b/exportvector.cpp
index f98dc33..1e4790b 100644
--- a/exportvector.cpp
+++ b/exportvector.cpp
@@ -64,12 +64,12 @@ void DxfFileWriter::StartFile(void) {
"ENTITIES\r\n");
}
-void DxfFileWriter::StartPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void DxfFileWriter::StartPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
}
-void DxfFileWriter::FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void DxfFileWriter::FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
}
@@ -165,14 +165,14 @@ void EpsFileWriter::StartFile(void) {
MmToPts(ptMax.y - ptMin.y));
}
-void EpsFileWriter::StartPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void EpsFileWriter::StartPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
fprintf(f, "newpath\r\n");
prevPt = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE);
}
-void EpsFileWriter::FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void EpsFileWriter::FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
fprintf(f, " %.3f setlinewidth\r\n"
" %.3f %.3f %.3f setrgbcolor\r\n"
@@ -180,11 +180,11 @@ void EpsFileWriter::FinishPath(uint32_t strokeRgb, double lineWidth,
" 1 setlinecap\r\n" // rounded
" gsave stroke grestore\r\n",
MmToPts(lineWidth),
- REDf(strokeRgb), GREENf(strokeRgb), BLUEf(strokeRgb));
+ strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF());
if(filled) {
fprintf(f, " %.3f %.3f %.3f setrgbcolor\r\n"
" gsave fill grestore\r\n",
- REDf(fillRgb), GREENf(fillRgb), BLUEf(fillRgb));
+ fillRgb.redF(), fillRgb.greenF(), fillRgb.blueF());
}
}
@@ -205,7 +205,7 @@ void EpsFileWriter::Triangle(STriangle *tr) {
" %.3f %.3f lineto\r\n"
" closepath\r\n"
"gsave fill grestore\r\n",
- REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
+ tr->meta.color.redF(), tr->meta.color.greenF(), tr->meta.color.blueF(),
MmToPts(tr->a.x - ptMin.x), MmToPts(tr->a.y - ptMin.y),
MmToPts(tr->b.x - ptMin.x), MmToPts(tr->b.y - ptMin.y),
MmToPts(tr->c.x - ptMin.x), MmToPts(tr->c.y - ptMin.y));
@@ -390,23 +390,23 @@ void PdfFileWriter::FinishAndCloseFile(void) {
}
-void PdfFileWriter::StartPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void PdfFileWriter::StartPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
fprintf(f, "1 J 1 j " // round endcaps and joins
"%.3f w "
"%.3f %.3f %.3f RG\r\n",
MmToPts(lineWidth),
- REDf(strokeRgb), GREENf(strokeRgb), BLUEf(strokeRgb));
+ strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF());
if(filled) {
fprintf(f, "%.3f %.3f %.3f rg\r\n",
- REDf(fillRgb), GREENf(fillRgb), BLUEf(fillRgb));
+ fillRgb.redF(), fillRgb.greenF(), fillRgb.blueF());
}
prevPt = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE);
}
-void PdfFileWriter::FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void PdfFileWriter::FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
if(filled) {
fprintf(f, "b\r\n");
@@ -435,8 +435,8 @@ void PdfFileWriter::Triangle(STriangle *tr) {
"%.3f %.3f l\r\n"
"%.3f %.3f l\r\n"
"b\r\n",
- REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
- REDf(tr->meta.color), GREENf(tr->meta.color), BLUEf(tr->meta.color),
+ tr->meta.color.redF(), tr->meta.color.greenF(), tr->meta.color.blueF(),
+ tr->meta.color.redF(), tr->meta.color.greenF(), tr->meta.color.blueF(),
MmToPts(sw),
MmToPts(tr->a.x - ptMin.x), MmToPts(tr->a.y - ptMin.y),
MmToPts(tr->b.x - ptMin.x), MmToPts(tr->b.y - ptMin.y),
@@ -480,26 +480,26 @@ void SvgFileWriter::StartFile(void) {
// A little bit of extra space for the stroke width.
}
-void SvgFileWriter::StartPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void SvgFileWriter::StartPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
fprintf(f, "\r\n",
- lineWidth, RED(strokeRgb), GREEN(strokeRgb), BLUE(strokeRgb),
+ lineWidth, strokeRgb.red, strokeRgb.green, strokeRgb.blue,
fill);
}
@@ -523,9 +523,9 @@ void SvgFileWriter::Triangle(STriangle *tr) {
(tr->a.x - ptMin.x), (ptMax.y - tr->a.y),
(tr->b.x - ptMin.x), (ptMax.y - tr->b.y),
(tr->c.x - ptMin.x), (ptMax.y - tr->c.y),
- RED(tr->meta.color), GREEN(tr->meta.color), BLUE(tr->meta.color),
+ tr->meta.color.red, tr->meta.color.green, tr->meta.color.blue,
sw,
- RED(tr->meta.color), GREEN(tr->meta.color), BLUE(tr->meta.color));
+ tr->meta.color.red, tr->meta.color.green, tr->meta.color.blue);
}
void SvgFileWriter::Bezier(SBezier *sb) {
@@ -585,12 +585,12 @@ void HpglFileWriter::StartFile(void) {
fprintf(f, "SP1;\r\n");
}
-void HpglFileWriter::StartPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void HpglFileWriter::StartPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
}
-void HpglFileWriter::FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void HpglFileWriter::FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
}
@@ -622,12 +622,12 @@ void HpglFileWriter::FinishAndCloseFile(void) {
void GCodeFileWriter::StartFile(void) {
ZERO(&sel);
}
-void GCodeFileWriter::StartPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void GCodeFileWriter::StartPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
}
-void GCodeFileWriter::FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void GCodeFileWriter::FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
}
void GCodeFileWriter::Triangle(STriangle *tr) {
@@ -691,12 +691,12 @@ void Step2dFileWriter::StartFile(void) {
void Step2dFileWriter::Triangle(STriangle *tr) {
}
-void Step2dFileWriter::StartPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void Step2dFileWriter::StartPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
}
-void Step2dFileWriter::FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb)
+void Step2dFileWriter::FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb)
{
}
diff --git a/file.cpp b/file.cpp
index ee96c41..db55175 100644
--- a/file.cpp
+++ b/file.cpp
@@ -303,7 +303,7 @@ bool SolveSpace::SaveToFile(char *filename) {
STriangle *tr = &(m->l.elem[i]);
fprintf(fh, "Triangle %08x %08x "
"%.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f\n",
- tr->meta.face, tr->meta.color,
+ tr->meta.face, tr->meta.color.ToPackedInt(),
CO(tr->a), CO(tr->b), CO(tr->c));
}
@@ -311,7 +311,7 @@ bool SolveSpace::SaveToFile(char *filename) {
SSurface *srf;
for(srf = s->surface.First(); srf; srf = s->surface.NextAfter(srf)) {
fprintf(fh, "Surface %08x %08x %08x %d %d\n",
- srf->h.v, srf->color, srf->face, srf->degm, srf->degn);
+ srf->h.v, srf->color.ToPackedInt(), srf->face, srf->degm, srf->degn);
for(i = 0; i <= srf->degm; i++) {
for(j = 0; j <= srf->degn; j++) {
fprintf(fh, "SCtrl %d %d %.20f %.20f %.20f Weight %20.20f\n",
@@ -538,23 +538,27 @@ bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le,
} else if(StrStartsWith(line, "Triangle ")) {
STriangle tr; ZERO(&tr);
+ unsigned int rgb = 0;
if(sscanf(line, "Triangle %x %x "
"%lf %lf %lf %lf %lf %lf %lf %lf %lf",
- &(tr.meta.face), &(tr.meta.color),
+ &(tr.meta.face), &rgb,
&(tr.a.x), &(tr.a.y), &(tr.a.z),
&(tr.b.x), &(tr.b.y), &(tr.b.z),
&(tr.c.x), &(tr.c.y), &(tr.c.z)) != 11)
{
oops();
}
+ tr.meta.color = RgbColor::FromPackedInt((uint32_t)rgb);
m->AddTriangle(&tr);
} else if(StrStartsWith(line, "Surface ")) {
+ unsigned int rgb = 0;
if(sscanf(line, "Surface %x %x %x %d %d",
- &(srf.h.v), &(srf.color), &(srf.face),
+ &(srf.h.v), &rgb, &(srf.face),
&(srf.degm), &(srf.degn)) != 5)
{
oops();
}
+ srf.color = RgbColor::FromPackedInt((uint32_t)rgb);
} else if(StrStartsWith(line, "SCtrl ")) {
int i, j;
Vector c;
diff --git a/glhelper.cpp b/glhelper.cpp
index d7f25df..d0ba662 100644
--- a/glhelper.cpp
+++ b/glhelper.cpp
@@ -178,10 +178,10 @@ void glxFatLine(Vector a, Vector b, double width)
}
-void glxLockColorTo(uint32_t rgb)
+void glxLockColorTo(RgbColor rgb)
{
ColorLocked = false;
- glColor3d(REDf(rgb), GREENf(rgb), BLUEf(rgb));
+ glColor3d(rgb.redF(), rgb.greenF(), rgb.blueF());
ColorLocked = true;
}
@@ -190,16 +190,16 @@ void glxUnlockColor(void)
ColorLocked = false;
}
-void glxColorRGB(uint32_t rgb)
+void glxColorRGB(RgbColor rgb)
{
// Is there a bug in some graphics drivers where this is not equivalent
// to glColor3d? There seems to be...
glxColorRGBa(rgb, 1.0);
}
-void glxColorRGBa(uint32_t rgb, double a)
+void glxColorRGBa(RgbColor rgb, double a)
{
- if(!ColorLocked) glColor4d(REDf(rgb), GREENf(rgb), BLUEf(rgb), a);
+ if(!ColorLocked) glColor4d(rgb.redF(), rgb.greenF(), rgb.blueF(), a);
}
static void Stipple(bool forSel)
@@ -233,7 +233,7 @@ static void Stipple(bool forSel)
}
}
-static void StippleTriangle(STriangle *tr, bool s, uint32_t rgb)
+static void StippleTriangle(STriangle *tr, bool s, RgbColor rgb)
{
glEnd();
glDisable(GL_LIGHTING);
@@ -249,25 +249,25 @@ static void StippleTriangle(STriangle *tr, bool s, uint32_t rgb)
glBegin(GL_TRIANGLES);
}
-void glxFillMesh(uint32_t specColor, SMesh *m, uint32_t h, uint32_t s1, uint32_t s2)
+void glxFillMesh(RgbColor specColor, SMesh *m, uint32_t h, uint32_t s1, uint32_t s2)
{
- uint32_t rgbHovered = Style::Color(Style::HOVERED),
+ RgbColor rgbHovered = Style::Color(Style::HOVERED),
rgbSelected = Style::Color(Style::SELECTED);
glEnable(GL_NORMALIZE);
- uint32_t prevColor = (uint32_t)-1;
+ RgbColor prevColor = NULL_COLOR;
glBegin(GL_TRIANGLES);
for(int i = 0; i < m->l.n; i++) {
STriangle *tr = &(m->l.elem[i]);
- uint32_t color;
- if(specColor & 0x80000000) {
+ RgbColor color;
+ if(specColor.UseDefault()) {
color = tr->meta.color;
} else {
color = specColor;
}
- if(color != prevColor) {
- GLfloat mpf[] = { REDf(color), GREENf(color), BLUEf(color), 1.0 };
+ if(!color.Equals(prevColor)) {
+ GLfloat mpf[] = { color.redF(), color.greenF(), color.blueF(), 1.0f };
glEnd();
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mpf);
prevColor = color;
diff --git a/groupmesh.cpp b/groupmesh.cpp
index 4bfacd2..5fd810a 100644
--- a/groupmesh.cpp
+++ b/groupmesh.cpp
@@ -434,12 +434,12 @@ Group *Group::RunningMeshGroup(void) {
}
void Group::DrawDisplayItems(int t) {
- int specColor;
+ RgbColor specColor;
if(t == DRAWING_3D || t == DRAWING_WORKPLANE) {
// force the color to something dim
specColor = Style::Color(Style::DIM_SOLID);
} else {
- specColor = -1; // use the model color
+ specColor = RgbColor::Default(); // use the model color
}
// The back faces are drawn in red; should never seem them, since we
// draw closed shells, so that's a debugging aid.
diff --git a/polygon.h b/polygon.h
index a42165e..5583406 100644
--- a/polygon.h
+++ b/polygon.h
@@ -123,7 +123,7 @@ public:
typedef struct {
uint32_t face;
- uint32_t color;
+ RgbColor color;
} STriMeta;
class SPolygon {
diff --git a/sketch.h b/sketch.h
index 61231ac..a53957a 100644
--- a/sketch.h
+++ b/sketch.h
@@ -118,7 +118,7 @@ public:
double valA;
double valB;
double valC;
- uint32_t color;
+ RgbColor color;
struct {
int how;
@@ -242,7 +242,7 @@ public:
void GenerateDisplayItems(void);
void DrawDisplayItems(int t);
void Draw(void);
- uint32_t GetLoopSetFillColor(SBezierLoopSet *sbls,
+ RgbColor GetLoopSetFillColor(SBezierLoopSet *sbls,
bool *allSame, Vector *errorAt);
void FillLoopSetAsPolygon(SBezierLoopSet *sbls);
void DrawFilledPaths(void);
@@ -729,9 +729,9 @@ public:
};
int textOrigin;
double textAngle;
- uint32_t color;
+ RgbColor color;
bool filled;
- uint32_t fillColor;
+ RgbColor fillColor;
bool visible;
bool exportable;
@@ -740,7 +740,7 @@ public:
typedef struct {
hStyle h;
const char *cnfPrefix;
- uint32_t color;
+ RgbColor color;
double width;
} Default;
static const Default Defaults[];
@@ -757,13 +757,13 @@ public:
static void AssignSelectionToStyle(uint32_t v);
static uint32_t CreateCustomStyle(void);
- static uint32_t RewriteColor(uint32_t rgb);
+ static RgbColor RewriteColor(RgbColor rgb);
static Style *Get(hStyle hs);
- static uint32_t Color(hStyle hs, bool forExport=false);
- static uint32_t FillColor(hStyle hs, bool forExport=false);
+ static RgbColor Color(hStyle hs, bool forExport=false);
+ static RgbColor FillColor(hStyle hs, bool forExport=false);
static float Width(hStyle hs);
- static uint32_t Color(int hs, bool forExport=false);
+ static RgbColor Color(int hs, bool forExport=false);
static float Width(int hs);
static double WidthMm(int hs);
static double TextHeight(hStyle hs);
diff --git a/solvespace.cpp b/solvespace.cpp
index 1fc31d5..c4fc96e 100644
--- a/solvespace.cpp
+++ b/solvespace.cpp
@@ -15,14 +15,14 @@ void SolveSpace::Init(char *cmdLine) {
// Then, load the registry settings.
int i;
// Default list of colors for the model material
- modelColor[0] = CnfThawInt(RGB(150, 150, 150), "ModelColor_0");
- modelColor[1] = CnfThawInt(RGB(100, 100, 100), "ModelColor_1");
- modelColor[2] = CnfThawInt(RGB( 30, 30, 30), "ModelColor_2");
- modelColor[3] = CnfThawInt(RGB(150, 0, 0), "ModelColor_3");
- modelColor[4] = CnfThawInt(RGB( 0, 100, 0), "ModelColor_4");
- modelColor[5] = CnfThawInt(RGB( 0, 80, 80), "ModelColor_5");
- modelColor[6] = CnfThawInt(RGB( 0, 0, 130), "ModelColor_6");
- modelColor[7] = CnfThawInt(RGB( 80, 0, 80), "ModelColor_7");
+ modelColor[0] = CnfThawColor(RGB(150, 150, 150), "ModelColor_0");
+ modelColor[1] = CnfThawColor(RGB(100, 100, 100), "ModelColor_1");
+ modelColor[2] = CnfThawColor(RGB( 30, 30, 30), "ModelColor_2");
+ modelColor[3] = CnfThawColor(RGB(150, 0, 0), "ModelColor_3");
+ modelColor[4] = CnfThawColor(RGB( 0, 100, 0), "ModelColor_4");
+ modelColor[5] = CnfThawColor(RGB( 0, 80, 80), "ModelColor_5");
+ modelColor[6] = CnfThawColor(RGB( 0, 0, 130), "ModelColor_6");
+ modelColor[7] = CnfThawColor(RGB( 80, 0, 80), "ModelColor_7");
// Light intensities
lightIntensity[0] = CnfThawFloat(1.0f, "LightIntensity_0");
lightIntensity[1] = CnfThawFloat(0.5f, "LightIntensity_1");
@@ -62,7 +62,7 @@ void SolveSpace::Init(char *cmdLine) {
// Export pwl curves (instead of exact) always
exportPwlCurves = CnfThawBool(false, "ExportPwlCurves");
// Background color on-screen
- backgroundColor = CnfThawInt(RGB(0, 0, 0), "BackgroundColor");
+ backgroundColor = CnfThawColor(RGB(0, 0, 0), "BackgroundColor");
// Whether export canvas size is fixed or derived from bbox
exportCanvasSizeAuto = CnfThawBool(true, "ExportCanvasSizeAuto");
// Margins for automatic canvas size
@@ -120,7 +120,7 @@ void SolveSpace::Exit(void) {
// Model colors
for(i = 0; i < MODEL_COLORS; i++) {
sprintf(name, "ModelColor_%d", i);
- CnfFreezeInt(modelColor[i], name);
+ CnfFreezeColor(modelColor[i], name);
}
// Light intensities
CnfFreezeFloat((float)lightIntensity[0], "LightIntensity_0");
@@ -160,7 +160,7 @@ void SolveSpace::Exit(void) {
// Export pwl curves (instead of exact) always
CnfFreezeBool(exportPwlCurves, "ExportPwlCurves");
// Background color on-screen
- CnfFreezeInt(backgroundColor, "BackgroundColor");
+ CnfFreezeColor(backgroundColor, "BackgroundColor");
// Whether export canvas size is fixed or derived from bbox
CnfFreezeBool(exportCanvasSizeAuto, "ExportCanvasSizeAuto");
// Margins for automatic canvas size
diff --git a/solvespace.h b/solvespace.h
index 4013103..1760e0c 100644
--- a/solvespace.h
+++ b/solvespace.h
@@ -82,6 +82,7 @@ inline double Random(double vmax) {
class Expr;
class ExprVector;
class ExprQuaternion;
+class RgbColor;
//================
@@ -178,11 +179,9 @@ void ExitNow(void);
void CnfFreezeString(const char *str, const char *name);
void CnfFreezeInt(uint32_t v, const char *name);
void CnfFreezeFloat(float v, const char *name);
-void CnfFreezeBool(bool v, const char *name);
void CnfThawString(char *str, int maxLen, const char *name);
uint32_t CnfThawInt(uint32_t v, const char *name);
float CnfThawFloat(float v, const char *name);
-bool CnfThawBool(bool v, const char *name);
void *AllocTemporary(size_t n);
void FreeTemporary(void *p);
@@ -223,7 +222,7 @@ void glxAxisAlignedLineLoop(double l, double r, double t, double b);
typedef void GLX_CALLBACK glxCallbackFptr(void);
void glxTesselatePolygon(GLUtesselator *gt, SPolygon *p);
void glxFillPolygon(SPolygon *p);
-void glxFillMesh(uint32_t color, SMesh *m, uint32_t h, uint32_t s1, uint32_t s2);
+void glxFillMesh(RgbColor color, SMesh *m, uint32_t h, uint32_t s1, uint32_t s2);
void glxDebugPolygon(SPolygon *p);
void glxDrawEdges(SEdgeList *l, bool endpointsToo);
void glxDebugMesh(SMesh *m);
@@ -235,11 +234,11 @@ void glxWriteTextRefCenter(const char *str, double h, Vector t, Vector u, Vector
glxLineFn *fn, void *fndata);
double glxStrWidth(const char *str, double h);
double glxStrHeight(double h);
-void glxLockColorTo(uint32_t rgb);
+void glxLockColorTo(RgbColor rgb);
void glxFatLine(Vector a, Vector b, double width);
void glxUnlockColor(void);
-void glxColorRGB(uint32_t rgb);
-void glxColorRGBa(uint32_t rgb, double a);
+void glxColorRGB(RgbColor rgb);
+void glxColorRGBa(RgbColor rgb, double a);
void glxDepthRangeOffset(int units);
void glxDepthRangeLockToFront(bool yes);
void glxDrawPixelsWithTexture(uint8_t *data, int w, int h);
@@ -266,6 +265,10 @@ bool StringAllPrintable(const char *str);
bool StringEndsIn(const char *str, const char *ending);
void Message(const char *str, ...);
void Error(const char *str, ...);
+void CnfFreezeBool(bool v, const char *name);
+void CnfFreezeColor(RgbColor v, const char *name);
+bool CnfThawBool(bool v, const char *name);
+RgbColor CnfThawColor(RgbColor v, const char *name);
class System {
public:
@@ -459,10 +462,10 @@ public:
void BezierAsPwl(SBezier *sb);
void BezierAsNonrationalCubic(SBezier *sb, int depth=0);
- virtual void StartPath( uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb) = 0;
- virtual void FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb) = 0;
+ virtual void StartPath( RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb) = 0;
+ virtual void FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb) = 0;
virtual void Bezier(SBezier *sb) = 0;
virtual void Triangle(STriangle *tr) = 0;
virtual void StartFile(void) = 0;
@@ -471,10 +474,10 @@ public:
};
class DxfFileWriter : public VectorFileWriter {
public:
- void StartPath( uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
- void FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
+ void StartPath( RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
+ void FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
void Triangle(STriangle *tr);
void Bezier(SBezier *sb);
void StartFile(void);
@@ -486,10 +489,10 @@ public:
Vector prevPt;
void MaybeMoveTo(Vector s, Vector f);
- void StartPath( uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
- void FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
+ void StartPath( RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
+ void FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
void Triangle(STriangle *tr);
void Bezier(SBezier *sb);
void StartFile(void);
@@ -503,10 +506,10 @@ public:
Vector prevPt;
void MaybeMoveTo(Vector s, Vector f);
- void StartPath( uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
- void FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
+ void StartPath( RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
+ void FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
void Triangle(STriangle *tr);
void Bezier(SBezier *sb);
void StartFile(void);
@@ -518,10 +521,10 @@ public:
Vector prevPt;
void MaybeMoveTo(Vector s, Vector f);
- void StartPath( uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
- void FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
+ void StartPath( RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
+ void FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
void Triangle(STriangle *tr);
void Bezier(SBezier *sb);
void StartFile(void);
@@ -531,10 +534,10 @@ public:
class HpglFileWriter : public VectorFileWriter {
public:
static double MmToHpglUnits(double mm);
- void StartPath( uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
- void FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
+ void StartPath( RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
+ void FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
void Triangle(STriangle *tr);
void Bezier(SBezier *sb);
void StartFile(void);
@@ -543,10 +546,10 @@ public:
};
class Step2dFileWriter : public VectorFileWriter {
StepFileWriter sfw;
- void StartPath( uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
- void FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
+ void StartPath( RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
+ void FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
void Triangle(STriangle *tr);
void Bezier(SBezier *sb);
void StartFile(void);
@@ -556,10 +559,10 @@ class Step2dFileWriter : public VectorFileWriter {
class GCodeFileWriter : public VectorFileWriter {
public:
SEdgeList sel;
- void StartPath( uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
- void FinishPath(uint32_t strokeRgb, double lineWidth,
- bool filled, uint32_t fillRgb);
+ void StartPath( RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
+ void FinishPath(RgbColor strokeRgb, double lineWidth,
+ bool filled, RgbColor fillRgb);
void Triangle(STriangle *tr);
void Bezier(SBezier *sb);
void StartFile(void);
@@ -640,7 +643,7 @@ public:
// Little bits of extra configuration state
enum { MODEL_COLORS = 8 };
- uint32_t modelColor[MODEL_COLORS];
+ RgbColor modelColor[MODEL_COLORS];
Vector lightDir[2];
double lightIntensity[2];
double ambientIntensity;
@@ -654,7 +657,7 @@ public:
bool drawBackFaces;
bool checkClosedContour;
bool showToolbar;
- uint32_t backgroundColor;
+ RgbColor backgroundColor;
bool exportShadedTriangles;
bool exportPwlCurves;
bool exportCanvasSizeAuto;
diff --git a/srf/merge.cpp b/srf/merge.cpp
index eacd6d6..9dd256a 100644
--- a/srf/merge.cpp
+++ b/srf/merge.cpp
@@ -34,7 +34,7 @@ void SShell::MergeCoincidentSurfaces(void) {
sj = &(surface.elem[j]);
if(sj->tag) continue;
if(!sj->CoincidentWith(si, true)) continue;
- if(sj->color != si->color) continue;
+ if(!sj->color.Equals(si->color)) continue;
// But we do merge surfaces with different face entities, since
// otherwise we'd hardly ever merge anything.
diff --git a/srf/surface.cpp b/srf/surface.cpp
index 8557836..40180b9 100644
--- a/srf/surface.cpp
+++ b/srf/surface.cpp
@@ -490,7 +490,7 @@ typedef struct {
} TrimLine;
void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
- uint32_t color)
+ RgbColor color)
{
// Make the extrusion direction consistent with respect to the normal
// of the sketch we're extruding.
@@ -610,7 +610,7 @@ typedef struct {
} Revolved;
void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
- uint32_t color)
+ RgbColor color)
{
SBezierLoop *sbl;
diff --git a/srf/surface.h b/srf/surface.h
index 2706790..03ad26f 100644
--- a/srf/surface.h
+++ b/srf/surface.h
@@ -250,7 +250,7 @@ public:
// when I copy things over.
hSSurface newH;
- uint32_t color;
+ RgbColor color;
uint32_t face;
int degm, degn;
@@ -361,9 +361,9 @@ public:
bool booleanFailed;
void MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
- uint32_t color);
+ RgbColor color);
void MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
- uint32_t color);
+ RgbColor color);
void MakeFromUnionOf(SShell *a, SShell *b);
void MakeFromDifferenceOf(SShell *a, SShell *b);
diff --git a/style.cpp b/style.cpp
index c647e55..d5e2bee 100644
--- a/style.cpp
+++ b/style.cpp
@@ -22,7 +22,7 @@ const Style::Default Style::Defaults[] = {
{ { ANALYZE }, "Analyze", RGBf(0.0, 1.0, 1.0), 1.0, },
{ { DRAW_ERROR }, "DrawError", RGBf(1.0, 0.0, 0.0), 8.0, },
{ { DIM_SOLID }, "DimSolid", RGBf(0.1, 0.1, 0.1), 1.0, },
- { { 0 }, NULL, 0, 0.0, }
+ { { 0 }, NULL, NULL_COLOR, 0.0 }
};
char *Style::CnfColor(const char *prefix) {
@@ -74,7 +74,7 @@ void Style::CreateDefaultStyle(hStyle h) {
Style ns;
ZERO(&ns);
- ns.color = CnfThawInt(d->color, CnfColor(d->cnfPrefix));
+ ns.color = CnfThawColor(d->color, CnfColor(d->cnfPrefix));
ns.width = CnfThawFloat((float)(d->width), CnfWidth(d->cnfPrefix));
ns.widthAs = UNITS_AS_PIXELS;
ns.textHeight = DEFAULT_TEXT_HEIGHT;
@@ -121,7 +121,7 @@ void Style::LoadFactoryDefaults(void) {
void Style::FreezeDefaultStyles(void) {
const Default *d;
for(d = &(Defaults[0]); d->h.v; d++) {
- CnfFreezeInt(Color(d->h), CnfColor(d->cnfPrefix));
+ CnfFreezeColor(Color(d->h), CnfColor(d->cnfPrefix));
CnfFreezeFloat((float)Width(d->h), CnfWidth(d->cnfPrefix));
}
}
@@ -197,7 +197,7 @@ Style *Style::Get(hStyle h) {
// A couple of wrappers, so that I can call these functions with either an
// hStyle or with the integer corresponding to that hStyle.v.
//-----------------------------------------------------------------------------
-uint32_t Style::Color(int s, bool forExport) {
+RgbColor Style::Color(int s, bool forExport) {
hStyle hs = { (uint32_t)s };
return Color(hs, forExport);
}
@@ -210,8 +210,8 @@ float Style::Width(int s) {
// If a color is almost white, then we can rewrite it to black, just so that
// it won't disappear on file formats with a light background.
//-----------------------------------------------------------------------------
-uint32_t Style::RewriteColor(uint32_t rgbin) {
- Vector rgb = Vector::From(REDf(rgbin), GREENf(rgbin), BLUEf(rgbin));
+RgbColor Style::RewriteColor(RgbColor rgbin) {
+ Vector rgb = Vector::From(rgbin.redF(), rgbin.greenF(), rgbin.blueF());
rgb = rgb.Minus(Vector::From(1, 1, 1));
if(rgb.Magnitude() < 0.4 && SS.fixExportColors) {
// This is an almost-white color in a default style, which is
@@ -227,7 +227,7 @@ uint32_t Style::RewriteColor(uint32_t rgbin) {
//-----------------------------------------------------------------------------
// Return the stroke color associated with our style as 8-bit RGB.
//-----------------------------------------------------------------------------
-uint32_t Style::Color(hStyle h, bool forExport) {
+RgbColor Style::Color(hStyle h, bool forExport) {
Style *s = Get(h);
if(forExport) {
return RewriteColor(s->color);
@@ -239,7 +239,7 @@ uint32_t Style::Color(hStyle h, bool forExport) {
//-----------------------------------------------------------------------------
// Return the fill color associated with our style as 8-bit RGB.
//-----------------------------------------------------------------------------
-uint32_t Style::FillColor(hStyle h, bool forExport) {
+RgbColor Style::FillColor(hStyle h, bool forExport) {
Style *s = Get(h);
if(forExport) {
return RewriteColor(s->fillColor);
@@ -349,7 +349,7 @@ void TextWindow::ScreenCreateCustomStyle(int link, uint32_t v) {
}
void TextWindow::ScreenChangeBackgroundColor(int link, uint32_t v) {
- uint32_t rgb = SS.backgroundColor;
+ RgbColor rgb = SS.backgroundColor;
SS.TW.ShowEditControlWithColorPicker(v, 3, rgb);
SS.TW.edit.meaning = EDIT_BACKGROUND_COLOR;
}
@@ -440,9 +440,9 @@ void TextWindow::ShowListOfStyles(void) {
bool darkbg = false;
Style *s;
for(s = SK.style.First(); s; s = SK.style.NextAfter(s)) {
- Printf(false, "%Bp %Bp %Bp %Fl%Ll%f%D%s%E",
+ Printf(false, "%Bp %Bz %Bp %Fl%Ll%f%D%s%E",
darkbg ? 'd' : 'a',
- 0x80000000 | s->color,
+ &s->color,
darkbg ? 'd' : 'a',
ScreenShowStyleInfo, s->h.v,
s->DescriptionString());
@@ -455,10 +455,10 @@ void TextWindow::ShowListOfStyles(void) {
Printf(false, "");
- uint32_t rgb = SS.backgroundColor;
+ RgbColor rgb = SS.backgroundColor;
Printf(false, "%Ft background color (r, g, b)%E");
Printf(false, "%Ba %@, %@, %@ %Fl%D%f%Ll[change]%E",
- REDf(rgb), GREENf(rgb), BLUEf(rgb),
+ rgb.redF(), rgb.greenF(), rgb.blueF(),
top[rows-1] + 2, &ScreenChangeBackgroundColor);
Printf(false, "");
@@ -549,7 +549,7 @@ void TextWindow::ScreenChangeStyleColor(int link, uint32_t v) {
Style *s = Style::Get(hs);
// Same function used for stroke and fill colors
int row, col, em;
- uint32_t rgb;
+ RgbColor rgb;
if(link == 's') {
row = 15; col = 13;
em = EDIT_STYLE_COLOR;
@@ -738,9 +738,9 @@ void TextWindow::ShowStyleInfo(void) {
}
Printf(true, "%Ft line stroke style%E");
- Printf(false, "%Ba %Ftcolor %E%Bp %Ba (%@, %@, %@) %D%f%Ls%Fl[change]%E",
- 0x80000000 | s->color,
- REDf(s->color), GREENf(s->color), BLUEf(s->color),
+ Printf(false, "%Ba %Ftcolor %E%Bz %Ba (%@, %@, %@) %D%f%Ls%Fl[change]%E",
+ &s->color,
+ s->color.redF(), s->color.greenF(), s->color.blueF(),
s->h.v, ScreenChangeStyleColor);
// The line width, and its units
@@ -776,9 +776,9 @@ void TextWindow::ShowStyleInfo(void) {
Printf(false, "");
Printf(false, "%Ft contour fill style%E");
Printf(false,
- "%Ba %Ftcolor %E%Bp %Ba (%@, %@, %@) %D%f%Lf%Fl[change]%E",
- 0x80000000 | s->fillColor,
- REDf(s->fillColor), GREENf(s->fillColor), BLUEf(s->fillColor),
+ "%Ba %Ftcolor %E%Bz %Ba (%@, %@, %@) %D%f%Lf%Fl[change]%E",
+ &s->fillColor,
+ s->fillColor.redF(), s->fillColor.greenF(), s->fillColor.blueF(),
s->h.v, ScreenChangeStyleColor);
Printf(false, "%Bd %D%f%Lf%c contours are filled%E",
diff --git a/textscreens.cpp b/textscreens.cpp
index df3b44c..3b1be88 100644
--- a/textscreens.cpp
+++ b/textscreens.cpp
@@ -365,9 +365,9 @@ void TextWindow::ShowGroupInfo(void) {
g->type == Group::LATHE)
{
Printf(false,
- "%Bd %Ftcolor %E%Bp %Bd (%@, %@, %@) %f%D%Lf%Fl[change]%E",
- 0x80000000 | g->color,
- REDf(g->color), GREENf(g->color), BLUEf(g->color),
+ "%Bd %Ftcolor %E%Bz %Bd (%@, %@, %@) %f%D%Lf%Fl[change]%E",
+ &g->color,
+ g->color.redF(), g->color.greenF(), g->color.blueF(),
ScreenColor, top[rows-1] + 2);
} else if(g->type == Group::IMPORTED) {
bool sup = g->suppress;
diff --git a/textwin.cpp b/textwin.cpp
index 04d0941..6625da7 100644
--- a/textwin.cpp
+++ b/textwin.cpp
@@ -18,14 +18,14 @@ const TextWindow::Color TextWindow::fgColors[] = {
{ 'i', RGB( 0, 255, 255) },
{ 'g', RGB(160, 160, 160) },
{ 'b', RGB(200, 200, 200) },
- { 0, 0 },
+ { 0, NULL_COLOR }
};
const TextWindow::Color TextWindow::bgColors[] = {
{ 'd', RGB( 0, 0, 0) },
{ 't', RGB( 34, 15, 15) },
{ 'a', RGB( 25, 25, 25) },
{ 'r', RGB(255, 255, 255) },
- { 0, 0 },
+ { 0, NULL_COLOR }
};
bool TextWindow::SPACER = false;
@@ -49,9 +49,9 @@ void TextWindow::MakeColorTable(const Color *in, float *out) {
for(i = 0; in[i].c != 0; i++) {
int c = in[i].c;
if(c < 0 || c > 255) oops();
- out[c*3 + 0] = REDf(in[i].color);
- out[c*3 + 1] = GREENf(in[i].color);
- out[c*3 + 2] = BLUEf(in[i].color);
+ out[c*3 + 0] = in[i].color.redF();
+ out[c*3 + 1] = in[i].color.greenF();
+ out[c*3 + 2] = in[i].color.blueF();
}
}
@@ -85,10 +85,10 @@ void TextWindow::ShowEditControl(int halfRow, int col, char *s) {
ShowTextEditControl(x - 3, y + 2, s);
}
-void TextWindow::ShowEditControlWithColorPicker(int halfRow, int col, uint32_t rgb)
+void TextWindow::ShowEditControlWithColorPicker(int halfRow, int col, RgbColor rgb)
{
char str[1024];
- sprintf(str, "%.2f, %.2f, %.2f", REDf(rgb), GREENf(rgb), BLUEf(rgb));
+ sprintf(str, "%.2f, %.2f, %.2f", rgb.redF(), rgb.greenF(), rgb.blueF());
SS.later.showTW = true;
@@ -131,7 +131,8 @@ void TextWindow::Printf(bool halfLine, const char *fmt, ...) {
}
char fg = 'd';
- int bg = 'd';
+ char bg = 'd';
+ RgbColor bgRgb = NULL_COLOR;
int link = NOT_A_LINK;
uint32_t data = 0;
LinkFunction *f = NULL, *h = NULL;
@@ -201,20 +202,18 @@ void TextWindow::Printf(bool halfLine, const char *fmt, ...) {
case 'F':
case 'B': {
- int color;
- if(fmt[1] == '\0') goto done;
- if(fmt[1] == 'p') {
- color = va_arg(vl, int);
- } else {
- color = fmt[1];
- }
- if((color < 0 || color > 255) && !(color & 0x80000000)) {
- color = 0;
+ char cc = fmt[1]; // color code
+ RgbColor *rgbPtr = NULL;
+ switch(cc) {
+ case 0: goto done; // truncated directive
+ case 'p': cc = (char)va_arg(vl, int); break;
+ case 'z': rgbPtr = va_arg(vl, RgbColor *); break;
}
if(*fmt == 'F') {
- fg = (char)color;
+ fg = cc;
} else {
- bg = color;
+ bg = cc;
+ if(rgbPtr) bgRgb = *rgbPtr;
}
fmt++;
break;
@@ -248,7 +247,7 @@ void TextWindow::Printf(bool halfLine, const char *fmt, ...) {
}
} else {
buf[0] = *fmt;
- buf[1]= '\0';
+ buf[1] = '\0';
}
for(unsigned i = 0; i < strlen(buf); i++) {
@@ -256,6 +255,7 @@ void TextWindow::Printf(bool halfLine, const char *fmt, ...) {
text[r][c] = buf[i];
meta[r][c].fg = fg;
meta[r][c].bg = bg;
+ meta[r][c].bgRgb = bgRgb;
meta[r][c].link = link;
meta[r][c].data = data;
meta[r][c].f = f;
@@ -268,6 +268,7 @@ void TextWindow::Printf(bool halfLine, const char *fmt, ...) {
while(c < MAX_COLS) {
meta[r][c].fg = fg;
meta[r][c].bg = bg;
+ meta[r][c].bgRgb = bgRgb;
c++;
}
@@ -538,8 +539,8 @@ uint8_t *TextWindow::HsvPattern1d(double h, double s) {
void TextWindow::ColorPickerDone(void) {
char str[1024];
- uint32_t rgb = editControl.colorPicker.rgb;
- sprintf(str, "%.2f, %.2f, %.3f", REDf(rgb), GREENf(rgb), BLUEf(rgb));
+ RgbColor rgb = editControl.colorPicker.rgb;
+ sprintf(str, "%.2f, %.2f, %.3f", rgb.redF(), rgb.greenF(), rgb.blueF());
EditControlDone(str);
}
@@ -556,7 +557,7 @@ bool TextWindow::DrawOrHitTestColorPicker(int how, bool leftDown,
if(!editControl.colorPicker.show) return false;
if(how == CLICK || (how == HOVER && leftDown)) InvalidateText();
- static const uint32_t BaseColor[12] = {
+ static const RgbColor BaseColor[12] = {
RGB(255, 0, 0),
RGB( 0, 255, 0),
RGB( 0, 0, 255),
@@ -609,16 +610,16 @@ bool TextWindow::DrawOrHitTestColorPicker(int how, bool leftDown,
for(i = 0; i < WIDTH/2; i++) {
for(j = 0; j < HEIGHT; j++) {
Vector rgb;
- uint32_t d;
+ RgbColor d;
if(i == 0 && j < 8) {
d = SS.modelColor[j];
- rgb = Vector::From(REDf(d), GREENf(d), BLUEf(d));
+ rgb = Vector::From(d.redF(), d.greenF(), d.blueF());
} else if(i == 0) {
double a = (j - 8.0)/3.0;
rgb = Vector::From(a, a, a);
} else {
d = BaseColor[j];
- rgb = Vector::From(REDf(d), GREENf(d), BLUEf(d));
+ rgb = Vector::From(d.redF(), d.greenF(), d.blueF());
if(i >= 2 && i <= 4) {
double a = (i == 2) ? 0.2 : (i == 3) ? 0.3 : 0.4;
rgb = rgb.Plus(Vector::From(a, a, a));
@@ -841,20 +842,21 @@ void TextWindow::Paint(void) {
int fg = meta[r][c].fg;
int bg = meta[r][c].bg;
+ RgbColor bgRgb = meta[r][c].bgRgb;
// On the first pass, all the background quads; on the next
// pass, all the foreground (i.e., font) quads.
if(a == 0) {
int bh = LINE_HEIGHT, adj = -2;
- if(bg & 0x80000000) {
- glColor3f(REDf(bg), GREENf(bg), BLUEf(bg));
+ if(bg == 'z') {
+ glColor3f(bgRgb.redF(), bgRgb.greenF(), bgRgb.blueF());
bh = CHAR_HEIGHT;
adj += 2;
} else {
glColor3fv(&(bgColorTable[bg*3]));
}
- if(!(bg == 'd')) {
+ if(bg != 'd') {
// Move the quad down a bit, so that the descenders
// still have the correct background.
y += adj;
diff --git a/ui.h b/ui.h
index c258d2d..47e426a 100644
--- a/ui.h
+++ b/ui.h
@@ -16,19 +16,9 @@ public:
MAX_ROWS = 2000
};
-#ifndef RGB
-#define RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16))
-#endif
-#define RGBf(r, g, b) RGB((int)(255*(r)), (int)(255*(g)), (int)(255*(b)))
-#define RED(v) (((v) >> 0) & 0xff)
-#define GREEN(v) (((v) >> 8) & 0xff)
-#define BLUE(v) (((v) >> 16) & 0xff)
-#define REDf(v) (RED (v) / 255.0f)
-#define GREENf(v) (GREEN(v) / 255.0f)
-#define BLUEf(v) (BLUE (v) / 255.0f)
typedef struct {
char c;
- uint32_t color;
+ RgbColor color;
} Color;
static const Color fgColors[];
static const Color bgColors[];
@@ -56,7 +46,8 @@ public:
enum { NOT_A_LINK = 0 };
struct {
char fg;
- int bg;
+ char bg;
+ RgbColor bgRgb;
int link;
uint32_t data;
LinkFunction *f;
@@ -206,7 +197,7 @@ public:
int col;
struct {
- uint32_t rgb;
+ RgbColor rgb;
double h, s, v;
bool show;
bool picker1dActive;
@@ -216,7 +207,7 @@ public:
void HideEditControl(void);
void ShowEditControl(int halfRow, int col, char *s);
- void ShowEditControlWithColorPicker(int halfRow, int col, uint32_t rgb);
+ void ShowEditControlWithColorPicker(int halfRow, int col, RgbColor rgb);
void ClearSuper(void);
diff --git a/util.cpp b/util.cpp
index 2b661c7..89bcfb8 100644
--- a/util.cpp
+++ b/util.cpp
@@ -205,6 +205,18 @@ void Message(const char *str, ...)
va_end(f);
}
+void CnfFreezeBool(bool v, const char *name)
+ { CnfFreezeInt(v ? 1 : 0, name); }
+
+void CnfFreezeColor(RgbColor v, const char *name)
+ { CnfFreezeInt(v.ToPackedInt(), name); }
+
+bool CnfThawBool(bool v, const char *name)
+ { return CnfThawInt(v ? 1 : 0, name) != 0; }
+
+RgbColor CnfThawColor(RgbColor v, const char *name)
+ { return RgbColor::FromPackedInt(CnfThawInt(v.ToPackedInt(), name)); }
+
//-----------------------------------------------------------------------------
// Solve a mostly banded matrix. In a given row, there are LEFT_OF_DIAG
diff --git a/win32/w32main.cpp b/win32/w32main.cpp
index 61c3536..b1a9535 100644
--- a/win32/w32main.cpp
+++ b/win32/w32main.cpp
@@ -8,6 +8,8 @@
#include "solvespace.h"
#include
#include
+#undef RGB // our definition clashes with Microsoft's
+#define RGB(r, g, b) ((COLORREF)0)
#include
#include
@@ -83,7 +85,7 @@ static LRESULT CALLBACK MessageProc(HWND hwnd, UINT msg, WPARAM wParam,
HDC hdc = BeginPaint(hwnd, &ps);
int row = 0, col = 0, i;
SelectObject(hdc, FixedFont);
- SetTextColor(hdc, RGB(0, 0, 0));
+ SetTextColor(hdc, 0x000000);
SetBkMode(hdc, TRANSPARENT);
for(i = 0; MessageString[i]; i++) {
if(MessageString[i] == '\n') {
@@ -277,9 +279,6 @@ void CnfFreezeInt(uint32_t v, const char *name)
void CnfFreezeFloat(float v, const char *name)
{ FreezeDWORDF(*((DWORD *)&v), FREEZE_SUBKEY, name); }
-void CnfFreezeBool(bool v, const char *name)
- { FreezeDWORDF((DWORD)v, FREEZE_SUBKEY, name); }
-
void CnfThawString(char *str, int maxLen, const char *name)
{ ThawStringF(str, maxLen, FREEZE_SUBKEY, name); }
@@ -291,9 +290,6 @@ float CnfThawFloat(float v, const char *name) {
return *((float *)&d);
}
-bool CnfThawBool(bool v, const char *name)
- { return ThawDWORDF((DWORD)v, FREEZE_SUBKEY, name) ? true : false; }
-
void SetWindowTitle(const char *str) {
SetWindowText(GraphicsWnd, str);
}