Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

easyGUIFixed/GuiGraph16.h

Committer:
jmitc91516
Date:
2017-07-31
Revision:
8:26e49e6955bd
Parent:
1:a5258871b33d

File content as of revision 8:26e49e6955bd:

/* ************************************************************************ */
/*                                                                          */
/*                     (C)2004-2015 IBIS Solutions ApS                      */
/*                            sales@easyGUI.com                             */
/*                             www.easyGUI.com                              */
/*                                                                          */
/*        12/15/16 bit (4096/32K/64K color) graphics primitives library     */
/*                               v6.0.9.005                                 */
/*                                                                          */
/*     GuiLib.c include file - do NOT reference it in your linker setup     */
/*                                                                          */
/* ************************************************************************ */

//------------------------------------------------------------------------------
#define WANT_DOUBLE_BUFFERING // Also in GuiDisplay.c, GuiLib.c - *** all three must match ***
#ifdef WANT_DOUBLE_BUFFERING
//DisplayBufUnion GuiLib_DisplayBuf;
// Experiment - what if we put GuiLib_DisplayBuf at a specific location - but not the display?
//DisplayBufUnion GuiLib_DisplayBuf __attribute__((at(0xA00BB810))); // Result of second DMBoard->display->allocateFramebuffer() call
DisplayBufUnion GuiLib_DisplayBuf __attribute__((at(0xA00BCFE0))); // Result of second DMBoard->display->allocateFramebuffer() call (as of 26 Oct 2016)
#else // Want to write direct to the display
//DisplayBufUnion GuiLib_DisplayBuf __attribute__((at(0xA0000008))); // Result of first DMBoard->display->allocateFramebuffer() call
DisplayBufUnion GuiLib_DisplayBuf __attribute__((at(0xA00017D8))); // Result of first DMBoard->display->allocateFramebuffer() call (as of 26 Oct 2016)
                                                                   // Must be same as FRAME_ADDRESS in GuiDisplay.h
#endif

//==============================================================================

#ifdef GuiConst_CLIPPING_SUPPORT_ON
//------------------------------------------------------------------------------
static void SetClipping(
   GuiConst_INT16S X1,
   GuiConst_INT16S Y1,
   GuiConst_INT16S X2,
   GuiConst_INT16S Y2)
{
  if (X1 < 0)
    X1 = 0;
  if (Y1 < 0)
    Y1 = 0;
  if (X2 > (GuiConst_INT16S)sgl.CurLayerWidth - 1)
    X2 = (GuiConst_INT16S)sgl.CurLayerWidth - 1;
  if (Y2 > (GuiConst_INT16S)sgl.CurLayerHeight - 1)
    Y2 = (GuiConst_INT16S)sgl.CurLayerHeight - 1;

  sgl.ClippingX1 = X1;
  sgl.ClippingY1 = Y1;
  sgl.ClippingX2 = X2;
  sgl.ClippingY2 = Y2;
}
#endif

//------------------------------------------------------------------------------
static void MarkDisplayBoxRepaint(
   GuiConst_INT16S X1,
   GuiConst_INT16S Y1,
   GuiConst_INT16S X2,
   GuiConst_INT16S Y2)
{
  if (!sgl.BaseLayerDrawing)
    return;

  while (Y1 <= Y2)
  {
    if ((GuiLib_DisplayRepaint[Y1].ByteEnd == -1) ||
        (X1 < GuiLib_DisplayRepaint[Y1].ByteBegin))
      GuiLib_DisplayRepaint[Y1].ByteBegin = X1;
    if (X2 > GuiLib_DisplayRepaint[Y1].ByteEnd)
      GuiLib_DisplayRepaint[Y1].ByteEnd = X2;
    #ifdef GuiConst_VNC_REMOTE_SUPPORT_ON
    if ((GuiLib_VncRepaint[Y1].ByteEnd == -1) ||
        (X1 < GuiLib_VncRepaint[Y1].ByteBegin))
      GuiLib_VncRepaint[Y1].ByteBegin = X1;
    if (X2 > GuiLib_VncRepaint[Y1].ByteEnd)
      GuiLib_VncRepaint[Y1].ByteEnd = X2;
    #endif

    Y1++;
  }
}

//------------------------------------------------------------------------------
static void ClearDisplay(void)
{
  int X,Y;
  GuiConst_INT16U *PixelPtr;

  PixelPtr = (GuiConst_INT16U*)sgl.CurLayerBufPtr;
  for (Y = 0; Y < (GuiConst_INT16S)sgl.CurLayerHeight; Y++)
    for (X = 0; X < (GuiConst_INT16S)sgl.CurLayerWidth; X++)
    {
      *PixelPtr = GuiConst_PIXEL_OFF;
      PixelPtr++;
    }
}

//------------------------------------------------------------------------------
static void MakeDot(
   GuiConst_INT16S X,
   GuiConst_INT16S Y,
   GuiConst_INTCOLOR Color)
{
#ifdef GuiConst_CLIPPING_SUPPORT_ON
  if (CheckRect (&X, &Y, &X, &Y))
#endif
  {
#ifdef GuiConst_DISPLAY_BIG_ENDIAN
    *((GuiConst_INT16U*)sgl.CurLayerBufPtr +
      (GuiConst_INT32U)Y * sgl.CurLayerWidth + (GuiConst_INT32U)X) =
       (Color << 8 ) | (Color >> 8);
#else
    *((GuiConst_INT16U*)sgl.CurLayerBufPtr +
      (GuiConst_INT32U)Y * sgl.CurLayerWidth + (GuiConst_INT32U)X) = Color;
#endif
    MarkDisplayBoxRepaint(X, Y, X, Y);
  }
}

//------------------------------------------------------------------------------
static GuiConst_INTCOLOR ReadDot(
   GuiConst_INT16S X,
   GuiConst_INT16S Y)
{
  GuiConst_INT16U *PixelPtr;

  if ((X < 0) || (X >= (GuiConst_INT16S)sgl.CurLayerWidth) ||
      (Y < 0) || (Y >= (GuiConst_INT16S)sgl.CurLayerHeight))
    return (0);
  else
  {
    PixelPtr = (GuiConst_INT16U*)sgl.CurLayerBufPtr +
               (GuiConst_INT32U)Y * sgl.CurLayerWidth + (GuiConst_INT32U)X;
#ifdef GuiConst_DISPLAY_BIG_ENDIAN
    return ((*PixelPtr << 8) | (*PixelPtr >> 8));
#else
    return (*PixelPtr);
#endif
  }
}

//------------------------------------------------------------------------------
static void HorzLine(
   GuiConst_INT16S X1,
   GuiConst_INT16S X2,
   GuiConst_INT16S Y,
   GuiConst_INTCOLOR Color)
{
  GuiConst_INT16U *PixelPtr;

  PixelPtr = (GuiConst_INT16U*)sgl.CurLayerBufPtr +
             (GuiConst_INT32U)Y * sgl.CurLayerWidth + (GuiConst_INT32U)X1;
  while (X1 <= X2)
  {
#ifdef GuiConst_DISPLAY_BIG_ENDIAN
    *PixelPtr = (Color << 8) | (Color >> 8);
#else
    *PixelPtr = Color;
#endif
    PixelPtr++;
    X1++;
  }
}

//------------------------------------------------------------------------------
static void VertLine(
   GuiConst_INT16S X,
   GuiConst_INT16S Y1,
   GuiConst_INT16S Y2,
   GuiConst_INTCOLOR Color)
{
  GuiConst_INT16U *PixelPtr;

  PixelPtr = (GuiConst_INT16U*)sgl.CurLayerBufPtr +
             (GuiConst_INT32U)Y1 * sgl.CurLayerWidth + (GuiConst_INT32U)X;
  while (Y1 <= Y2)
  {
#ifdef GuiConst_DISPLAY_BIG_ENDIAN
    *PixelPtr = (Color << 8) | (Color >> 8);
#else
    *PixelPtr = Color;
#endif
    Y1++;
    PixelPtr += sgl.CurLayerWidth;
  }
}

//------------------------------------------------------------------------------
static void DrawChar(
   GuiConst_INT16S X,
   GuiConst_INT16S Y,
   GuiLib_FontRecPtr Font,
#ifdef GuiConst_REMOTE_FONT_DATA
   GuiConst_INT32S CharNdx,
#else
   GuiConst_INT8U PrefixRom * CharPtr,
#endif
   GuiConst_INTCOLOR Color,
   GuiConst_INT8U FullPixelFill)
{
#ifdef GuiConst_REMOTE_FONT_DATA
  GuiConst_INT8U *PixelData;
  GuiConst_INT8U * CharPtr;
#else
  GuiConst_INT8U PrefixRom *PixelData;
#endif
  GuiConst_INT8U PixelPattern;
  GuiConst_INT16S N;
  GuiConst_INT8U YHeight;
  GuiConst_INT8U PixN;
  GuiConst_INT16S Bx;
  GuiConst_INT16S PY, Y2;
  GuiConst_INT8U PixelLineSize;
#ifndef GuiConst_FONT_UNCOMPRESSED
#ifdef GuiConst_REMOTE_FONT_DATA
  GuiConst_INT8U *LineCtrl;
#else
  GuiConst_INT8U PrefixRom *LineCtrl;
#endif
  GuiConst_INT8U LineCtrlByte;
  GuiConst_INT16S LineRepeat;
  GuiConst_INT16S M;
  GuiConst_INT8U Finished;
  GuiConst_INT16U *PixelPtr;
#endif
#ifdef GuiConst_ADV_FONTS_ON
  GuiConst_INT8U PixelShade, PixelShadeInv;
  GuiConst_INTCOLOR PixelColor;
  GuiConst_INT8U PixelR, PixelG, PixelB;
  GuiConst_INT8U ColorR, ColorG, ColorB;
#endif

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  if (sgl.ClippingTotal)
    return;
#endif

#ifdef GuiConst_REMOTE_FONT_DATA
  if (CharNdx != sgl.CurRemoteFont)
  {
    GuiLib_RemoteDataReadBlock(
       (GuiConst_INT32U PrefixRom)GuiFont_ChPtrList[CharNdx],
       (GuiConst_INT32U PrefixRom)GuiFont_ChPtrList[CharNdx + 1] -
       (GuiConst_INT32U PrefixRom)GuiFont_ChPtrList[CharNdx],
       sgl.GuiLib_RemoteFontBuffer);
    sgl.CurRemoteFont = CharNdx;
  }
  CharPtr = &sgl.GuiLib_RemoteFontBuffer[0];
#endif

  if ((*(CharPtr + GuiLib_CHR_XWIDTH_OFS) == 0) ||
      (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) == 0))
    return;

  GuiLib_COORD_ADJUST(X, Y);
  GuiLib_COLOR_ADJUST(Color);

  gl.Dummy1_8U = Font->LineSize;   // To avoid compiler warning
#ifdef GuiConst_FONT_UNCOMPRESSED
  PixelLineSize = Font->LineSize;
  #ifdef GuiConst_ROTATED_90DEGREE
  YHeight = Font->XSize;
  #else
  YHeight = Font->YSize;
  #endif
  PixelData = CharPtr + GuiLib_CHR_LINECTRL_OFS + 1;
#else
  #ifdef GuiConst_ROTATED_90DEGREE
  PixelLineSize = *(CharPtr + GuiLib_CHR_YHEIGHT_OFS);
  YHeight = *(CharPtr + GuiLib_CHR_XWIDTH_OFS);
  #else
  PixelLineSize = *(CharPtr + GuiLib_CHR_XWIDTH_OFS);
  YHeight = *(CharPtr + GuiLib_CHR_YHEIGHT_OFS);
  #endif
  LineCtrl = CharPtr + GuiLib_CHR_LINECTRL_OFS;
  N = (YHeight + 7) / 8;
  if (N == 0)
    N++;
  PixelData = LineCtrl + N;
#ifdef GuiConst_ADV_FONTS_ON
  if (Font->ColorDepth == 4)
    PixelLineSize = (PixelLineSize + 1) / 2;
  else
#endif
    PixelLineSize = (PixelLineSize + 7) / 8;
#endif

#ifdef GuiConst_FONT_UNCOMPRESSED

#ifdef GuiConst_ROTATED_OFF
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= Font->XSize - 1;
  Y -= Font->YSize - 1;
    #else
  X -= Font->XSize - 1;
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  Y -= Font->YSize - 1;
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_90DEGREE_RIGHT
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= Font->YSize - 1;
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= Font->YSize - 1;
  Y -= Font->XSize - 1;
    #else
  Y -= Font->XSize - 1;
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_UPSIDEDOWN
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifndef GuiConst_MIRRORED_VERTICALLY
  Y -= Font->YSize - 1;
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= Font->XSize - 1;
    #else
  X -= Font->XSize - 1;
  Y -= Font->YSize - 1;
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_90DEGREE_LEFT
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  Y -= Font->XSize - 1;
    #else
  X -= Font->YSize - 1;
  Y -= Font->XSize - 1;
    #endif
  #else
    #ifndef GuiConst_MIRRORED_VERTICALLY
  X -= Font->YSize - 1;
    #endif
  #endif
#endif

#else

#ifdef GuiConst_ROTATED_OFF
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= (*(CharPtr + GuiLib_CHR_XWIDTH_OFS) +
        *(CharPtr + GuiLib_CHR_XLEFT_OFS) - 1);
  Y -= (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) +
        *(CharPtr + GuiLib_CHR_YTOP_OFS) - 1);
    #else
  X -= (*(CharPtr + GuiLib_CHR_XWIDTH_OFS) +
        *(CharPtr + GuiLib_CHR_XLEFT_OFS) - 1);
  Y += *(CharPtr + GuiLib_CHR_YTOP_OFS);
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X += *(CharPtr + GuiLib_CHR_XLEFT_OFS);
  Y -= (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) +
        *(CharPtr + GuiLib_CHR_YTOP_OFS) - 1);
    #else
  X += *(CharPtr + GuiLib_CHR_XLEFT_OFS);
  Y += *(CharPtr + GuiLib_CHR_YTOP_OFS);
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_90DEGREE_RIGHT
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) +
        *(CharPtr + GuiLib_CHR_YTOP_OFS) - 1);
  Y += *(CharPtr + GuiLib_CHR_XLEFT_OFS);
    #else
  X += *(CharPtr + GuiLib_CHR_YTOP_OFS);
  Y += *(CharPtr + GuiLib_CHR_XLEFT_OFS);
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) +
        *(CharPtr + GuiLib_CHR_YTOP_OFS) - 1);
  Y -= (*(CharPtr + GuiLib_CHR_XWIDTH_OFS) +
        *(CharPtr + GuiLib_CHR_XLEFT_OFS) - 1);
    #else
  X += *(CharPtr + GuiLib_CHR_YTOP_OFS);
  Y -= (*(CharPtr + GuiLib_CHR_XWIDTH_OFS) +
        *(CharPtr + GuiLib_CHR_XLEFT_OFS) - 1);
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_UPSIDEDOWN
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X += *(CharPtr + GuiLib_CHR_XLEFT_OFS);
  Y += *(CharPtr + GuiLib_CHR_YTOP_OFS);
    #else
  X += *(CharPtr + GuiLib_CHR_XLEFT_OFS);
  Y -= (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) +
        *(CharPtr + GuiLib_CHR_YTOP_OFS) - 1);
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= (*(CharPtr + GuiLib_CHR_XWIDTH_OFS) +
        *(CharPtr + GuiLib_CHR_XLEFT_OFS) - 1);
  Y += *(CharPtr + GuiLib_CHR_YTOP_OFS);
    #else
  X -= (*(CharPtr + GuiLib_CHR_XWIDTH_OFS) +
        *(CharPtr + GuiLib_CHR_XLEFT_OFS) - 1);
  Y -= (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) +
        *(CharPtr + GuiLib_CHR_YTOP_OFS) - 1);
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_90DEGREE_LEFT
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X += *(CharPtr + GuiLib_CHR_YTOP_OFS);
  Y -= (*(CharPtr + GuiLib_CHR_XWIDTH_OFS) +
        *(CharPtr + GuiLib_CHR_XLEFT_OFS) - 1);
    #else
  X -= (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) +
        *(CharPtr + GuiLib_CHR_YTOP_OFS) - 1);
  Y -= (*(CharPtr + GuiLib_CHR_XWIDTH_OFS) +
        *(CharPtr + GuiLib_CHR_XLEFT_OFS) - 1);
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X += *(CharPtr + GuiLib_CHR_YTOP_OFS);
  Y += *(CharPtr + GuiLib_CHR_XLEFT_OFS);
    #else
  X -= (*(CharPtr + GuiLib_CHR_YHEIGHT_OFS) +
        *(CharPtr + GuiLib_CHR_YTOP_OFS) - 1);
  Y += *(CharPtr + GuiLib_CHR_XLEFT_OFS);
    #endif
  #endif
#endif

#endif

#ifdef GuiConst_ADV_FONTS_ON
  ColorR = (Color & GuiConst_COLORCODING_R_MASK) >>
     GuiConst_COLORCODING_R_START;
  ColorG = (Color & GuiConst_COLORCODING_G_MASK) >>
     GuiConst_COLORCODING_G_START;
  ColorB = (Color & GuiConst_COLORCODING_B_MASK) >>
     GuiConst_COLORCODING_B_START;
#endif

  PY = 0;
#ifndef GuiConst_FONT_UNCOMPRESSED
  LineCtrlByte = *LineCtrl;
  LineCtrlByte >>= 1;
  LineCtrl++;
#endif
  while (PY < YHeight)
  {
#ifndef GuiConst_FONT_UNCOMPRESSED
    LineRepeat = 0;
    do
    {
      LineRepeat++;
      Finished = (((LineCtrlByte & 0x01) == 0) || (PY >= YHeight - 1));

      PY++;
      if (PY % 8 == 7)
      {
        LineCtrlByte = *LineCtrl;
        LineCtrl++;
      }
      else
        LineCtrlByte >>= 1;
    }
    while (!Finished);
#endif

#ifdef GuiConst_ADV_FONTS_ON
    if (Font->ColorDepth == 4)
      Bx = X;
    else
#endif
      Bx = X;

    for (N = 0; N < PixelLineSize; N++)
    {
      PixelPattern = *PixelData;

      if (PixelPattern != 0)
      {
#ifdef GuiConst_ADV_FONTS_ON
        if (Font->ColorDepth == 4)
        {
          for (PixN = 0; PixN < 2; PixN++)
          {
            if (PixN == 0)
              PixelShade = PixelPattern & 0x0F;
            else
              PixelShade = (PixelPattern & 0xF0) >> 4;
            if (FullPixelFill && (PixelShade > 0))
              PixelShade = 0x0F;
            if (
#ifdef GuiConst_CLIPPING_SUPPORT_ON
                (Bx + PixN >= sgl.ClippingX1) && (Bx + PixN <= sgl.ClippingX2) &&
#endif
               (PixelShade > 0))
            {
              PixelShadeInv = 15 - PixelShade;
              Y2 = Y;
              PixelPtr = (GuiConst_INT16U*)sgl.CurLayerBufPtr +
                         (GuiConst_INT32U)Y2 * sgl.CurLayerWidth +
                         (GuiConst_INT32U)(Bx + PixN);
#ifndef GuiConst_FONT_UNCOMPRESSED
              for (M = 0; M < LineRepeat; M++)
#endif
              {
#ifdef GuiConst_CLIPPING_SUPPORT_ON
                if ((Y2 >= sgl.ClippingY1) && (Y2 <= sgl.ClippingY2))
#endif
                {
                  if (PixelShade == 0x0F)
                  {
#ifdef GuiConst_DISPLAY_BIG_ENDIAN
                    *PixelPtr = (Color << 8) | (Color >> 8);
#else
                    *PixelPtr = Color;
#endif
                  }
                  else
                  {
                    PixelColor = *PixelPtr;
                    PixelR = (PixelColor & GuiConst_COLORCODING_R_MASK) >>
                       GuiConst_COLORCODING_R_START;
                    PixelG = (PixelColor & GuiConst_COLORCODING_G_MASK) >>
                       GuiConst_COLORCODING_G_START;
                    PixelB = (PixelColor & GuiConst_COLORCODING_B_MASK) >>
                       GuiConst_COLORCODING_B_START;
                    PixelR = (PixelShade * ColorR + PixelShadeInv * PixelR) / 15;
                    PixelG = (PixelShade * ColorG + PixelShadeInv * PixelG) / 15;
                    PixelB = (PixelShade * ColorB + PixelShadeInv * PixelB) / 15;
                    PixelColor = (PixelR << GuiConst_COLORCODING_R_START) |
                                (PixelG << GuiConst_COLORCODING_G_START) |
                                (PixelB << GuiConst_COLORCODING_B_START);
#ifdef GuiConst_DISPLAY_BIG_ENDIAN
                    *PixelPtr = ((PixelColor>>8)&0xFF) | ((PixelColor<<8)&0xFF00);
#else
                    *PixelPtr = PixelColor;
#endif
                  }
                }
                Y2++;
                PixelPtr += sgl.CurLayerWidth;
              }
            }
          }
        }
        else
  #endif
        {
          for (PixN = 0; PixN < 8; PixN++)
          {
            if (
#ifdef GuiConst_CLIPPING_SUPPORT_ON
                (Bx + PixN >= sgl.ClippingX1) && (Bx + PixN <= sgl.ClippingX2) &&
#endif
               ((PixelPattern >> (7-PixN)) & 0x01))
            {
              Y2 = Y;
              PixelPtr = (GuiConst_INT16U*)sgl.CurLayerBufPtr +
                         (GuiConst_INT32U)Y2 * sgl.CurLayerWidth +
                         (GuiConst_INT32U)(Bx + PixN);
#ifndef GuiConst_FONT_UNCOMPRESSED
              for (M = 0; M < LineRepeat; M++)
#endif
              {
#ifdef GuiConst_CLIPPING_SUPPORT_ON
                if ((Y2 >= sgl.ClippingY1) && (Y2 <= sgl.ClippingY2))
#endif
                {
#ifdef GuiConst_DISPLAY_BIG_ENDIAN
                  *PixelPtr = (Color << 8) | (Color >> 8);
#else
                  *PixelPtr = Color;
#endif
                }
                Y2++;
                PixelPtr += sgl.CurLayerWidth;
              }
            }
          }
        }
      }

      PixelData++;
#ifdef GuiConst_ADV_FONTS_ON
      if (Font->ColorDepth == 4)
        Bx+=2;
      else
#endif
        Bx+=8;
    }

#ifdef GuiConst_FONT_UNCOMPRESSED
    PY++;
    Y++;
#else
    Y += LineRepeat;
#endif
  }
}

#ifdef GuiConst_BITMAP_SUPPORT_ON

#define RenderPix                                                              \
{                                                                              \
  *PixelPtr2 = *PixelDataPtr2;                                                 \
  PixelPtr2++;                                                                 \
  *PixelPtr2 = *(PixelDataPtr2 + 1);                                           \
  PixelPtr2++;                                                                 \
}

//------------------------------------------------------------------------------
static void ShowBitmapArea(
#ifdef GuiConst_REMOTE_BITMAP_DATA
   GuiConst_INT8U * PixelDataPtr,
#else
   GuiConst_INT8U PrefixRom * PixelDataPtr,
#endif
   GuiConst_INT16S X,
   GuiConst_INT16S Y,
   GuiConst_INT16S X1,
   GuiConst_INT16S Y1,
   GuiConst_INT16S X2,
   GuiConst_INT16S Y2,
   GuiConst_INT32S TranspColor,
   GuiConst_INT8U BitmapType)
{
#ifdef GuiConst_REMOTE_BITMAP_DATA
   GuiConst_INT8U * PixelDataPtr2;
#else
   GuiConst_INT8U PrefixRom * PixelDataPtr2;
#endif
  GuiConst_INT16S SizeX;
  GuiConst_INT16S SizeY;
  GuiConst_INT8U *PixelPtr1, *PixelPtr2;
  GuiConst_INT16S I;
  GuiConst_INT16U Cnt, CntPix;
  GuiConst_INT8U Diff;
#ifdef GuiConst_BITMAP_COMPRESSED
  GuiConst_INT16U Offset;
  GuiConst_INT16S DX;
#ifdef GuiConst_REMOTE_BITMAP_DATA
   GuiConst_INT8U * RemPixelDataPtr;
   GuiConst_INT8U * LinePixelDataPtr;
#else
   GuiConst_INT8U PrefixRom * RemPixelDataPtr;
   GuiConst_INT8U PrefixRom * LinePixelDataPtr;
#endif
#endif

#ifdef GuiConst_DISPLAY_BIG_ENDIAN
  TranspColor = ((TranspColor&0xFF)<<8)|((TranspColor&0xFF00)>>8);
#endif

  SizeX = (GuiConst_INT16S)*PixelDataPtr;
  PixelDataPtr++;
  SizeX += 256*(GuiConst_INT16S)*PixelDataPtr;
  PixelDataPtr++;
  SizeY = (GuiConst_INT16S)*PixelDataPtr;
  PixelDataPtr++;
  SizeY += 256*(GuiConst_INT16S)*PixelDataPtr;
  PixelDataPtr++;

#ifdef GuiConst_ROTATED_90DEGREE
  sgl.BitmapWriteX2 = X + SizeY - 1;
  sgl.BitmapWriteY2 = Y + SizeX - 1;
#else
  sgl.BitmapWriteX2 = X + SizeX - 1;
  sgl.BitmapWriteY2 = Y + SizeY - 1;
#endif

  GuiLib_COORD_ADJUST(X, Y);
  GuiLib_COLOR_ADJUST_TRANSP(TranspColor);

  if (BitmapType == GuiLib_AREA_BITMAP)
  {
    GuiLib_COORD_ADJUST(X1, Y1);
    GuiLib_COORD_ADJUST(X2, Y2);
    OrderCoord(&X1, &X2);
    OrderCoord(&Y1, &Y2);
  }

#ifdef GuiConst_ROTATED_OFF
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= SizeX - 1;
  Y -= SizeY - 1;
    #else
  X -= SizeX - 1;
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  Y -= SizeY - 1;
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_90DEGREE_RIGHT
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= SizeX - 1;
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= SizeX - 1;
  Y -= SizeY - 1;
    #else
  Y -= SizeY - 1;
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_UPSIDEDOWN
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifndef GuiConst_MIRRORED_VERTICALLY
  Y -= SizeY - 1;
    #endif
  #else
    #ifdef GuiConst_MIRRORED_VERTICALLY
  X -= SizeX - 1;
    #else
  X -= SizeX - 1;
  Y -= SizeY - 1;
    #endif
  #endif
#endif
#ifdef GuiConst_ROTATED_90DEGREE_LEFT
  #ifdef GuiConst_MIRRORED_HORIZONTALLY
    #ifdef GuiConst_MIRRORED_VERTICALLY
  Y -= SizeY - 1;
    #else
  X -= SizeX - 1;
  Y -= SizeY - 1;
    #endif
  #else
    #ifndef GuiConst_MIRRORED_VERTICALLY
  X -= SizeX - 1;
    #endif
  #endif
#endif

  if (BitmapType == GuiLib_AREA_BITMAP)
  {
    if ((X1 > X + SizeX - 1) || (X2 < X) || (Y1 > Y + SizeY - 1) || (Y2 < Y))
      return;
    if (X1 < X)
      X1 = X;
    if (X2 > X + SizeX - 1)
      X2 = X + SizeX - 1;
    if (Y1 < Y)
      Y1 = Y;
    if (Y2 > Y + SizeY - 1)
      Y2 = Y + SizeY - 1;
  }
  else
  {
    X2 = X + SizeX - 1;
    Y2 = Y + SizeY - 1;

    OrderCoord(&X, &X2);
    OrderCoord(&Y, &Y2);

    X1 = X;
    Y1 = Y;
  }

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  if (!CheckRect(&X1, &Y1, &X2, &Y2))
    return;
#endif

  MarkDisplayBoxRepaint(X1, Y1, X2, Y2);   // Before changing Y1

#ifdef GuiConst_BITMAP_COMPRESSED
  while (Y < Y1)
  {
    Offset = (GuiConst_INT16U)*PixelDataPtr;
    PixelDataPtr++;
    Offset += 256 * (GuiConst_INT16U)*PixelDataPtr;
    PixelDataPtr++;
    if (Offset != 0)
    {
      LinePixelDataPtr = PixelDataPtr;
      PixelDataPtr += Offset - 2;
    }

    Y++;
  }
  DX = X1 - X;
#else
  PixelDataPtr += 2 * (SizeX * (Y1 - Y) + (X1 - X));
  Diff = 1;
#endif
  PixelPtr1 = sgl.CurLayerBufPtr +
              (GuiConst_INT32U)Y1 * sgl.CurLayerLineSize + (GuiConst_INT32U)(2 * X1);
  while (Y1 <= Y2)
  {
    PixelPtr2 = PixelPtr1;

#ifdef GuiConst_BITMAP_COMPRESSED
    Offset = (GuiConst_INT16U)*PixelDataPtr;
    PixelDataPtr++;
    Offset += 256 * (GuiConst_INT16U)*PixelDataPtr;
    PixelDataPtr++;
    if (Offset == 0)
    {
      RemPixelDataPtr = PixelDataPtr;
      PixelDataPtr = LinePixelDataPtr;
    }
    else
      LinePixelDataPtr = PixelDataPtr;

    Cnt = 0;
    X = DX;
    while (X > 0)
    {
      Diff = *PixelDataPtr;
      Cnt = Diff & 0x7F;
      Diff >>= 7;
      PixelDataPtr++;

      if (X >= Cnt)
      {
        if (Diff)
          PixelDataPtr += 2 * Cnt;
        else
          PixelDataPtr += 2;
        X -= Cnt;
        Cnt = 0;
      }
      else
      {
        if (Diff)
          PixelDataPtr += 2 * X;
        Cnt -= X;
        X = 0;
      }
    }
#endif

    PixelDataPtr2 = PixelDataPtr;
    for (X = X1; X <= X2; X++)
    {
#ifdef GuiConst_BITMAP_COMPRESSED
      if (Cnt == 0)
      {
        Diff = *PixelDataPtr2;
        Cnt = Diff & 0x7F;
        Diff >>= 7;
        PixelDataPtr2++;
      }
      CntPix = GuiLib_GET_MIN(Cnt, X2 - X + 1);
      Cnt -= CntPix;
#else
      CntPix = X2 - X + 1;
#endif
      X += CntPix - 1;

      if (Diff)
      {
        if (TranspColor == -1)
        {
          CopyBytes(PixelPtr2, PixelDataPtr2, 2 * CntPix);
          PixelPtr2 += 2 * CntPix;
          PixelDataPtr2 += 2 * CntPix;
        }
        else
        {
          while (CntPix > 0)
          {
            if (*(GuiConst_INT16U*)PixelDataPtr2 ==
               (GuiConst_INT16U)TranspColor)
              PixelPtr2 += 2;
            else
            {
              RenderPix;
            }

            CntPix--;
            PixelDataPtr2 += 2;
          }
        }
      }
#ifdef GuiConst_BITMAP_COMPRESSED
      else
      {
        if ((TranspColor == -1) ||
           (*(GuiConst_INT16U*)PixelDataPtr2 != (GuiConst_INT16U)TranspColor))
        {
          while (CntPix > 0)
          {
            RenderPix;
            CntPix--;
          }
        }
        else
          PixelPtr2 += 2 * CntPix;

        PixelDataPtr2 += 2;
      }

      if ((X > X2) && Diff)
        PixelDataPtr2 += 2 * (X - X2);
      Cnt = 0;
#endif
    }

#ifdef GuiConst_BITMAP_COMPRESSED
    if (Offset == 0)
      PixelDataPtr = RemPixelDataPtr;
    else
      PixelDataPtr = LinePixelDataPtr + Offset - 2;
#else
    PixelDataPtr += 2 * SizeX;
#endif

    Y1++;
    PixelPtr1 += sgl.CurLayerLineSize;
  }
}
#endif

//==============================================================================

//------------------------------------------------------------------------------
void GuiLib_InvertBox(
   GuiConst_INT16S X1,
   GuiConst_INT16S Y1,
   GuiConst_INT16S X2,
   GuiConst_INT16S Y2)
{
  GuiConst_INT16S X;
  GuiConst_INT16U *PixelPtr;
  GuiConst_INT32U DeltaLineSize;

  GuiLib_COORD_ADJUST(X1, Y1);
  GuiLib_COORD_ADJUST(X2, Y2);

  OrderCoord(&X1, &X2);
  OrderCoord(&Y1, &Y2);

#ifdef GuiConst_CLIPPING_SUPPORT_ON
  if (CheckRect (&X1, &Y1, &X2, &Y2))
#endif
  {
    MarkDisplayBoxRepaint(X1, Y1, X2, Y2);

    PixelPtr = (GuiConst_INT16U*)sgl.CurLayerBufPtr +
               (GuiConst_INT32U)Y1 * sgl.CurLayerWidth + (GuiConst_INT32U)X1;
    DeltaLineSize = sgl.CurLayerWidth - (GuiConst_INT32U)(X2 - X1 + 1);
    while (Y1 <= Y2)
    {
      for (X = X1; X <= X2; X++)
      {
        *PixelPtr = ~*PixelPtr;
        PixelPtr++;
      }
      Y1++;
      PixelPtr += DeltaLineSize;
    }
  }
}