/* * Copyright (c) 1989 Stanford University * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Stanford not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Stanford makes no representations about * the suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Logo object implementation. */ #include "logo.h" #include #include #include #include #include #include #include #include #include #include #include Logo::Logo () { SetClassName("Logo"); input = new Sensor(); input->Catch(KeyEvent); bitmap = nil; rainbow = 0; } void Logo::Handle (Event& e) { if (e.eventType == KeyEvent && e.keystring[0] == 'q') { e.target = nil; } } void Logo::Reconfig () { const char* name = GetAttribute("bitmap"); rainbow = atoi(GetAttribute("rainbow")); if (bitmap == nil) { if (name != nil) { bitmap = new Bitmap(name); } } if (bitmap != nil) { // if (bitmap->Valid()) { shape->width = bitmap->Width(); shape->height = bitmap->Height(); // } else { // fprintf(stderr, "logo: cannot open bitmap file `%s'\n", name); // exit(1); // } } else { shape->width = 65; shape->height = 65; } } void Logo::DrawBitmap () { Transformer* oldt = output->GetTransformer(); Transformer t; t.Scale(float(xmax+1)/bitmap->Width(), float(ymax+1)/bitmap->Height()); output->SetTransformer(&t); output->Stencil( canvas, -bitmap->Left(), -bitmap->Bottom(), bitmap, bitmap ); output->SetTransformer(oldt); output->SetOrigin(0, 0); } static Coord poly1_x[] = { 0, 245, 200, 350, 450, 50, 50, 100, 0}; static Coord poly1_y[] = { 71, 314, 350, 350, 450, 450, 310, 310, 210}; static int poly1_count = sizeof(poly1_x)/sizeof(Coord); static Coord poly2_x[] = { 0, 550, 650, 0}; static Coord poly2_y[] = { 550, 550, 650, 650}; static int poly2_count = sizeof(poly2_x)/sizeof(Coord); void do_draw ( Painter* painter, Canvas* canvas, float rotate, float scalex, float scaley ) { Transformer* oldt = painter->GetTransformer(); Transformer t; t.Rotate(rotate); t.Scale(scalex, scaley); painter->SetTransformer(&t); painter->FillPolygon(canvas, poly1_x, poly1_y, poly1_count); painter->FillPolygon(canvas, poly2_x, poly2_y, poly2_count); painter->SetTransformer(oldt); } void Logo::DrawPolygon () { float scalex = float(xmax+2)/1300; float scaley = float(ymax+2)/1300; output->SetOrigin(xmax/2, ymax/2); do_draw(output, canvas, 0, scalex, scaley); do_draw(output, canvas, 90, scalex, -scaley); do_draw(output, canvas, 90, scalex, scaley); do_draw(output, canvas, 0, scalex, -scaley); do_draw(output, canvas, 0, -scalex, -scaley); do_draw(output, canvas, 90, -scalex, scaley); do_draw(output, canvas, 90, -scalex, -scaley); do_draw(output, canvas, 0, -scalex, scaley); output->SetOrigin(0, 0); } static float red_profile[] = { 1.0, 1.0, 1.0, 0.0, 0.0, 0.5, 1.0 }; static float green_profile[] = { 0.0, 0.5, 1.0, 0.8, 0.0, 0.0, 0.0 }; static float blue_profile[] = { 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 }; static int profile_count = sizeof(red_profile)/sizeof(float); static unsigned intensity (float hue, float* profile, int count) { int index = min(int(floor(hue * (count-1))), count-1); float i = ( profile[index] + (hue * (count-1) - index) * (profile[index+1] - profile[index]) ); return unsigned(i * 65535); } static Color** colors; void Logo::Redraw (Coord, Coord, Coord, Coord) { if (rainbow > 0) { if (colors == nil) { colors = new Color* [rainbow]; for (int c = 0; c < rainbow; ++c) { float hue = float(c) / float(rainbow-1); colors[c] = new Color( intensity(hue, red_profile, profile_count), intensity(hue, green_profile, profile_count), intensity(hue, blue_profile, profile_count) ); colors[c]->Reference(); } } float h = float(ymax+1)/rainbow; Color* oldfg = output->GetFgColor(); for (int c = 0; c < rainbow; ++c) { output->SetColors(colors[c], nil); output->FillRect(canvas, 0, Coord(c * h), xmax, Coord((c+1) * h)); } output->SetColors(oldfg, nil); } else { output->ClearRect(canvas, 0, 0, xmax, ymax); } if (bitmap == nil) { DrawPolygon(); } else { DrawBitmap(); } }