mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Fix issue with caret position in text boxes caused by a bad hash function. Fletcher is 2-bytes-at-a-time and thus very inappropriate for short strings.
This commit is contained in:
parent
2c8fb0fbd1
commit
d1d1e1f742
5 changed files with 13 additions and 41 deletions
|
@ -46,7 +46,7 @@ bool TextDrawerAndroid::IsReady() const {
|
|||
uint32_t TextDrawerAndroid::SetFont(const char *fontName, int size, int flags) {
|
||||
// We will only use the default font but just for consistency let's still involve
|
||||
// the font name.
|
||||
uint32_t fontHash = hash::Fletcher((const uint8_t *)fontName, strlen(fontName));
|
||||
uint32_t fontHash = hash::Adler32((const uint8_t *)fontName, strlen(fontName));
|
||||
fontHash ^= size;
|
||||
fontHash ^= flags << 10;
|
||||
|
||||
|
@ -79,7 +79,7 @@ std::string TextDrawerAndroid::NormalizeString(std::string str) {
|
|||
}
|
||||
|
||||
void TextDrawerAndroid::MeasureString(const char *str, size_t len, float *w, float *h) {
|
||||
uint32_t stringHash = hash::Fletcher((const uint8_t *)str, len);
|
||||
uint32_t stringHash = hash::Adler32((const uint8_t *)str, len);
|
||||
uint32_t entryHash = stringHash ^ fontHash_;
|
||||
|
||||
TextMeasureEntry *entry;
|
||||
|
@ -129,7 +129,7 @@ void TextDrawerAndroid::MeasureStringRect(const char *str, size_t len, const Bou
|
|||
float total_w = 0.0f;
|
||||
float total_h = 0.0f;
|
||||
for (size_t i = 0; i < lines.size(); i++) {
|
||||
uint32_t stringHash = hash::Fletcher((const uint8_t *)&lines[i][0], lines[i].length());
|
||||
uint32_t stringHash = hash::Adler32((const uint8_t *)&lines[i][0], lines[i].length());
|
||||
uint32_t entryHash = stringHash ^ fontHash_;
|
||||
|
||||
TextMeasureEntry *entry;
|
||||
|
@ -168,7 +168,7 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x,
|
|||
int result = javaVM->GetEnv((void **)&env, JNI_VERSION_1_6);
|
||||
assert(env == env_);
|
||||
|
||||
uint32_t stringHash = hash::Fletcher((const uint8_t *)text.data(), text.size());
|
||||
uint32_t stringHash = hash::Adler32((const uint8_t *)text.data(), text.size());
|
||||
uint32_t entryHash = stringHash ^ fontHash_ ^ (align << 24);
|
||||
|
||||
target.Flush(true);
|
||||
|
|
|
@ -24,7 +24,7 @@ TextDrawerQt::~TextDrawerQt() {
|
|||
|
||||
uint32_t TextDrawerQt::SetFont(const char *fontName, int size, int flags) {
|
||||
// We will only use the default font
|
||||
uint32_t fontHash = 0; //hash::Fletcher((const uint8_t *)fontName, strlen(fontName));
|
||||
uint32_t fontHash = 0; //hash::Adler32((const uint8_t *)fontName, strlen(fontName));
|
||||
fontHash ^= size;
|
||||
fontHash ^= flags << 10;
|
||||
|
||||
|
@ -72,7 +72,7 @@ void TextDrawerQt::DrawString(DrawBuffer &target, const char *str, float x, floa
|
|||
if (!strlen(str))
|
||||
return;
|
||||
|
||||
uint32_t stringHash = hash::Fletcher((const uint8_t *)str, strlen(str));
|
||||
uint32_t stringHash = hash::Adler32((const uint8_t *)str, strlen(str));
|
||||
uint32_t entryHash = stringHash ^ fontHash_ ^ (align << 24);
|
||||
|
||||
target.Flush(true);
|
||||
|
|
|
@ -83,7 +83,7 @@ TextDrawerWin32::~TextDrawerWin32() {
|
|||
}
|
||||
|
||||
uint32_t TextDrawerWin32::SetFont(const char *fontName, int size, int flags) {
|
||||
uint32_t fontHash = fontName ? hash::Fletcher((const uint8_t *)fontName, strlen(fontName)) : 0;
|
||||
uint32_t fontHash = fontName ? hash::Adler32((const uint8_t *)fontName, strlen(fontName)) : 0;
|
||||
fontHash ^= size;
|
||||
fontHash ^= flags << 10;
|
||||
|
||||
|
@ -119,7 +119,7 @@ void TextDrawerWin32::SetFont(uint32_t fontHandle) {
|
|||
}
|
||||
|
||||
void TextDrawerWin32::MeasureString(const char *str, size_t len, float *w, float *h) {
|
||||
uint32_t stringHash = hash::Fletcher((const uint8_t *)str, len);
|
||||
uint32_t stringHash = hash::Adler32((const uint8_t *)str, len);
|
||||
uint32_t entryHash = stringHash ^ fontHash_;
|
||||
|
||||
TextMeasureEntry *entry;
|
||||
|
@ -164,7 +164,7 @@ void TextDrawerWin32::MeasureStringRect(const char *str, size_t len, const Bound
|
|||
float total_w = 0.0f;
|
||||
float total_h = 0.0f;
|
||||
for (size_t i = 0; i < lines.size(); i++) {
|
||||
uint32_t stringHash = hash::Fletcher((const uint8_t *)&lines[i][0], lines[i].length());
|
||||
uint32_t stringHash = hash::Adler32((const uint8_t *)&lines[i][0], lines[i].length());
|
||||
uint32_t entryHash = stringHash ^ fontHash_;
|
||||
|
||||
TextMeasureEntry *entry;
|
||||
|
@ -197,7 +197,7 @@ void TextDrawerWin32::DrawString(DrawBuffer &target, const char *str, float x, f
|
|||
if (!strlen(str))
|
||||
return;
|
||||
|
||||
uint32_t stringHash = hash::Fletcher((const uint8_t *)str, strlen(str));
|
||||
uint32_t stringHash = hash::Adler32((const uint8_t *)str, strlen(str));
|
||||
uint32_t entryHash = stringHash ^ fontHash_ ^ (align << 24);
|
||||
|
||||
target.Flush(true);
|
||||
|
|
|
@ -3,35 +3,7 @@
|
|||
|
||||
namespace hash {
|
||||
|
||||
// uint32_t
|
||||
// WARNING - may read one more byte! Fine if the input is a null-terminated string.
|
||||
// Implementation from Wikipedia.
|
||||
uint32_t Fletcher(const uint8_t *data_uint8, size_t length) {
|
||||
const uint16_t *data = (const uint16_t *)data_uint8;
|
||||
size_t len = (length + 1) / 2;
|
||||
uint32_t sum1 = 0xffff, sum2 = 0xffff;
|
||||
|
||||
while (len) {
|
||||
size_t tlen = len > 360 ? 360 : len;
|
||||
len -= tlen;
|
||||
|
||||
do {
|
||||
sum1 += *data++;
|
||||
sum2 += sum1;
|
||||
} while (--tlen);
|
||||
|
||||
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
|
||||
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
|
||||
}
|
||||
|
||||
/* Second reduction step to reduce sums to 16 bits */
|
||||
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
|
||||
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
|
||||
return sum2 << 16 | sum1;
|
||||
}
|
||||
|
||||
// Implementation from Wikipedia
|
||||
// Slightly slower than Fletcher above, but slighly more reliable.
|
||||
#define MOD_ADLER 65521
|
||||
// data: Pointer to the data to be summed; len is in bytes
|
||||
uint32_t Adler32(const uint8_t *data, size_t len) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#ifndef _UTIL_HASH_HASH_H
|
||||
#define _UTIL_HASH_HASH_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
namespace hash {
|
||||
|
||||
uint32_t Fletcher(const uint8_t *data_u8, size_t length); // FAST. Length & 1 == 0.
|
||||
uint32_t Adler32(const uint8_t *data, size_t len); // Fairly accurate, slightly slower
|
||||
// Fairly decent function for hashing strings.
|
||||
uint32_t Adler32(const uint8_t *data, size_t len);
|
||||
|
||||
} // namespace hash
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue