Open dobraMorda opened 2 years ago
I made this feature in my local code. To avoid potential damage to the rest of the code, I wrote two separate methods. If someone want to use this feature you can add below methods to OLEDDisplay.cpp file:
void OLEDDisplay::drawStringInternalNegative( int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth ) {
uint8_t textHeight = pgm_read_byte( fontData + HEIGHT_POS );
uint8_t firstChar = pgm_read_byte( fontData + FIRST_CHAR_POS );
uint16_t sizeOfJumpTable = pgm_read_byte( fontData + CHAR_NUM_POS ) * JUMPTABLE_BYTES;
uint16_t cursorX = 0;
uint16_t cursorY = 0;
switch ( textAlignment ) {
case TEXT_ALIGN_CENTER_BOTH:
yMove -= textHeight >> 1;
// Fallthrough
case TEXT_ALIGN_CENTER:
xMove -= textWidth >> 1; // divide by 2
break;
case TEXT_ALIGN_RIGHT:
xMove -= textWidth;
break;
case TEXT_ALIGN_LEFT:
break;
}
// Don't draw anything if it is not on the screen.
if ( xMove + textWidth < 0 || xMove > this->width( ) ) {
return;
}
if ( yMove + textHeight < 0 || yMove > this->width( ) ) {
return;
}
// inverse color again
setColor( WHITE );
// fill rect under text
fillRect( xMove, yMove + 2, textWidth, textHeight - 4 );
// inverse color
setColor( BLACK );
for ( uint16_t j = 0; j < textLength; j++ ) {
int16_t xPos = xMove + cursorX;
int16_t yPos = yMove + cursorY;
uint8_t code = text[ j ];
if ( code >= firstChar ) {
uint8_t charCode = code - firstChar;
// 4 Bytes per char code
uint8_t msbJumpToChar = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES ); // MSB \ JumpAddress
uint8_t lsbJumpToChar = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_LSB ); // LSB /
uint8_t charByteSize = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_SIZE ); // Size
uint8_t currentCharWidth = pgm_read_byte( fontData + JUMPTABLE_START + charCode * JUMPTABLE_BYTES + JUMPTABLE_WIDTH ); // Width
// Test if the char is drawable
if ( !( msbJumpToChar == 255 && lsbJumpToChar == 255 ) ) {
// Get the position of the char data
uint16_t charDataPosition = JUMPTABLE_START + sizeOfJumpTable + ( ( msbJumpToChar << 8 ) + lsbJumpToChar );
drawInternal( xPos, yPos, currentCharWidth, textHeight, fontData, charDataPosition, charByteSize );
}
cursorX += currentCharWidth;
}
}
// inverse color again to back to normal mode
setColor( WHITE );
}
void OLEDDisplay::drawStringNegative( int16_t xMove, int16_t yMove, const String& strUser ) {
uint16_t lineHeight = pgm_read_byte( fontData + HEIGHT_POS );
// char* text must be freed!
char* text = utf8ascii( strUser );
uint16_t yOffset = 0;
// If the string should be centered vertically too
// we need to now how heigh the string is.
if ( textAlignment == TEXT_ALIGN_CENTER_BOTH ) {
uint16_t lb = 0;
// Find number of linebreaks in text
for ( uint16_t i = 0; text[ i ] != 0; i++ ) {
lb += ( text[ i ] == 10 );
}
// Calculate center
yOffset = ( lb * lineHeight ) / 2;
}
uint16_t line = 0;
char* textPart = strtok( text, "\n" );
while ( textPart != NULL ) {
uint16_t length = strlen( textPart );
drawStringInternalNegative( xMove, yMove - yOffset + ( line++ ) * lineHeight, textPart, length, getStringWidth( textPart, length ) );
textPart = strtok( NULL, "\n" );
}
free( text );
}
And then you need to add declare of methods in .h file:
in public section:
void drawStringNegative( int16_t xMove, int16_t yMove, const String& strUser );
in protected section:
void drawStringInternalNegative( int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth );
@marcelstoer If You accept this feature and the code I wrote is correct for you, feel free to add it to your library!
Thanks for the proposal and your willingness to help the community. I like the idea, it sounds sane. However, I am not happy with the proposed implementation for two primary reasons:
Alternative I:
bool inverseColor
state flag to OLEDDisplay
void setInverseColor(bool inverseColor)
to OLEDDisplay
change the statedrawStringInternal
functionbool inverse
parameter (e.g. like drawIco16x16()
)Alternative II:
bool inverse = false
parameter to the various drawString
functions (just like drawIco16x16()
has)
Hello!
Did you think anytime about add new feature to this library which can make draw string in negative like in below picture? I think it will be great feature to making multi menus with scrolling screen to easy showing selected position in menu.I think it should be method like drawNegativeString(x, y, message). Maybe I can help with that for you?
Best Regards!