42 #include "freertos/FreeRTOS.h" 43 #include "freertos/queue.h" 44 #include "freertos/task.h" 60 enum PrimitiveCmd : uint8_t {
235 RGB888(uint8_t red, uint8_t green, uint8_t blue) :
R(red),
G(green),
B(blue) { }
236 } __attribute__ ((packed));
239 inline bool operator==(RGB888
const& lhs, RGB888
const& rhs)
241 return lhs.R == rhs.R && lhs.G == rhs.G && lhs.B == rhs.B;
245 inline bool operator!=(RGB888
const& lhs, RGB888
const& rhs)
247 return lhs.R != rhs.R || lhs.G != rhs.G || lhs.B == rhs.B;
264 RGBA8888(
int red,
int green,
int blue,
int alpha) :
R(red),
G(green),
B(blue),
A(alpha) { }
281 RGB222(uint8_t red, uint8_t green, uint8_t blue) :
R(red),
G(green),
B(blue) { }
282 RGB222(RGB888
const & value);
284 static bool lowBitOnly;
288 inline bool operator==(RGB222
const& lhs, RGB222
const& rhs)
290 return lhs.R == rhs.R && lhs.G == rhs.G && lhs.B == rhs.B;
294 inline bool operator!=(RGB222
const& lhs, RGB222
const& rhs)
296 return lhs.R != rhs.R || lhs.G != rhs.G || lhs.B == rhs.B;
311 RGBA2222(
int red,
int green,
int blue,
int alpha) :
R(red),
G(green),
B(blue),
A(alpha) { }
319 uint8_t RGB888toPackedRGB222(RGB888
const & rgb);
335 Glyph(
int X_,
int Y_,
int width_,
int height_, uint8_t
const * data_) :
X(X_),
Y(Y_),
width(width_),
height(height_),
data(data_) { }
336 } __attribute__ ((packed));
378 } __attribute__ ((packed));
388 #define GLYPHMAP_INDEX_BIT 0 389 #define GLYPHMAP_BGCOLOR_BIT 8 390 #define GLYPHMAP_FGCOLOR_BIT 12 391 #define GLYPHMAP_OPTIONS_BIT 16 392 #define GLYPHMAP_ITEM_MAKE(index, bgColor, fgColor, options) (((uint32_t)(index) << GLYPHMAP_INDEX_BIT) | ((uint32_t)(bgColor) << GLYPHMAP_BGCOLOR_BIT) | ((uint32_t)(fgColor) << GLYPHMAP_FGCOLOR_BIT) | ((uint32_t)((options).value) << GLYPHMAP_OPTIONS_BIT)) 394 inline uint8_t glyphMapItem_getIndex(uint32_t
const volatile * mapItem) {
return *mapItem >> GLYPHMAP_INDEX_BIT & 0xFF; }
395 inline uint8_t glyphMapItem_getIndex(uint32_t
const & mapItem) {
return mapItem >> GLYPHMAP_INDEX_BIT & 0xFF; }
397 inline Color glyphMapItem_getBGColor(uint32_t
const volatile * mapItem) {
return (
Color)(*mapItem >> GLYPHMAP_BGCOLOR_BIT & 0x0F); }
398 inline Color glyphMapItem_getBGColor(uint32_t
const & mapItem) {
return (
Color)(mapItem >> GLYPHMAP_BGCOLOR_BIT & 0x0F); }
400 inline Color glyphMapItem_getFGColor(uint32_t
const volatile * mapItem) {
return (
Color)(*mapItem >> GLYPHMAP_FGCOLOR_BIT & 0x0F); }
401 inline Color glyphMapItem_getFGColor(uint32_t
const & mapItem) {
return (
Color)(mapItem >> GLYPHMAP_FGCOLOR_BIT & 0x0F); }
403 inline GlyphOptions glyphMapItem_getOptions(uint32_t
const volatile * mapItem) {
return (GlyphOptions){.value = (uint16_t)(*mapItem >> GLYPHMAP_OPTIONS_BIT & 0xFFFF)}; }
404 inline GlyphOptions glyphMapItem_getOptions(uint32_t
const & mapItem) {
return (GlyphOptions){.value = (uint16_t)(mapItem >> GLYPHMAP_OPTIONS_BIT & 0xFFFF)}; }
406 inline void glyphMapItem_setOptions(uint32_t
volatile * mapItem, GlyphOptions
const & options) { *mapItem = (*mapItem & ~((uint32_t)0xFFFF << GLYPHMAP_OPTIONS_BIT)) | ((uint32_t)(options.value) << GLYPHMAP_OPTIONS_BIT); }
408 struct GlyphsBuffer {
410 int16_t glyphsHeight;
411 uint8_t
const * glyphsData;
418 struct GlyphsBufferRenderInfo {
421 GlyphsBuffer
const * glyphsBuffer;
423 GlyphsBufferRenderInfo(
int itemX_,
int itemY_, GlyphsBuffer
const * glyphsBuffer_) : itemX(itemX_), itemY(itemY_), glyphsBuffer(glyphsBuffer_) { }
424 } __attribute__ ((packed));
474 Bitmap(
int width_,
int height_,
void const * data_,
PixelFormat format_,
bool copy =
false);
475 Bitmap(
int width_,
int height_,
void const * data_,
PixelFormat format_,
RGB888 foregroundColor_,
bool copy =
false);
478 void setPixel(
int x,
int y,
int value);
479 void setPixel(
int x,
int y,
RGBA2222 value);
480 void setPixel(
int x,
int y,
RGBA8888 value);
482 int getAlpha(
int x,
int y);
486 void copyFrom(
void const * srcData);
490 struct BitmapDrawingInfo {
493 Bitmap
const * bitmap;
495 BitmapDrawingInfo(
int X_,
int Y_, Bitmap
const * bitmap_) :
X(X_),
Y(Y_), bitmap(bitmap_) { }
496 } __attribute__ ((packed));
535 struct QuadTreeObject;
551 int16_t currentFrame;
554 int16_t savedBackgroundWidth;
555 int16_t savedBackgroundHeight;
556 uint8_t * savedBackground;
557 QuadTreeObject * collisionDetectorObject;
564 uint8_t allowDraw: 1;
569 Bitmap * getFrame() {
return frames ? frames[currentFrame] :
nullptr; }
570 int getFrameIndex() {
return currentFrame; }
571 void nextFrame() { ++currentFrame;
if (currentFrame >= framesCount) currentFrame = 0; }
572 Sprite * setFrame(
int frame) { currentFrame = frame;
return this; }
576 int getWidth() {
return frames[currentFrame]->
width; }
577 int getHeight() {
return frames[currentFrame]->
height; }
578 Sprite * moveBy(
int offsetX,
int offsetY);
579 Sprite * moveBy(
int offsetX,
int offsetY,
int wrapAroundWidth,
int wrapAroundHeight);
580 Sprite * moveTo(
int x,
int y);
585 Point const * points;
588 } __attribute__ ((packed));
599 } __attribute__ ((packed));
605 } __attribute__ ((packed));
617 GlyphOptions glyphOptions;
618 PaintOptions paintOptions;
619 GlyphsBufferRenderInfo glyphsBufferRenderInfo;
620 BitmapDrawingInfo bitmapDrawingInfo;
624 TaskHandle_t notifyTask;
625 } __attribute__ ((packed));
628 Primitive(PrimitiveCmd cmd_) : cmd(cmd_) { }
629 Primitive(PrimitiveCmd cmd_, Rect
const & rect_) : cmd(cmd_), rect(rect_) { }
630 } __attribute__ ((packed));
637 GlyphOptions glyphOptions;
638 PaintOptions paintOptions;
639 Rect scrollingRegion;
642 Rect absClippingRect;
666 virtual void setResolution(
char const * modeline,
int viewPortWidth = -1,
int viewPortHeight = -1,
bool doubleBuffered =
false) = 0;
668 virtual void begin() = 0;
699 int16_t m_screenWidth;
700 int16_t m_screenHeight;
714 virtual int getColumns() = 0;
715 virtual int getRows() = 0;
716 virtual void adjustMapSize(
int * columns,
int * rows) = 0;
717 virtual void setTextMap(uint32_t
const * map,
int rows) = 0;
718 virtual void enableCursor(
bool value) = 0;
719 virtual void setCursorPos(
int row,
int col) = 0;
720 virtual void setCursorForeground(
Color value) = 0;
721 virtual void setCursorBackground(
Color value) = 0;
722 virtual FontInfo
const * getFont() = 0;
760 PaintState & paintState() {
return m_paintState; }
762 void addPrimitive(Primitive & primitive);
764 void primitivesExecutionWait();
788 bool backgroundPrimitiveTimeoutEnabled() {
return m_backgroundPrimitiveTimeoutEnabled; }
838 template <
typename T>
893 virtual void readScreen(
Rect const & rect,
RGB888 * destBuf) = 0;
912 virtual void setPixelAt(PixelDesc
const & pixelDesc,
Rect & updateRect) = 0;
914 virtual void absDrawLine(
int X1,
int Y1,
int X2,
int Y2,
RGB888 color) = 0;
916 virtual void rawFillRow(
int y,
int x1,
int x2,
RGB888 color) = 0;
918 virtual void drawEllipse(
Size const & size,
Rect & updateRect) = 0;
920 virtual void clear(
Rect & updateRect) = 0;
922 virtual void VScroll(
int scroll,
Rect & updateRect) = 0;
924 virtual void HScroll(
int scroll,
Rect & updateRect) = 0;
928 virtual void invertRect(
Rect const & rect,
Rect & updateRect) = 0;
930 virtual void swapFGBG(
Rect const & rect,
Rect & updateRect) = 0;
932 virtual void copyRect(
Rect const & source,
Rect & updateRect) = 0;
934 virtual void swapBuffers() = 0;
936 virtual int getBitmapSavePixelSize() = 0;
938 virtual void rawDrawBitmap_Native(
int destX,
int destY,
Bitmap const * bitmap,
int X1,
int Y1,
int XCount,
int YCount) = 0;
940 virtual void rawDrawBitmap_Mask(
int destX,
int destY,
Bitmap const * bitmap,
void * saveBackground,
int X1,
int Y1,
int XCount,
int YCount) = 0;
942 virtual void rawDrawBitmap_RGBA2222(
int destX,
int destY,
Bitmap const * bitmap,
void * saveBackground,
int X1,
int Y1,
int XCount,
int YCount) = 0;
944 virtual void rawDrawBitmap_RGBA8888(
int destX,
int destY,
Bitmap const * bitmap,
void * saveBackground,
int X1,
int Y1,
int XCount,
int YCount) = 0;
948 void execPrimitive(Primitive
const & prim,
Rect & updateRect,
bool insideISR);
950 void updateAbsoluteClippingRect();
952 RGB888 getActualPenColor();
954 RGB888 getActualBrushColor();
956 void lineTo(
Point const & position,
Rect & updateRect);
958 void drawRect(
Rect const & rect,
Rect & updateRect);
960 void drawPath(Path
const & path,
Rect & updateRect);
962 void absDrawThickLine(
int X1,
int Y1,
int X2,
int Y2,
int penWidth,
RGB888 const & color);
964 void fillRect(
Rect const & rect,
RGB888 const & color,
Rect & updateRect);
966 void fillEllipse(
int centerX,
int centerY,
Size const & size,
RGB888 const & color,
Rect & updateRect);
968 void fillPath(Path
const & path,
RGB888 const & color,
Rect & updateRect);
970 void renderGlyphsBuffer(GlyphsBufferRenderInfo
const & glyphsBufferRenderInfo,
Rect & updateRect);
974 Sprite * getSprite(
int index);
976 int spritesCount() {
return m_spritesCount; }
978 void hideSprites(
Rect & updateRect);
980 void showSprites(
Rect & updateRect);
982 void drawBitmap(BitmapDrawingInfo
const & bitmapDrawingInfo,
Rect & updateRect);
984 void absDrawBitmap(
int destX,
int destY,
Bitmap const * bitmap,
void * saveBackground,
bool ignoreClippingRect);
986 void setDoubleBuffered(
bool value);
988 bool getPrimitive(Primitive * primitive,
int timeOutMS = 0);
990 bool getPrimitiveISR(Primitive * primitive);
992 void waitForPrimitives();
994 Sprite * mouseCursor() {
return &m_mouseCursor; }
996 void resetPaintState();
1000 void primitiveReplaceDynamicBuffers(Primitive & primitive);
1003 PaintState m_paintState;
1005 volatile bool m_doubleBuffered;
1006 volatile QueueHandle_t m_execQueue;
1008 bool m_backgroundPrimitiveExecutionEnabled;
1009 volatile bool m_backgroundPrimitiveTimeoutEnabled;
1014 bool m_spritesHidden;
1017 Sprite m_mouseCursor;
1018 int16_t m_mouseHotspotX;
1019 int16_t m_mouseHotspotY;
1022 LightMemoryPool m_primDynMemPool;
1034 class GenericBitmappedDisplayController :
public BitmappedDisplayController {
1039 template <
typename TPreparePixel,
typename TRawSetPixel>
1040 void genericSetPixelAt(PixelDesc
const & pixelDesc, Rect & updateRect, TPreparePixel preparePixel, TRawSetPixel rawSetPixel)
1042 const int x = pixelDesc.pos.X + paintState().origin.X;
1043 const int y = pixelDesc.pos.Y + paintState().origin.Y;
1045 const int clipX1 = paintState().absClippingRect.X1;
1046 const int clipY1 = paintState().absClippingRect.Y1;
1047 const int clipX2 = paintState().absClippingRect.X2;
1048 const int clipY2 = paintState().absClippingRect.Y2;
1050 if (x >= clipX1 && x <= clipX2 && y >= clipY1 && y <= clipY2) {
1051 updateRect = updateRect.merge(Rect(x, y, x, y));
1052 hideSprites(updateRect);
1053 rawSetPixel(x, y, preparePixel(pixelDesc.color));
1060 template <
typename TPreparePixel,
typename TRawFillRow,
typename TRawInvertRow,
typename TRawSetPixel,
typename TRawInvertPixel>
1061 void genericAbsDrawLine(
int X1,
int Y1,
int X2,
int Y2, RGB888
const & color, TPreparePixel preparePixel, TRawFillRow rawFillRow, TRawInvertRow rawInvertRow, TRawSetPixel rawSetPixel, TRawInvertPixel rawInvertPixel)
1063 if (paintState().penWidth > 1) {
1064 absDrawThickLine(
X1,
Y1,
X2,
Y2, paintState().penWidth, color);
1067 auto pattern = preparePixel(color);
1070 if (
Y1 < paintState().absClippingRect.Y1 ||
Y1 > paintState().absClippingRect.Y2)
1074 if (
X1 > paintState().absClippingRect.X2 ||
X2 < paintState().absClippingRect.X1)
1076 X1 = iclamp(
X1, paintState().absClippingRect.X1, paintState().absClippingRect.X2);
1077 X2 = iclamp(
X2, paintState().absClippingRect.X1, paintState().absClippingRect.X2);
1078 if (paintState().paintOptions.NOT)
1079 rawInvertRow(
Y1,
X1,
X2);
1081 rawFillRow(
Y1,
X1,
X2, pattern);
1082 }
else if (
X1 ==
X2) {
1084 if (
X1 < paintState().absClippingRect.X1 ||
X1 > paintState().absClippingRect.X2)
1088 if (
Y1 > paintState().absClippingRect.Y2 ||
Y2 < paintState().absClippingRect.Y1)
1090 Y1 = iclamp(
Y1, paintState().absClippingRect.Y1, paintState().absClippingRect.Y2);
1091 Y2 = iclamp(
Y2, paintState().absClippingRect.Y1, paintState().absClippingRect.Y2);
1092 if (paintState().paintOptions.NOT) {
1093 for (
int y =
Y1; y <=
Y2; ++y)
1094 rawInvertPixel(
X1, y);
1096 for (
int y =
Y1; y <=
Y2; ++y)
1097 rawSetPixel(
X1, y, pattern);
1111 if (!clipLine(
X1,
Y1,
X2,
Y2, paintState().absClippingRect,
true))
1113 const int dx = abs(
X2 -
X1);
1114 const int dy = abs(
Y2 -
Y1);
1115 const int sx =
X1 <
X2 ? 1 : -1;
1116 const int sy =
Y1 <
Y2 ? 1 : -1;
1117 int err = (dx > dy ? dx : -dy) / 2;
1119 if (paintState().absClippingRect.contains(
X1,
Y1)) {
1120 if (paintState().paintOptions.NOT)
1121 rawInvertPixel(
X1,
Y1);
1123 rawSetPixel(
X1,
Y1, pattern);
1142 template <
typename TPreparePixel,
typename TRawSetPixel>
1143 void genericDrawEllipse(Size
const & size, Rect & updateRect, TPreparePixel preparePixel, TRawSetPixel rawSetPixel)
1145 auto pattern = preparePixel(getActualPenColor());
1147 const int clipX1 = paintState().absClippingRect.X1;
1148 const int clipY1 = paintState().absClippingRect.Y1;
1149 const int clipX2 = paintState().absClippingRect.X2;
1150 const int clipY2 = paintState().absClippingRect.Y2;
1152 const int centerX = paintState().position.X;
1153 const int centerY = paintState().position.Y;
1155 const int halfWidth = size.width / 2;
1156 const int halfHeight = size.height / 2;
1158 updateRect = updateRect.merge(Rect(centerX - halfWidth, centerY - halfHeight, centerX + halfWidth, centerY + halfHeight));
1159 hideSprites(updateRect);
1161 const int a2 = halfWidth * halfWidth;
1162 const int b2 = halfHeight * halfHeight;
1163 const int crit1 = -(a2 / 4 + halfWidth % 2 + b2);
1164 const int crit2 = -(b2 / 4 + halfHeight % 2 + a2);
1165 const int crit3 = -(b2 / 4 + halfHeight % 2);
1166 const int d2xt = 2 * b2;
1167 const int d2yt = 2 * a2;
1171 int dxt = 2 * b2 * x;
1172 int dyt = -2 * a2 * y;
1174 while (y >= 0 && x <= halfWidth) {
1175 const int col1 = centerX - x;
1176 const int col2 = centerX + x;
1177 const int row1 = centerY - y;
1178 const int row2 = centerY + y;
1180 if (col1 >= clipX1 && col1 <= clipX2) {
1181 if (row1 >= clipY1 && row1 <= clipY2)
1182 rawSetPixel(col1, row1, pattern);
1183 if (row2 >= clipY1 && row2 <= clipY2)
1184 rawSetPixel(col1, row2, pattern);
1186 if (col2 >= clipX1 && col2 <= clipX2) {
1187 if (row1 >= clipY1 && row1 <= clipY2)
1188 rawSetPixel(col2, row1, pattern);
1189 if (row2 >= clipY1 && row2 <= clipY2)
1190 rawSetPixel(col2, row2, pattern);
1193 if (t + b2 * x <= crit1 || t + a2 * y <= crit3) {
1197 }
else if (t - a2 * y > crit2) {
1213 template <
typename TPreparePixel,
typename TRawGetRow,
typename TRawSetPixelInRow>
1214 void genericDrawGlyph(Glyph
const & glyph, GlyphOptions glyphOptions, RGB888 penColor, RGB888 brushColor, Rect & updateRect, TPreparePixel preparePixel, TRawGetRow rawGetRow, TRawSetPixelInRow rawSetPixelInRow)
1216 if (!glyphOptions.bold && !glyphOptions.italic && !glyphOptions.blank && !glyphOptions.underline && !glyphOptions.doubleWidth && glyph.width <= 32)
1217 genericDrawGlyph_light(glyph, glyphOptions, penColor, brushColor, updateRect, preparePixel, rawGetRow, rawSetPixelInRow);
1219 genericDrawGlyph_full(glyph, glyphOptions, penColor, brushColor, updateRect, preparePixel, rawGetRow, rawSetPixelInRow);
1224 template <
typename TPreparePixel,
typename TRawGetRow,
typename TRawSetPixelInRow>
1225 void genericDrawGlyph_full(Glyph
const & glyph, GlyphOptions glyphOptions, RGB888 penColor, RGB888 brushColor, Rect & updateRect, TPreparePixel preparePixel, TRawGetRow rawGetRow, TRawSetPixelInRow rawSetPixelInRow)
1227 const int clipX1 = paintState().absClippingRect.X1;
1228 const int clipY1 = paintState().absClippingRect.Y1;
1229 const int clipX2 = paintState().absClippingRect.X2;
1230 const int clipY2 = paintState().absClippingRect.Y2;
1232 const int origX = paintState().origin.X;
1233 const int origY = paintState().origin.Y;
1235 const int glyphX = glyph.X + origX;
1236 const int glyphY = glyph.Y + origY;
1238 if (glyphX > clipX2 || glyphY > clipY2)
1241 int16_t glyphWidth = glyph.width;
1242 int16_t glyphHeight = glyph.height;
1243 uint8_t
const * glyphData = glyph.data;
1244 int16_t glyphWidthByte = (glyphWidth + 7) / 8;
1245 int16_t glyphSize = glyphHeight * glyphWidthByte;
1248 bool bold = glyphOptions.bold;
1249 bool italic = glyphOptions.italic;
1250 bool blank = glyphOptions.blank;
1251 bool underline = glyphOptions.underline;
1257 uint8_t * newGlyphData = (uint8_t*) alloca(glyphSize);
1259 int offset = (
doubleWidth == 2 ? 0 : (glyphHeight >> 1));
1260 for (
int y = 0; y < glyphHeight ; ++y)
1261 for (
int x = 0; x < glyphWidthByte; ++x)
1262 newGlyphData[x + y * glyphWidthByte] = glyphData[x + (offset + (y >> 1)) * glyphWidthByte];
1263 glyphData = newGlyphData;
1267 int skewAdder = 0, skewH1 = 0, skewH2 = 0;
1270 skewH1 = glyphHeight / 3;
1271 skewH2 = skewH1 * 2;
1275 int16_t XCount = glyphWidth;
1276 int16_t destX = glyphX;
1278 if (destX < clipX1) {
1282 if (
X1 >= glyphWidth)
1285 if (destX + XCount + skewAdder > clipX2 + 1)
1286 XCount = clipX2 + 1 - destX - skewAdder;
1287 if (
X1 + XCount > glyphWidth)
1288 XCount = glyphWidth -
X1;
1291 int16_t YCount = glyphHeight;
1294 if (destY < clipY1) {
1295 Y1 = clipY1 - destY;
1298 if (
Y1 >= glyphHeight)
1301 if (destY + YCount > clipY2 + 1)
1302 YCount = clipY2 + 1 - destY;
1303 if (
Y1 + YCount > glyphHeight)
1304 YCount = glyphHeight -
Y1;
1306 updateRect = updateRect.merge(Rect(destX, destY, destX + XCount + skewAdder - 1, destY + YCount - 1));
1307 hideSprites(updateRect);
1309 if (glyphOptions.invert ^ paintState().paintOptions.swapFGBG)
1310 tswap(penColor, brushColor);
1313 if (glyphOptions.reduceLuminosity) {
1314 if (penColor.R > 128) penColor.R = 128;
1315 if (penColor.G > 128) penColor.G = 128;
1316 if (penColor.B > 128) penColor.B = 128;
1319 auto penPattern = preparePixel(penColor);
1320 auto brushPattern = preparePixel(brushColor);
1321 auto boldPattern =
bold ? preparePixel(RGB888(penColor.R / 2 + 1,
1323 penColor.B / 2 + 1))
1324 : preparePixel(RGB888(0, 0, 0));
1326 for (
int y =
Y1; y <
Y1 + YCount; ++y, ++destY) {
1329 bool prevSet =
false;
1331 auto dstrow = rawGetRow(destY);
1332 auto srcrow = glyphData + y * glyphWidthByte;
1336 for (
int x =
X1, adestX = destX + skewAdder; x <
X1 + XCount && adestX <= clipX2; ++x, ++adestX) {
1337 rawSetPixelInRow(dstrow, adestX,
blank ? brushPattern : penPattern);
1340 if (adestX > clipX2)
1342 rawSetPixelInRow(dstrow, adestX,
blank ? brushPattern : penPattern);
1348 for (
int x =
X1, adestX = destX + skewAdder; x <
X1 + XCount && adestX <= clipX2; ++x, ++adestX) {
1349 if ((srcrow[x >> 3] << (x & 7)) & 0x80 && !
blank) {
1350 rawSetPixelInRow(dstrow, adestX, penPattern);
1352 }
else if (
bold && prevSet) {
1353 rawSetPixelInRow(dstrow, adestX, boldPattern);
1356 rawSetPixelInRow(dstrow, adestX, brushPattern);
1363 if (adestX > clipX2)
1366 rawSetPixelInRow(dstrow, adestX, prevSet ? penPattern : brushPattern);
1368 rawSetPixelInRow(dstrow, adestX, penPattern);
1374 if (
italic && (y == skewH1 || y == skewH2))
1388 template <
typename TPreparePixel,
typename TRawGetRow,
typename TRawSetPixelInRow>
1389 void genericDrawGlyph_light(Glyph
const & glyph, GlyphOptions glyphOptions, RGB888 penColor, RGB888 brushColor, Rect & updateRect, TPreparePixel preparePixel, TRawGetRow rawGetRow, TRawSetPixelInRow rawSetPixelInRow)
1391 const int clipX1 = paintState().absClippingRect.X1;
1392 const int clipY1 = paintState().absClippingRect.Y1;
1393 const int clipX2 = paintState().absClippingRect.X2;
1394 const int clipY2 = paintState().absClippingRect.Y2;
1396 const int origX = paintState().origin.X;
1397 const int origY = paintState().origin.Y;
1399 const int glyphX = glyph.X + origX;
1400 const int glyphY = glyph.Y + origY;
1402 if (glyphX > clipX2 || glyphY > clipY2)
1405 int16_t glyphWidth = glyph.width;
1406 int16_t glyphHeight = glyph.height;
1407 uint8_t
const * glyphData = glyph.data;
1408 int16_t glyphWidthByte = (glyphWidth + 7) / 8;
1411 int16_t XCount = glyphWidth;
1412 int16_t destX = glyphX;
1415 int16_t YCount = glyphHeight;
1418 if (destX < clipX1) {
1419 X1 = clipX1 - destX;
1422 if (
X1 >= glyphWidth)
1425 if (destX + XCount > clipX2 + 1)
1426 XCount = clipX2 + 1 - destX;
1427 if (
X1 + XCount > glyphWidth)
1428 XCount = glyphWidth -
X1;
1430 if (destY < clipY1) {
1431 Y1 = clipY1 - destY;
1434 if (
Y1 >= glyphHeight)
1437 if (destY + YCount > clipY2 + 1)
1438 YCount = clipY2 + 1 - destY;
1439 if (
Y1 + YCount > glyphHeight)
1440 YCount = glyphHeight -
Y1;
1442 updateRect = updateRect.merge(Rect(destX, destY, destX + XCount - 1, destY + YCount - 1));
1443 hideSprites(updateRect);
1445 if (glyphOptions.invert ^ paintState().paintOptions.swapFGBG)
1446 tswap(penColor, brushColor);
1449 if (glyphOptions.reduceLuminosity) {
1450 if (penColor.R > 128) penColor.R = 128;
1451 if (penColor.G > 128) penColor.G = 128;
1452 if (penColor.B > 128) penColor.B = 128;
1457 auto penPattern = preparePixel(penColor);
1458 auto brushPattern = preparePixel(brushColor);
1460 for (
int y =
Y1; y <
Y1 + YCount; ++y, ++destY) {
1461 auto dstrow = rawGetRow(destY);
1462 uint8_t
const * srcrow = glyphData + y * glyphWidthByte;
1464 uint32_t src = (srcrow[0] << 24) | (srcrow[1] << 16) | (srcrow[2] << 8) | (srcrow[3]);
1468 for (
int x =
X1, adestX = destX; x <
X1 + XCount; ++x, ++adestX, src <<= 1)
1469 rawSetPixelInRow(dstrow, adestX, src & 0x80000000 ? penPattern : brushPattern);
1472 for (
int x =
X1, adestX = destX; x <
X1 + XCount; ++x, ++adestX, src <<= 1)
1473 if (src & 0x80000000)
1474 rawSetPixelInRow(dstrow, adestX, penPattern);
1480 template <
typename TRawInvertRow>
1481 void genericInvertRect(Rect
const & rect, Rect & updateRect, TRawInvertRow rawInvertRow)
1483 const int origX = paintState().origin.X;
1484 const int origY = paintState().origin.Y;
1486 const int clipX1 = paintState().absClippingRect.X1;
1487 const int clipY1 = paintState().absClippingRect.Y1;
1488 const int clipX2 = paintState().absClippingRect.X2;
1489 const int clipY2 = paintState().absClippingRect.Y2;
1491 const int x1 = iclamp(rect.X1 + origX, clipX1, clipX2);
1492 const int y1 = iclamp(rect.Y1 + origY, clipY1, clipY2);
1493 const int x2 = iclamp(rect.X2 + origX, clipX1, clipX2);
1494 const int y2 = iclamp(rect.Y2 + origY, clipY1, clipY2);
1496 updateRect = updateRect.merge(Rect(x1, y1, x2, y2));
1497 hideSprites(updateRect);
1499 for (
int y = y1; y <= y2; ++y)
1500 rawInvertRow(y, x1, x2);
1504 template <
typename TPreparePixel,
typename TRawGetRow,
typename TRawGetPixelInRow,
typename TRawSetPixelInRow>
1505 void genericSwapFGBG(Rect
const & rect, Rect & updateRect, TPreparePixel preparePixel, TRawGetRow rawGetRow, TRawGetPixelInRow rawGetPixelInRow, TRawSetPixelInRow rawSetPixelInRow)
1507 auto penPattern = preparePixel(paintState().penColor);
1508 auto brushPattern = preparePixel(paintState().brushColor);
1510 int origX = paintState().origin.X;
1511 int origY = paintState().origin.Y;
1513 const int clipX1 = paintState().absClippingRect.X1;
1514 const int clipY1 = paintState().absClippingRect.Y1;
1515 const int clipX2 = paintState().absClippingRect.X2;
1516 const int clipY2 = paintState().absClippingRect.Y2;
1518 const int x1 = iclamp(rect.X1 + origX, clipX1, clipX2);
1519 const int y1 = iclamp(rect.Y1 + origY, clipY1, clipY2);
1520 const int x2 = iclamp(rect.X2 + origX, clipX1, clipX2);
1521 const int y2 = iclamp(rect.Y2 + origY, clipY1, clipY2);
1523 updateRect = updateRect.merge(Rect(x1, y1, x2, y2));
1524 hideSprites(updateRect);
1526 for (
int y = y1; y <= y2; ++y) {
1527 auto row = rawGetRow(y);
1528 for (
int x = x1; x <= x2; ++x) {
1529 auto px = rawGetPixelInRow(row, x);
1530 if (px == penPattern)
1531 rawSetPixelInRow(row, x, brushPattern);
1532 else if (px == brushPattern)
1533 rawSetPixelInRow(row, x, penPattern);
1539 template <
typename TRawGetRow,
typename TRawGetPixelInRow,
typename TRawSetPixelInRow>
1540 void genericCopyRect(Rect
const & source, Rect & updateRect, TRawGetRow rawGetRow, TRawGetPixelInRow rawGetPixelInRow, TRawSetPixelInRow rawSetPixelInRow)
1542 const int clipX1 = paintState().absClippingRect.X1;
1543 const int clipY1 = paintState().absClippingRect.Y1;
1544 const int clipX2 = paintState().absClippingRect.X2;
1545 const int clipY2 = paintState().absClippingRect.Y2;
1547 int origX = paintState().origin.X;
1548 int origY = paintState().origin.Y;
1550 int srcX = source.X1 + origX;
1551 int srcY = source.Y1 + origY;
1552 int width = source.X2 - source.X1 + 1;
1553 int height = source.Y2 - source.Y1 + 1;
1554 int destX = paintState().position.X;
1555 int destY = paintState().position.Y;
1556 int deltaX = destX - srcX;
1557 int deltaY = destY - srcY;
1559 int incX = deltaX < 0 ? 1 : -1;
1560 int incY = deltaY < 0 ? 1 : -1;
1562 int startX = deltaX < 0 ? destX : destX +
width - 1;
1563 int startY = deltaY < 0 ? destY : destY +
height - 1;
1565 updateRect = updateRect.merge(Rect(srcX, srcY, srcX +
width - 1, srcY +
height - 1));
1566 updateRect = updateRect.merge(Rect(destX, destY, destX +
width - 1, destY +
height - 1));
1567 hideSprites(updateRect);
1569 for (
int y = startY, i = 0; i <
height; y += incY, ++i) {
1570 if (y >= clipY1 && y <= clipY2) {
1571 auto srcRow = rawGetRow(y - deltaY);
1572 auto dstRow = rawGetRow(y);
1573 for (
int x = startX, j = 0; j <
width; x += incX, ++j) {
1574 if (x >= clipX1 && x <= clipX2)
1575 rawSetPixelInRow(dstRow, x, rawGetPixelInRow(srcRow, x - deltaX));
1582 template <
typename TRawGetRow,
typename TRawSetPixelInRow,
typename TDataType>
1583 void genericRawDrawBitmap_Native(
int destX,
int destY, TDataType *
data,
int width,
int X1,
int Y1,
int XCount,
int YCount,
1584 TRawGetRow rawGetRow, TRawSetPixelInRow rawSetPixelInRow)
1586 const int yEnd =
Y1 + YCount;
1587 const int xEnd =
X1 + XCount;
1588 for (
int y =
Y1; y < yEnd; ++y, ++destY) {
1589 auto dstrow = rawGetRow(destY);
1591 for (
int x =
X1, adestX = destX; x < xEnd; ++x, ++adestX, ++src)
1592 rawSetPixelInRow(dstrow, adestX, *src);
1598 template <
typename TRawGetRow,
typename TRawGetPixelInRow,
typename TRawSetPixelInRow,
typename TBackground>
1599 void genericRawDrawBitmap_Mask(
int destX,
int destY, Bitmap
const * bitmap, TBackground * saveBackground,
int X1,
int Y1,
int XCount,
int YCount,
1600 TRawGetRow rawGetRow, TRawGetPixelInRow rawGetPixelInRow, TRawSetPixelInRow rawSetPixelInRow)
1602 const int width = bitmap->width;
1603 const int yEnd =
Y1 + YCount;
1604 const int xEnd =
X1 + XCount;
1605 auto data = bitmap->data;
1606 const int rowlen = (bitmap->width + 7) / 8;
1608 if (saveBackground) {
1611 for (
int y =
Y1; y < yEnd; ++y, ++destY) {
1612 auto dstrow = rawGetRow(destY);
1613 auto savePx = saveBackground + y *
width +
X1;
1614 auto src =
data + y * rowlen;
1615 for (
int x =
X1, adestX = destX; x < xEnd; ++x, ++adestX, ++savePx) {
1616 *savePx = rawGetPixelInRow(dstrow, adestX);
1617 if ((src[x >> 3] << (x & 7)) & 0x80)
1618 rawSetPixelInRow(dstrow, adestX);
1625 for (
int y =
Y1; y < yEnd; ++y, ++destY) {
1626 auto dstrow = rawGetRow(destY);
1627 auto src =
data + y * rowlen;
1628 for (
int x =
X1, adestX = destX; x < xEnd; ++x, ++adestX) {
1629 if ((src[x >> 3] << (x & 7)) & 0x80)
1630 rawSetPixelInRow(dstrow, adestX);
1638 template <
typename TRawGetRow,
typename TRawGetPixelInRow,
typename TRawSetPixelInRow,
typename TBackground>
1639 void genericRawDrawBitmap_RGBA2222(
int destX,
int destY, Bitmap
const * bitmap, TBackground * saveBackground,
int X1,
int Y1,
int XCount,
int YCount,
1640 TRawGetRow rawGetRow, TRawGetPixelInRow rawGetPixelInRow, TRawSetPixelInRow rawSetPixelInRow)
1642 const int width = bitmap->width;
1643 const int yEnd =
Y1 + YCount;
1644 const int xEnd =
X1 + XCount;
1645 auto data = bitmap->data;
1647 if (saveBackground) {
1650 for (
int y =
Y1; y < yEnd; ++y, ++destY) {
1651 auto dstrow = rawGetRow(destY);
1652 auto savePx = saveBackground + y *
width +
X1;
1654 for (
int x =
X1, adestX = destX; x < xEnd; ++x, ++adestX, ++savePx, ++src) {
1655 *savePx = rawGetPixelInRow(dstrow, adestX);
1657 rawSetPixelInRow(dstrow, adestX, *src);
1664 for (
int y =
Y1; y < yEnd; ++y, ++destY) {
1665 auto dstrow = rawGetRow(destY);
1667 for (
int x =
X1, adestX = destX; x < xEnd; ++x, ++adestX, ++src) {
1669 rawSetPixelInRow(dstrow, adestX, *src);
1677 template <
typename TRawGetRow,
typename TRawGetPixelInRow,
typename TRawSetPixelInRow,
typename TBackground>
1678 void genericRawDrawBitmap_RGBA8888(
int destX,
int destY, Bitmap
const * bitmap, TBackground * saveBackground,
int X1,
int Y1,
int XCount,
int YCount,
1679 TRawGetRow rawGetRow, TRawGetPixelInRow rawGetPixelInRow, TRawSetPixelInRow rawSetPixelInRow)
1681 const int width = bitmap->width;
1682 const int yEnd =
Y1 + YCount;
1683 const int xEnd =
X1 + XCount;
1686 if (saveBackground) {
1689 for (
int y =
Y1; y < yEnd; ++y, ++destY) {
1690 auto dstrow = rawGetRow(destY);
1691 auto savePx = saveBackground + y *
width +
X1;
1693 for (
int x =
X1, adestX = destX; x < xEnd; ++x, ++adestX, ++savePx, ++src) {
1694 *savePx = rawGetPixelInRow(dstrow, adestX);
1696 rawSetPixelInRow(dstrow, adestX, *src);
1703 for (
int y =
Y1; y < yEnd; ++y, ++destY) {
1704 auto dstrow = rawGetRow(destY);
1706 for (
int x =
X1, adestX = destX; x < xEnd; ++x, ++adestX, ++src) {
1708 rawSetPixelInRow(dstrow, adestX, *src);
1719 template <
typename TRawCopyRow,
typename TRawFillRow>
1720 void genericVScroll(
int scroll, Rect & updateRect,
1721 TRawCopyRow rawCopyRow, TRawFillRow rawFillRow)
1723 hideSprites(updateRect);
1724 RGB888 color = getActualBrushColor();
1725 int Y1 = paintState().scrollingRegion.Y1;
1726 int Y2 = paintState().scrollingRegion.Y2;
1727 int X1 = paintState().scrollingRegion.X1;
1728 int X2 = paintState().scrollingRegion.X2;
1735 for (
int i = 0; i <
height + scroll; ++i) {
1737 rawCopyRow(
X1,
X2, (
Y1 + i - scroll), (
Y1 + i));
1741 rawFillRow(
Y1 + i,
X1,
X2, color);
1743 }
else if (scroll > 0) {
1746 for (
int i =
height - scroll - 1; i >= 0; --i) {
1748 rawCopyRow(
X1,
X2, (
Y1 + i), (
Y1 + i + scroll));
1752 for (
int i = 0; i < scroll; ++i)
1753 rawFillRow(
Y1 + i,
X1,
X2, color);
1762 template <
typename TSwapRowsCopying,
typename TSwapRowsPo
inters,
typename TRawFillRow>
1763 void genericVScroll(
int scroll, Rect & updateRect,
1764 TSwapRowsCopying swapRowsCopying, TSwapRowsPointers swapRowsPointers, TRawFillRow rawFillRow)
1766 hideSprites(updateRect);
1767 RGB888 color = getActualBrushColor();
1768 const int Y1 = paintState().scrollingRegion.Y1;
1769 const int Y2 = paintState().scrollingRegion.Y2;
1770 const int X1 = paintState().scrollingRegion.X1;
1771 const int X2 = paintState().scrollingRegion.X2;
1780 for (
int i = 0; i <
height + scroll; ++i) {
1784 swapRowsCopying(
Y1 + i,
Y1 + i - scroll, 0,
X1 - 1);
1785 if (
X2 < viewPortWidth - 1)
1786 swapRowsCopying(
Y1 + i,
Y1 + i - scroll,
X2 + 1, viewPortWidth - 1);
1789 swapRowsPointers(
Y1 + i,
Y1 + i - scroll);
1794 rawFillRow(
Y1 + i,
X1,
X2, color);
1796 }
else if (scroll > 0) {
1799 for (
int i =
height - scroll - 1; i >= 0; --i) {
1803 swapRowsCopying(
Y1 + i,
Y1 + i + scroll, 0,
X1 - 1);
1804 if (
X2 < viewPortWidth - 1)
1805 swapRowsCopying(
Y1 + i,
Y1 + i + scroll,
X2 + 1, viewPortWidth - 1);
1808 swapRowsPointers(
Y1 + i,
Y1 + i + scroll);
1812 for (
int i = 0; i < scroll; ++i)
1813 rawFillRow(
Y1 + i,
X1,
X2, color);
1823 template <
typename TPreparePixel,
typename TRawGetRow,
typename TRawGetPixelInRow,
typename TRawSetPixelInRow>
1824 void genericHScroll(
int scroll, Rect & updateRect,
1825 TPreparePixel preparePixel, TRawGetRow rawGetRow, TRawGetPixelInRow rawGetPixelInRow, TRawSetPixelInRow rawSetPixelInRow)
1827 hideSprites(updateRect);
1828 auto pattern = preparePixel(getActualBrushColor());
1830 int Y1 = paintState().scrollingRegion.Y1;
1831 int Y2 = paintState().scrollingRegion.Y2;
1832 int X1 = paintState().scrollingRegion.X1;
1833 int X2 = paintState().scrollingRegion.X2;
1837 for (
int y =
Y1; y <=
Y2; ++y) {
1838 auto row = rawGetRow(y);
1839 for (
int x =
X1; x <=
X2 + scroll; ++x) {
1840 auto c = rawGetPixelInRow(row, x - scroll);
1841 rawSetPixelInRow(row, x, c);
1844 for (
int x =
X2 + 1 + scroll; x <=
X2; ++x)
1845 rawSetPixelInRow(row, x, pattern);
1847 }
else if (scroll > 0) {
1849 for (
int y =
Y1; y <=
Y2; ++y) {
1850 auto row = rawGetRow(y);
1851 for (
int x =
X2 - scroll; x >=
X1; --x) {
1852 auto c = rawGetPixelInRow(row, x);
1853 rawSetPixelInRow(row, x + scroll, c);
1856 for (
int x =
X1; x <
X1 + scroll; ++x)
1857 rawSetPixelInRow(row, x, pattern);
Represents a 24 bit RGB color.
void setSprites(T *sprites, int count)
Sets the list of active sprites.
virtual void resumeBackgroundPrimitiveExecution()=0
Resumes drawings after suspendBackgroundPrimitiveExecution().
uint16_t reduceLuminosity
Color
This enum defines named colors.
Represents the base abstract class for bitmapped display controllers.
GlyphOptions & Invert(uint8_t value)
Helper method to set or reset foreground and background swapping.
LineEnds
This enum defines line ends when pen width is greater than 1.
GlyphOptions & DoubleWidth(uint8_t value)
Helper method to set or reset doubleWidth.
GlyphOptions & Italic(bool value)
Helper method to set or reset italic.
int getScreenWidth()
Determines the screen width in pixels.
virtual int getViewPortWidth()=0
Determines horizontal size of the viewport.
virtual int getViewPortHeight()=0
Determines vertical size of the viewport.
PixelFormat
This enum defines a pixel format.
DisplayControllerType controllerType()
Determines the display controller type.
Represents a glyph position, size and binary data.
Represents the coordinate of a point.
void refreshSprites()
Forces the sprites to be updated.
This file contains some utility classes and functions.
int getScreenHeight()
Determines the screen height in pixels.
GlyphOptions & Underline(bool value)
Helper method to set or reset underlined.
NativePixelFormat
This enum defines the display controller native pixel format.
void enableBackgroundPrimitiveExecution(bool value)
Enables or disables drawings inside vertical retracing time.
Represents a 32 bit RGBA color.
virtual DisplayControllerType controllerType()=0
Determines the display controller type.
Specifies various glyph painting options.
CursorName
This enum defines a set of predefined mouse cursors.
void setMouseCursor(Cursor *cursor)
Sets mouse cursor and make it visible.
This file contains FabGL library configuration settings, like number of supported colors...
static int queueSize
Size of display controller primitives queue.
virtual void suspendBackgroundPrimitiveExecution()=0
Suspends drawings.
#define FABGLIB_UNDERLINE_POSITION
Represents a bidimensional size.
DisplayControllerType controllerType()
Determines the display controller type.
void setMouseCursorPos(int X, int Y)
Sets mouse cursor position.
void processPrimitives()
Draws immediately all primitives in the queue.
bool isDoubleBuffered()
Determines whether BitmappedDisplayController is on double buffered mode.
Represents an 8 bit ABGR color.
DisplayControllerType
This enum defines types of display controllers.
void removeSprites()
Empties the list of active sprites.
Represents a 6 bit RGB color.
GlyphOptions & Bold(bool value)
Helper method to set or reset bold.
Represents the base abstract class for all display controllers.
Represents the base abstract class for textual display controllers.
GlyphOptions & Blank(uint8_t value)
Helper method to set or reset foreground and background swapping.
void enableBackgroundPrimitiveTimeout(bool value)
Enables or disables execution time limitation inside vertical retracing interrupt.
Specifies general paint options.
virtual NativePixelFormat nativePixelFormat()=0
Represents the native pixel format used by this display.
GlyphOptions & FillBackground(bool value)
Helper method to set or reset fillBackground.