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:
@@ -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,17 +48,39 @@ 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)
|
||||||
{
|
{
|
||||||
const char *ptr = text;
|
if (text) {
|
||||||
|
// iterate over numChars glyphs incrementing ptr by the
|
||||||
while (numChars) {
|
// number of bytes for each glyph, which is encoded in
|
||||||
ptr += UTF8NextCharLen(ptr);
|
// the first byte of any glyph.
|
||||||
numChars--;
|
const char *ptr = text;
|
||||||
|
while (numChars--) {
|
||||||
|
ptr += count_utf8_bytes(*ptr);
|
||||||
|
}
|
||||||
|
return ptr - text;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
return ptr - text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32
|
static inline uint32
|
||||||
|
|||||||
@@ -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,13 +428,14 @@ 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;
|
||||||
|
|||||||
Reference in New Issue
Block a user