MCPcopy Create free account
hub / github.com/crosspoint-reader/crosspoint-reader / drawBitmap

Method drawBitmap

lib/GfxRenderer/GfxRenderer.cpp:1061–1167  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1059}
1060
1061void GfxRenderer::drawBitmap(const Bitmap& bitmap, const int x, const int y, const int maxWidth, const int maxHeight,
1062 const float cropX, const float cropY) const {
1063 if (fontCacheManager_ && fontCacheManager_->isScanning()) return;
1064 // For 1-bit bitmaps, use optimized 1-bit rendering path (no crop support for 1-bit)
1065 if (bitmap.is1Bit() && cropX == 0.0f && cropY == 0.0f) {
1066 drawBitmap1Bit(bitmap, x, y, maxWidth, maxHeight);
1067 return;
1068 }
1069
1070 float scale = 1.0f;
1071 bool isScaled = false;
1072 int cropPixX = std::floor(bitmap.getWidth() * cropX / 2.0f);
1073 int cropPixY = std::floor(bitmap.getHeight() * cropY / 2.0f);
1074 LOG_DBG("GFX", "Cropping %dx%d by %dx%d pix, is %s", bitmap.getWidth(), bitmap.getHeight(), cropPixX, cropPixY,
1075 bitmap.isTopDown() ? "top-down" : "bottom-up");
1076
1077 const float croppedWidth = (1.0f - cropX) * static_cast<float>(bitmap.getWidth());
1078 const float croppedHeight = (1.0f - cropY) * static_cast<float>(bitmap.getHeight());
1079 bool hasTargetBounds = false;
1080 float fitScale = 1.0f;
1081
1082 if (maxWidth > 0 && croppedWidth > 0.0f) {
1083 fitScale = static_cast<float>(maxWidth) / croppedWidth;
1084 hasTargetBounds = true;
1085 }
1086
1087 if (maxHeight > 0 && croppedHeight > 0.0f) {
1088 const float heightScale = static_cast<float>(maxHeight) / croppedHeight;
1089 fitScale = hasTargetBounds ? std::min(fitScale, heightScale) : heightScale;
1090 hasTargetBounds = true;
1091 }
1092
1093 if (hasTargetBounds && fitScale < 1.0f) {
1094 scale = fitScale;
1095 isScaled = true;
1096 }
1097 LOG_DBG("GFX", "Scaling by %f - %s", scale, isScaled ? "scaled" : "not scaled");
1098
1099 // Calculate output row size (2 bits per pixel, packed into bytes)
1100 // IMPORTANT: Use int, not uint8_t, to avoid overflow for images > 1020 pixels wide
1101 const int outputRowSize = (bitmap.getWidth() + 3) / 4;
1102 auto* outputRow = static_cast<uint8_t*>(malloc(outputRowSize));
1103 auto* rowBytes = static_cast<uint8_t*>(malloc(bitmap.getRowBytes()));
1104
1105 if (!outputRow || !rowBytes) {
1106 LOG_ERR("GFX", "!! Failed to allocate BMP row buffers");
1107 free(outputRow);
1108 free(rowBytes);
1109 return;
1110 }
1111
1112 for (int bmpY = 0; bmpY < (bitmap.getHeight() - cropPixY); bmpY++) {
1113 // The BMP's (0, 0) is the bottom-left corner (if the height is positive, top-left if negative).
1114 // Screen's (0, 0) is the top-left corner.
1115 int screenY = -cropPixY + (bitmap.isTopDown() ? bmpY : bitmap.getHeight() - 1 - bmpY);
1116 if (isScaled) {
1117 screenY = std::floor(screenY * scale);
1118 }

Callers 6

drawRecentBookCoverMethod · 0.80
drawRecentBookCoverMethod · 0.80
drawRecentBookCoverMethod · 0.80
drawRecentBookCoverMethod · 0.80
onEnterMethod · 0.80

Calls 7

isScanningMethod · 0.80
is1BitMethod · 0.80
isTopDownMethod · 0.80
getRowBytesMethod · 0.80
readNextRowMethod · 0.80
getWidthMethod · 0.45
getHeightMethod · 0.45

Tested by

no test coverage detected