fixed memory corruption in the stuff I added to moreUTF8. This fixes GetEscapement crashes. The rest of the file needs reviewing as well, but I wanted to commit this ASAP

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13155 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-06-15 17:09:00 +00:00
parent 2d4b179de5
commit cf5ff0c0d0
2 changed files with 50 additions and 20 deletions
+39 -10
View File
@@ -1,22 +1,20 @@
#ifndef __MOREUTF8 #ifndef __MOREUTF8
#define __MOREUTF8 #define __MOREUTF8
#include <stdio.h>
static inline bool static inline bool
IsInsideGlyph(uchar ch) IsInsideGlyph(uchar ch)
{ {
return (ch & 0xC0) == 0x80; return (ch & 0xC0) == 0x80;
// return (ch & 0x80);
} }
static inline uint32 static inline uint32
UTF8NextCharLen(const char *text) UTF8NextCharLenUnsafe(const char *text)
{ {
const char *ptr = text; const char *ptr = text;
if (ptr == NULL || *ptr == 0)
return 0;
do { do {
ptr++; ptr++;
} while (IsInsideGlyph(*ptr)); } while (IsInsideGlyph(*ptr));
@@ -24,6 +22,15 @@ UTF8NextCharLen(const char *text)
return ptr - text; return ptr - text;
} }
static inline uint32
UTF8NextCharLen(const char *text)
{
if (text == NULL || *text == 0)
return 0;
return UTF8NextCharLenUnsafe(text);
}
static inline uint32 static inline uint32
UTF8PreviousCharLen(const char *text, const char *limit) UTF8PreviousCharLen(const char *text, const char *limit)
{ {
@@ -41,18 +48,40 @@ UTF8PreviousCharLen(const char *text, const char *limit)
return text - ptr; return text - ptr;
} }
// TODO: use this function in other places of this file...
static inline uint32
count_utf8_bytes(uchar ch)
{
// the number of high bits set until the first
// unset bit determine the count of bytes used for
// this glyph from this byte on
uchar bit = 1 << 7;
uint32 count = 1;
if (ch & bit) {
bit = bit >> 1;
while (ch & bit) {
count++;
bit = bit >> 1;
}
}
return count;
}
static inline uint32 static inline uint32
UTF8CountBytes(const char *text, uint32 numChars) UTF8CountBytes(const char *text, uint32 numChars)
{ {
if (text) {
// iterate over numChars glyphs incrementing ptr by the
// number of bytes for each glyph, which is encoded in
// the first byte of any glyph.
const char *ptr = text; const char *ptr = text;
while (numChars--) {
while (numChars) { ptr += count_utf8_bytes(*ptr);
ptr += UTF8NextCharLen(ptr);
numChars--;
} }
return ptr - text; return ptr - text;
} }
return 0;
}
static inline uint32 static inline uint32
UTF8CountChars(const char *text, int32 numBytes) UTF8CountChars(const char *text, int32 numBytes)
+6 -5
View File
@@ -294,7 +294,7 @@ ServerFont::GetGlyphShapes(const char charArray[], int32 numChars) const
if (!face) if (!face)
return NULL; return NULL;
FT_Set_Char_Size(face, 0, int32(fSize) * 64, 72, 72); FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
Angle rotation(fRotation); Angle rotation(fRotation);
Angle shear(fShear); Angle shear(fShear);
@@ -344,7 +344,7 @@ ServerFont::GetEscapements(const char charArray[], int32 numChars,
if (!face) if (!face)
return NULL; return NULL;
FT_Set_Char_Size(face, 0, int32(fSize) * 64, 72, 72); FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
Angle rotation(fRotation); Angle rotation(fRotation);
Angle shear(fShear); Angle shear(fShear);
@@ -408,7 +408,7 @@ ServerFont::GetEscapements(const char charArray[], int32 numChars,
if (!face) if (!face)
return false; return false;
FT_Set_Char_Size(face, 0, int32(fSize) * 64, 72, 72); FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
// UTF8 handling...this can probably be smarter // UTF8 handling...this can probably be smarter
// Here is what I do in the AGGTextRenderer to handle UTF8... // Here is what I do in the AGGTextRenderer to handle UTF8...
@@ -428,15 +428,16 @@ ServerFont::GetEscapements(const char charArray[], int32 numChars,
uint16* glyphIndex = (uint16*)convertedBuffer; uint16* glyphIndex = (uint16*)convertedBuffer;
// just to be sure // just to be sure
numChars = convertedLength / sizeof(uint16); numChars = min_c((uint32)numChars, convertedLength / sizeof(uint16));
for (int i = 0; i < numChars; i++) { for (int i = 0; i < numChars; i++) {
FT_Load_Char(face, glyphIndex[i], FT_LOAD_NO_BITMAP); FT_Load_Char(face, glyphIndex[i], FT_LOAD_NO_BITMAP);
// widthArray[i] = float(face->glyph->metrics.width / 64) / fSize; if (face->glyph) {
widthArray[i] = ((float)face->glyph->metrics.horiAdvance / 64.0) / fSize; widthArray[i] = ((float)face->glyph->metrics.horiAdvance / 64.0) / fSize;
widthArray[i] += is_white_space(glyphIndex[i]) ? delta.space : delta.nonspace; widthArray[i] += is_white_space(glyphIndex[i]) ? delta.space : delta.nonspace;
} }
} }
}
delete[] convertedBuffer; delete[] convertedBuffer;
return ret >= B_OK; return ret >= B_OK;