Ich bastel gerade an einer einfachen Version einer Blocksatz-Funktion.
Sie soll in Zeilen 'Hairspace' einfügen, um einen Blocksatz zu realisieren.
Leider werden die Zeichen U+2009 (Thin Space) Oder U+200A (Hair Space) nur als Kästchen mit 10 Pixel Breite angezeigt.
Anbei die Funktion, in der noch eine Menge dsyslog's sind
Code
void JustifyLine(std::string &Line, cFont *Font, int LineMaxWidth) { // NOLINT
if (isempty(Line.c_str())) { // Check for empty line
dsyslog("flatPlus: JustifyLine() ---Empty line---");
return;
}
// Count spaces in 'Line'
int LineSpaces {0};
for (auto &ch : Line)
if (ch == ' ') ++LineSpaces;
// Hair Space is a very small space: https://de.wikipedia.org/wiki/Leerzeichen#Schriftzeichen_in_ASCII_und_andere_Kodierungen
// Schmales Leerzeichen U+2009 (thinsp)
const char *FillChar = u8"\U00002009"; // U+200A (Decimal 8202)
int FillCharWidth = Font->Width(FillChar);
// Check if at least one fill char fits in to the line
int LineWidth = Font->Width(Line.c_str()); // Width in Pixel
if ((LineWidth + FillCharWidth) > LineMaxWidth) {
dsyslog("flatPlus: JustifyLine() ---Line too long for extra space---");
return;
}
if (LineSpaces == 0 || FillCharWidth == 0) { // Avoid div/0 with lines without space
dsyslog("flatPlus: JustifyLine() Zero value found: Spaces: %d, FillCharWidth: %d", LineSpaces, FillCharWidth);
return;
}
// How many fill char we need?
int NeedFillChar = (LineMaxWidth - LineWidth) / FillCharWidth;
int FillCharBlock = NeedFillChar / LineSpaces; // For inserting multiple 'FillChar'
int FillCharRemainder = NeedFillChar % LineSpaces;
std::string FillChars("");
for (int i {0}; i < FillCharBlock; ++i) { // Create 'FillChars' block for inserting
FillChars.append(FillChar);
}
size_t FillCharsLength = FillChars.size();
if (LineWidth > (LineMaxWidth * 0.6)) { // Lines shorter than 60% looking bad when justified
dsyslog("flatPlus: JustifyLine() [Line: %d Space, %d width]"
" [FillChar: %d needed, %d blocksize, %d remainder, %d width]"
" [FillChars: %ld length]",
LineSpaces, LineWidth, NeedFillChar, FillCharBlock, FillCharRemainder, FillCharWidth, FillCharsLength);
int InsertedFillChar {0};
size_t pos = Line.find_first_of(' ');
if ((FillCharBlock > 0) && InsertedFillChar <= (NeedFillChar - FillCharBlock)) { // Is space for one block?
pos = Line.find_first_of(' ');
while (pos != std::string::npos && ((InsertedFillChar + FillCharBlock) < NeedFillChar)) {
if (!(isspace(Line[pos - 1]))) {
dsyslog("flatPlus: Insert block at %ld", pos);
Line.insert(pos, FillChars);
InsertedFillChar += FillCharBlock;
}
pos = Line.find_first_of(' ', pos + FillCharsLength + 1); // Add inserted chars plus 1
}
dsyslog("flatPlus: JustifyLine() InsertedFillChar after second loop (' '): %d", InsertedFillChar);
}
// Insert the remainder of 'NeedFillChar'
if (InsertedFillChar <= (NeedFillChar - 1)) {
pos = Line.find_first_of(' ');
while (pos != std::string::npos && (InsertedFillChar < NeedFillChar)) {
if (!(isspace(Line[pos - 1]))) {
dsyslog("flatPlus: Insert char at %ld", pos);
Line.insert(pos, FillChar);
++InsertedFillChar;
}
pos = Line.find_first_of(' ', pos + 4); // 'FillChar' length is 3
}
dsyslog("flatPlus: JustifyLine() InsertedFillChar after third loop (' '): %d", InsertedFillChar);
}
} else {
dsyslog("flatPlus: JustifyLine() Line too short for justifying: %.0f/%d", LineMaxWidth * 0.6, LineMaxWidth);
// return;
}
}
Display More
Ein Auszug vom Log für die ersten zwei langen Zeilen:
Code
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: JustifyLine() [Line: 13 Space, 727 width] [FillChar: 2 needed, 0 blocksize, 2 remainder, 10 width] [FillChars: 0 length]
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 8
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 18
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: JustifyLine() InsertedFillChar after third loop (' '): 2
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: JustifyLine() [Line: 10 Space, 708 width] [FillChar: 4 needed, 0 blocksize, 4 remainder, 10 width] [FillChars: 0 length]
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 8
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 13
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 26
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 37
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: JustifyLine() InsertedFillChar after third loop (' '): 4
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: JustifyLine() [Line: 11 Space, 713 width] [FillChar: 4 needed, 0 blocksize, 4 remainder, 10 width] [FillChars: 0 length]
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 7
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 14
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 22
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: Insert char at 38
Feb 27 11:08:42 yavdr-vbox vdr[26565]: [26565] flatPlus: JustifyLine() InsertedFillChar after third loop (' '): 4
Display More
Das muss irgendwas mit Unicode und UTF-8 zu tun haben. Ich könnt eLeerzeichen verwenden, aber die sind 5 Pixel breit. Das Hair Space dürfte eher im Bereich von einem oder zwei Pixel liegen und würde auch ein optisch gutes Ergebnis liefern.
Vielleicht hat jemand ne Idee warum das nicht klappt?