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:
Axel Dörfler
2005-06-08 14:38:29 +00:00
parent e60b1ff1d8
commit 8b0b0568fd
+105 -107
View File
@@ -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;
} }
} }