diff --git a/src/Table.cpp b/src/Table.cpp index 76197547a..34773df9a 100644 --- a/src/Table.cpp +++ b/src/Table.cpp @@ -108,7 +108,7 @@ void Table::setTableDashedUnderline () int Table::addColumn (const std::string& col) { mSpecifiedWidth.push_back (minimum); - mMaxDataWidth.push_back (col == "" ? 1 : col.length ()); + mMaxDataWidth.push_back (col == "" ? 1 : getCharLength (col)); mCalculatedWidth.push_back (0); mColumnPadding.push_back (0); @@ -179,7 +179,7 @@ void Table::setRowColor (const int row, const Color& c) //////////////////////////////////////////////////////////////////////////////// void Table::addCell (const int row, const int col, const std::string& data) { - unsigned int length = 0; + int length = 0; if (mCommify.find (col) != mCommify.end ()) mData.add (row, col, commify (data)); @@ -193,14 +193,14 @@ void Table::addCell (const int row, const int col, const std::string& data) std::vector lines; split (lines, data, "\n"); for (unsigned int i = 0; i < lines.size (); ++i) - if (lines[i].length () > length) - length = lines[i].length (); + if (getCharLength (lines[i]) > length) + length = getCharLength (lines[i]); } else - length = data.length (); + length = getCharLength (data); // Automatically maintain max width. - mMaxDataWidth[col] = max (mMaxDataWidth[col], (int)length); + mMaxDataWidth[col] = max (mMaxDataWidth[col], length); } //////////////////////////////////////////////////////////////////////////////// @@ -435,6 +435,25 @@ Table::just Table::getHeaderJustification (int col) : left; } +//////////////////////////////////////////////////////////////////////////////// +int Table::getCharLength (const std::string& str) +{ + int byteLength = str.length (); + int charLength = byteLength; + const char* data = str.data (); + + // decrement the number of bytes for each byte that matches 0b10?????? + // this way only the first byte of any utf8 sequence is counted + for (int i = 0; i < byteLength; i++) + { + // extract the two MSB and check whether they are 10 + if ((data[i] & 0xC0) == 0x80) + charLength--; + } + + return charLength; +} + //////////////////////////////////////////////////////////////////////////////// // data One Data to be rendered // width 8 Max data width for column/specified width @@ -459,7 +478,7 @@ const std::string Table::formatHeader ( std::string data = mColumns[col]; Color c = getHeaderUnderline (col); - int gap = width - strippedLength (data); + int gap = width - strippedLength (data); // TODO Does this need Table::getCharLength too? std::string pad = std::string (padding, ' '); @@ -542,7 +561,7 @@ void Table::formatCell ( for (size_t chunk = 0; chunk < chunks.size (); ++chunk) { // Place the data within the available space - justify. - int gap = width - chunks[chunk].length (); + int gap = width - getCharLength (chunks[chunk]); preJust = ""; postJust = ""; diff --git a/src/Table.h b/src/Table.h index 01d8e3cf8..0b791d91b 100644 --- a/src/Table.h +++ b/src/Table.h @@ -100,6 +100,7 @@ private: void calculateColumnWidths (); just getJustification (const int, const int); just getHeaderJustification (const int); + int getCharLength (const std::string&); const std::string formatHeader (const int, const int, const int); const std::string formatHeaderDashedUnderline (const int, const int, const int); void formatCell (const int, const int, const int, const int, const int, std::vector &, std::string&);