summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2016-03-22 17:51:31 +0000
committerVincent Sanders <vince@kyllikki.org>2016-03-22 17:51:31 +0000
commitafc1d2c3c7631ea50cf94791e9cb20b8ea1f2051 (patch)
tree4f8a17f20f53755ee44b415e57fe7f52e3ef557e
parent719dc37b22bd36f45a30516e17f21ce46305db84 (diff)
downloadnetsurf-afc1d2c3c7631ea50cf94791e9cb20b8ea1f2051.tar.gz
netsurf-afc1d2c3c7631ea50cf94791e9cb20b8ea1f2051.tar.bz2
fix broken windows frontend font handling
-rw-r--r--windows/font.c160
1 files changed, 109 insertions, 51 deletions
diff --git a/windows/font.c b/windows/font.c
index 427bcb166..9358d1a85 100644
--- a/windows/font.c
+++ b/windows/font.c
@@ -38,14 +38,14 @@
HWND font_hwnd;
nserror utf8_to_font_encoding(const struct font_desc* font,
- const char *string,
+ const char *string,
size_t len,
char **result)
{
return utf8_to_enc(string, font->encoding, len, result);
}
-static nserror utf8_to_local_encoding(const char *string,
+static nserror utf8_to_local_encoding(const char *string,
size_t len,
char **result)
{
@@ -131,31 +131,48 @@ HFONT get_font(const plot_font_style_t *style)
return font;
}
-static bool nsfont_width(const plot_font_style_t *style,
- const char *string, size_t length,
- int *width)
+/**
+ * Measure the width of a string.
+ *
+ * \param[in] style plot style for this text
+ * \param[in] string UTF-8 string to measure
+ * \param[in] length length of string, in bytes
+ * \param[out] width updated to width of string[0..length)
+ * \return true on success and width updated else false
+ */
+static bool
+nsfont_width(const plot_font_style_t *style,
+ const char *string,
+ size_t length,
+ int *width)
{
- HDC hdc = GetDC(NULL);
- HFONT font = get_font(style);
- HFONT fontbak = SelectObject(hdc, font);
+ HDC hdc;
+ HFONT font;
+ HFONT fontbak;
SIZE s;
- if (length < 8192) { /* win 95/98/ME */
+ bool ret = true;
+
+ if (length == 0) {
+ *width = 0;
+ } else {
+ hdc = GetDC(NULL);
+ font = get_font(style);
+ fontbak = SelectObject(hdc, font);
+
/* may well need to convert utf-8 to lpctstr */
- GetTextExtentPoint32(hdc, string,
- utf8_bounded_length(string, length), &s);
- *width = s.cx;
+ if (GetTextExtentPoint32A(hdc, string, length, &s) != 0) {
+ *width = s.cx;
+ } else {
+ ret = false;
+ }
font = SelectObject(hdc, fontbak);
DeleteObject(font);
ReleaseDC(NULL, hdc);
- return true;
}
- LOG("nsfont_width failed");
- font = SelectObject(hdc, fontbak);
- DeleteObject(font);
- ReleaseDC(NULL, hdc);
- return false;
+ return ret;
}
+
/**
* Find the position in a string where an x coordinate falls.
*
@@ -168,25 +185,42 @@ static bool nsfont_width(const plot_font_style_t *style,
* \param actual_x updated to x coordinate of character closest to x
* \return true on success, false on error and error reported
*/
-
-static bool nsfont_position_in_string(const plot_font_style_t *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+static bool
+nsfont_position_in_string(const plot_font_style_t *style,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
{
- HDC hdc = GetDC(NULL);
- HFONT font = get_font(style);
- HFONT fontbak = SelectObject(hdc, font);
+ HDC hdc;
+ HFONT font;
+ HFONT fontbak;
SIZE s;
int offset;
- GetTextExtentExPoint(hdc, string, length, x, &offset, NULL, &s);
- *char_offset = (size_t)offset;
- nsfont_width(style, string, *char_offset, actual_x);
-
- font = SelectObject(hdc, fontbak);
- DeleteObject(font);
- ReleaseDC(NULL, hdc);
-
- return true;
+ bool ret = true;
+
+ if ((length == 0) || (x < 1)) {
+ *char_offset = 0;
+ *actual_x = 0;
+ } else {
+ hdc = GetDC(NULL);
+ font = get_font(style);
+ fontbak = SelectObject(hdc, font);
+
+ if ((GetTextExtentExPointA(hdc, string, length, x, &offset, NULL,&s) != 0) &&
+ (GetTextExtentPoint32A(hdc, string, offset, &s) != 0)) {
+ *char_offset = (size_t)offset;
+ *actual_x = s.cx;
+ } else {
+ ret = false;
+ }
+ font = SelectObject(hdc, fontbak);
+ DeleteObject(font);
+ ReleaseDC(NULL, hdc);
+ }
+
+ return ret;
}
@@ -206,28 +240,52 @@ static bool nsfont_position_in_string(const plot_font_style_t *style,
* string[char_offset] == ' ' ||
* char_offset == length]
*/
-
-static bool nsfont_split(const plot_font_style_t *style,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+static bool
+nsfont_split(const plot_font_style_t *style,
+ const char *string,
+ size_t length,
+ int x,
+ size_t *char_offset,
+ int *actual_x)
{
int c_off;
- nsfont_position_in_string(style, string, length, x, char_offset,
- actual_x);
- c_off = *char_offset;
- if (*char_offset == length) {
- return true;
- }
- while ((string[*char_offset] != ' ') && (*char_offset > 0))
- (*char_offset)--;
- if (*char_offset == 0) {
- *char_offset = c_off;
- while (*char_offset < length && string[*char_offset] != ' ') {
- (*char_offset)++;
+ bool ret = false;
+
+ if (nsfont_position_in_string(style,
+ string,
+ length,
+ x,
+ char_offset,
+ actual_x)) {
+ c_off = *char_offset;
+ if (*char_offset == length) {
+ ret = true;
+ } else {
+ while ((string[*char_offset] != ' ') &&
+ (*char_offset > 0)) {
+ (*char_offset)--;
+ }
+
+ if (*char_offset == 0) {
+ *char_offset = c_off;
+ while ((*char_offset < length) &&
+ (string[*char_offset] != ' ')) {
+ (*char_offset)++;
+ }
+ }
+
+ ret = nsfont_width(style,
+ string,
+ *char_offset,
+ actual_x);
}
}
- return nsfont_width(style, string, *char_offset, actual_x);
+/*
+ LOG("ret %d Split %u chars at %ipx: Split at char %i (%ipx) - %.*s",
+ ret, length, x, *char_offset, *actual_x, *char_offset, string);
+*/
+ return ret;
}
const struct font_functions nsfont = {