allegrographics.cpp

00001 /*      _______   __   __   __   ______   __   __   _______   __   __
00002  *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
00003  *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
00004  *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
00005  *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
00006  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
00007  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
00008  *
00009  * Copyright (c) 2004, 2005, 2006 Olof Naessén and Per Larsson
00010  *
00011  *                                                         Js_./
00012  * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
00013  * Olof Naessén a.k.a jansem/yakslem                _asww7!uY`>  )\a//
00014  *                                                 _Qhm`] _f "'c  1!5m
00015  * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
00016  *                                               .)j(] .d_/ '-(  P .   S
00017  * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
00018  * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
00019  * binary forms, with or without                 )4d[#7r, .   '     )d`)[
00020  * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
00021  * that the following conditions are met:       j<<WP+k/);.        _W=j f
00022  * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
00023  *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
00024  *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
00025  *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
00026  * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
00027  *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
00028  *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
00029  *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
00030  *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
00031  *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
00032  * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
00033  *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
00034  *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
00035  *    from this software without specific        (js, \[QQW$QWW#?!V"".
00036  *    prior written permission.                    ]y:.<\..          .
00037  *                                                 -]n w/ '         [.
00038  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
00039  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
00040  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
00041  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
00042  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
00043  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
00044  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
00045  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
00046  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
00047  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
00048  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
00049  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
00050  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00051  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00052  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00053  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00054  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00055  */
00056 
00057 /*
00058  * For comments regarding functions please see the header file.
00059  */
00060 
00061 #include "guichan/allegro/allegrographics.hpp"
00062 #include "guichan/allegro/allegroimage.hpp"
00063 #include "guichan/rectangle.hpp"
00064 #include "guichan/exception.hpp"
00065 #include "guichan/cliprectangle.hpp"
00066 #include "guichan/color.hpp"
00067 
00068 namespace gcn
00069 {
00070     AllegroGraphics::AllegroGraphics()
00071     {
00072         mTarget = NULL;
00073         mClipNull = false;
00074     }
00075 
00076     AllegroGraphics::AllegroGraphics(BITMAP *target)
00077     {
00078         mTarget = target;
00079     }
00080 
00081     AllegroGraphics::~AllegroGraphics()
00082     {
00083     }
00084 
00085     void AllegroGraphics::setTarget(BITMAP *target)
00086     {
00087         mTarget = target;
00088     }
00089 
00090     BITMAP *AllegroGraphics::getTarget()
00091     {
00092         return mTarget;
00093     }
00094 
00095     void AllegroGraphics::_beginDraw()
00096     {
00097         if (mTarget == NULL)
00098         {
00099             throw GCN_EXCEPTION("Target BITMAP is null, set it with setTarget first.");
00100         }
00101 
00102         // push a clip area the size of the target bitmap
00103         pushClipArea(Rectangle(0, 0, mTarget->w, mTarget->h));
00104     }
00105 
00106     void AllegroGraphics::_endDraw()
00107     {
00108         // pop the clip area pushed in _beginDraw
00109         popClipArea();
00110     }
00111 
00112     bool AllegroGraphics::pushClipArea(Rectangle area)
00113     {
00114         bool result = Graphics::pushClipArea(area);
00115 
00116         ClipRectangle cr = mClipStack.top();
00117 
00118         // Allegro won't let you set clip areas
00119         // that have zero width or height
00120         // so we have to check for that.
00121         if (cr.width == 0 || cr.height == 0)
00122         {
00123             mClipNull = true;
00124         }
00125         else
00126         {
00127             mClipNull = false;
00128 #if ALLEGRO_VERSION == 4 && ALLEGRO_SUB_VERSION == 0
00129             set_clip(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
00130 #else
00131             set_clip_rect(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
00132 #endif
00133         }
00134 
00135         return result;
00136     }
00137 
00138     void AllegroGraphics::popClipArea()
00139     {
00140         Graphics::popClipArea();
00141 
00142         if (mClipStack.empty())
00143         {
00144             return;
00145         }
00146 
00147         ClipRectangle cr = mClipStack.top();
00148 
00149         // Allegro won't let you set clip areas
00150         //that have zero width or height
00151         // so we have to check for that.
00152         if (cr.width == 0 || cr.height == 0)
00153         {
00154             mClipNull = true;
00155         }
00156         else
00157         {
00158             mClipNull = false;
00159 #if ALLEGRO_VERSION == 4 && ALLEGRO_SUB_VERSION == 0
00160             set_clip(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
00161 #else
00162             set_clip_rect(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
00163 #endif
00164         }
00165     }
00166 
00167     void AllegroGraphics::drawImage(const Image* image,
00168                                     int srcX, int srcY,
00169                                     int dstX, int dstY,
00170                                     int width, int height)
00171     {
00172         if (mClipNull)
00173         {
00174             return;
00175         }
00176 
00177         dstX += mClipStack.top().xOffset;
00178         dstY += mClipStack.top().yOffset;
00179 
00180         const AllegroImage* srcImage = dynamic_cast<const AllegroImage*>(image);
00181 
00182         if (srcImage == NULL)
00183         {
00184             throw GCN_EXCEPTION("Trying to draw an image of unknown format, must be an AllegroImage.");
00185         }
00186 
00187         masked_blit(srcImage->getBitmap(), mTarget, srcX, srcY, dstX, dstY, width, height);
00188     }
00189 
00190     void AllegroGraphics::drawPoint(int x, int y)
00191     {
00192         if (mClipNull)
00193         {
00194             return;
00195         }
00196 
00197         int xOffset = mClipStack.top().xOffset;
00198         int yOffset = mClipStack.top().yOffset;
00199 
00200         putpixel(mTarget,
00201                  x + xOffset,
00202                  y + yOffset,
00203                  mAlColor);
00204     }
00205 
00206     void AllegroGraphics::drawLine(int x1, int y1, int x2, int y2)
00207     {
00208         if (mClipNull)
00209         {
00210             return;
00211         }
00212 
00213         int xOffset = mClipStack.top().xOffset;
00214         int yOffset = mClipStack.top().yOffset;
00215 
00216         line(mTarget,
00217              x1 + xOffset,
00218              y1 + yOffset,
00219              x2 + xOffset,
00220              y2 + yOffset,
00221              mAlColor);
00222     }
00223 
00224     void AllegroGraphics::drawRectangle(const Rectangle& rectangle)
00225     {
00226         if (mClipNull)
00227         {
00228             return;
00229         }
00230 
00231         int xOffset = mClipStack.top().xOffset;
00232         int yOffset = mClipStack.top().yOffset;
00233 
00234         rect(mTarget,
00235              rectangle.x + xOffset,
00236              rectangle.y + yOffset,
00237              rectangle.x + rectangle.width - 1 + xOffset,
00238              rectangle.y + rectangle.height - 1 + yOffset,
00239              mAlColor);
00240     }
00241 
00242     void AllegroGraphics::fillRectangle(const Rectangle& rectangle)
00243     {
00244         if (mClipNull)
00245         {
00246             return;
00247         }
00248 
00249         int xOffset = mClipStack.top().xOffset;
00250         int yOffset = mClipStack.top().yOffset;
00251 
00252         rectfill(mTarget,
00253                  rectangle.x + xOffset,
00254                  rectangle.y + yOffset,
00255                  rectangle.x + rectangle.width - 1 + xOffset,
00256                  rectangle.y + rectangle.height - 1 + yOffset,
00257                  mAlColor);
00258     }
00259 
00260     void AllegroGraphics::setColor(const Color& color)
00261     {
00262         mColor = color;
00263         mAlColor = makecol(color.r, color.g, color.b);
00264 
00265         if (color.a != 255)
00266         {
00267             set_trans_blender(255, 255, 255, color.a);
00268             drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
00269         }
00270         else
00271         {
00272             solid_mode();
00273         }
00274     }
00275 
00276     const Color& AllegroGraphics::getColor()
00277     {
00278         return mColor;
00279     }
00280 }

Generated on Sat Jul 29 19:38:48 2006 for Guichan by  doxygen 1.4.7