Made copy_from_start() more clear and probably faster.
Commented out a check that would prevent characters smaller than B_UTF8_ELLIPSIS to be rendered (ie. the maximum width could be less than the ellipsisWidth but greater than the complete string width for small strings). Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13013 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -735,47 +735,49 @@ do_minimize_team(BRect zoomRect, team_id team, bool zoom)
|
|||||||
// ToDo: implement me, needed for Deskbar!
|
// ToDo: implement me, needed for Deskbar!
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy_from_start
|
|
||||||
|
// #pragma mark - truncate string
|
||||||
|
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
copy_from_start(const char* src, char* dst, uint32 numChars,
|
copy_from_start(const char* source, char* dest, uint32 numChars,
|
||||||
const float* escapementArray, float width, float ellipsisWidth, float size)
|
const float* escapementArray, float width, float ellipsisWidth, float size)
|
||||||
{
|
{
|
||||||
//printf("copy_from_start: %.1f\n", width);
|
|
||||||
float currentWidth = 0.0;
|
float currentWidth = 0.0;
|
||||||
for (uint32 c = 0; c < numChars; c++) {
|
ellipsisWidth /= size; // test if this is as accurate as escapementArray * size
|
||||||
//printf("forward: %c (%ld) (%.1f + %.1f = %.1f)\n", *src, c, currentWidth, escapementArray[c] * size, currentWidth + escapementArray[c] * size);
|
width /= size;
|
||||||
currentWidth += escapementArray[c] * size;
|
uint32 lastFit = 0, c;
|
||||||
if (currentWidth > width) {
|
|
||||||
//*dst = *src;
|
for (c = 0; c < numChars; c++) {
|
||||||
// ups, we definitely don't fit. go back until the ellipsis fits
|
currentWidth += escapementArray[c];
|
||||||
currentWidth += ellipsisWidth;
|
if (currentWidth + ellipsisWidth <= width)
|
||||||
for (int32 c2 = c; c2 >= 0; c2--) {
|
lastFit = c;
|
||||||
//printf(" backward: %c (%ld) (%.1f - %.1f = %.1f)\n", *dst, c2, currentWidth, escapementArray[c2] * size, currentWidth - escapementArray[c2] * size);
|
|
||||||
currentWidth -= escapementArray[c2] * size;
|
if (currentWidth > width)
|
||||||
do {
|
|
||||||
dst--;
|
|
||||||
} while (IsInsideGlyph(*dst));
|
|
||||||
// see if we went back enough
|
|
||||||
if (currentWidth <= width)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// dst needs to point behind the last glyph we want to use
|
|
||||||
dst++;
|
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
// copy one glyph
|
|
||||||
do {
|
|
||||||
*dst++ = *src++;
|
|
||||||
} while (IsInsideGlyph(*src));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dst;
|
|
||||||
|
if (c < numChars) {
|
||||||
|
// string does not fit into width
|
||||||
|
c = lastFit + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy string to destination
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < c; i++) {
|
||||||
|
// copy one glyph
|
||||||
|
do {
|
||||||
|
*dest++ = *source++;
|
||||||
|
} while (IsInsideGlyph(*source));
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy_from_end
|
|
||||||
static char*
|
static char*
|
||||||
copy_from_end(const char* src, char* dst, uint32 numChars, uint32 length,
|
copy_from_end(const char* src, char* dst, uint32 numChars, uint32 length,
|
||||||
const float* escapementArray, float width, float ellipsisWidth, float size)
|
const float* escapementArray, float width, float ellipsisWidth, float size)
|
||||||
{
|
{
|
||||||
const char* originalStart = src;
|
const char* originalStart = src;
|
||||||
src += length - 1;
|
src += length - 1;
|
||||||
@@ -811,95 +813,91 @@ copy_from_end(const char* src, char* dst, uint32 numChars, uint32 length,
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
write_ellipsis(char* dst)
|
write_ellipsis(char* dst)
|
||||||
{
|
{
|
||||||
strcpy(dst, B_UTF8_ELLIPSIS);
|
strcpy(dst, B_UTF8_ELLIPSIS);
|
||||||
//strcpy(dst, "...");
|
|
||||||
return dst + 3;
|
return dst + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// truncated_string
|
|
||||||
void
|
void
|
||||||
truncate_string(const char* string,
|
truncate_string(const char* string, uint32 mode, float width,
|
||||||
uint32 mode, float width, char* result,
|
char* result, const float* escapementArray, float fontSize,
|
||||||
const float* escapementArray, float fontSize,
|
float ellipsisWidth, int32 length, int32 numChars)
|
||||||
float ellipsisWidth, int32 length, int32 numChars)
|
|
||||||
{
|
{
|
||||||
if (string) {
|
// ToDo: that's actually not correct: the string could be smaller than ellipsisWidth
|
||||||
// skip calculation if we don't even have enough room for that
|
if (string == NULL /*|| width < ellipsisWidth*/) {
|
||||||
if (width >= ellipsisWidth) {
|
// we don't have room for a single glyph
|
||||||
|
strcpy(result, "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// iterate over glyphs and copy source into result string
|
// iterate over glyphs and copy source into result string
|
||||||
// one glyph at a time as long as we have room for the "…" yet
|
// one glyph at a time as long as we have room for the "…" yet
|
||||||
char* dst = result;
|
char* dst = result;
|
||||||
const char* src = string;
|
const char* src = string;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case B_TRUNCATE_BEGINNING: {
|
case B_TRUNCATE_BEGINNING: {
|
||||||
|
dst = copy_from_end(src, dst, numChars, length,
|
||||||
dst = copy_from_end(src, dst, numChars, length,
|
escapementArray, width, ellipsisWidth, fontSize);
|
||||||
escapementArray, width, ellipsisWidth, fontSize);
|
// "dst" points to the position behind the last glyph that
|
||||||
// "dst" points to the position behind the last glyph that
|
// was copied.
|
||||||
// was copied.
|
int32 dist = dst - result;
|
||||||
int32 dist = dst - result;
|
// we didn't terminate yet
|
||||||
// we didn't terminate yet
|
*dst = 0;
|
||||||
*dst = 0;
|
if (dist < length) {
|
||||||
if (dist < length) {
|
// TODO: Is there a smarter way?
|
||||||
// TODO: Is there a smarter way?
|
char* temp = new char[dist + 4];
|
||||||
char* temp = new char[dist + 4];
|
char* t = temp;
|
||||||
char* t = temp;
|
// append "…"
|
||||||
// append "…"
|
t = write_ellipsis(t);
|
||||||
t = write_ellipsis(t);
|
// shuffle arround strings so that "…" is prepended
|
||||||
// shuffle arround strings so that "…" is prepended
|
strcpy(t, result);
|
||||||
strcpy(t, result);
|
strcpy(result, temp);
|
||||||
strcpy(result, temp);
|
delete[] temp;
|
||||||
delete[] temp;
|
|
||||||
/* char t = result[3];
|
/* char t = result[3];
|
||||||
memmove(&result[3], result, dist + 1);
|
memmove(&result[3], result, dist + 1);
|
||||||
write_ellipsis(result);
|
write_ellipsis(result);
|
||||||
result[3] = t;*/
|
result[3] = t;*/
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case B_TRUNCATE_END:
|
|
||||||
|
|
||||||
dst = copy_from_start(src, dst, numChars,
|
|
||||||
escapementArray, width, ellipsisWidth, fontSize);
|
|
||||||
// "dst" points to the position behind the last glyph that
|
|
||||||
// was copied.
|
|
||||||
if (dst - result < length) {
|
|
||||||
// append "…" and terminate with 0
|
|
||||||
write_ellipsis(dst);
|
|
||||||
} else {
|
|
||||||
*dst = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_TRUNCATE_SMART:
|
|
||||||
// TODO: implement, though it was never implemented on R5
|
|
||||||
// FALL THROUGH (at least do something)
|
|
||||||
case B_TRUNCATE_MIDDLE:
|
|
||||||
|
|
||||||
// TODO: VERY BROKEN! (will always insert "…" even if width is large enough)
|
|
||||||
float halfWidth = width / 2.0;
|
|
||||||
|
|
||||||
dst = copy_from_start(src, dst, numChars,
|
|
||||||
escapementArray, halfWidth, ellipsisWidth, fontSize);
|
|
||||||
// insert "…"
|
|
||||||
dst = write_ellipsis(dst);
|
|
||||||
|
|
||||||
dst = copy_from_end(src, dst, numChars, length,
|
|
||||||
escapementArray, halfWidth, 0.0, fontSize);
|
|
||||||
// terminate
|
|
||||||
*dst = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
// we don't have room for a single glyph
|
|
||||||
strcpy(result, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case B_TRUNCATE_END:
|
||||||
|
dst = copy_from_start(src, dst, numChars, escapementArray,
|
||||||
|
width, ellipsisWidth, fontSize);
|
||||||
|
|
||||||
|
// "dst" points to the position behind the last glyph that
|
||||||
|
// was copied.
|
||||||
|
if (dst - result < length) {
|
||||||
|
// append "…" and terminate with 0
|
||||||
|
write_ellipsis(dst);
|
||||||
|
} else {
|
||||||
|
*dst = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_TRUNCATE_SMART:
|
||||||
|
// TODO: implement, though it was never implemented on R5
|
||||||
|
// FALL THROUGH (at least do something)
|
||||||
|
case B_TRUNCATE_MIDDLE:
|
||||||
|
|
||||||
|
// TODO: VERY BROKEN! (will always insert "…" even if width is large enough)
|
||||||
|
float halfWidth = width / 2.0;
|
||||||
|
|
||||||
|
dst = copy_from_start(src, dst, numChars,
|
||||||
|
escapementArray, halfWidth, ellipsisWidth, fontSize);
|
||||||
|
// insert "…"
|
||||||
|
dst = write_ellipsis(dst);
|
||||||
|
|
||||||
|
dst = copy_from_end(src, dst, numChars, length,
|
||||||
|
escapementArray, halfWidth, 0.0, fontSize);
|
||||||
|
// terminate
|
||||||
|
*dst = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user