From b297fc44e48eab27f46e4130fe754b3c910df03e Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 13 Dec 2018 08:20:12 +1100 Subject: [PATCH] allow measuring just text width and font height in drawer2D --- src/Drawer2D.c | 94 ++++++++++++++++++++++++++++---------------------- src/Drawer2D.h | 1 + src/LWidgets.c | 12 +++---- src/Launcher.c | 2 +- src/Platform.c | 32 ++++++++--------- src/Platform.h | 8 +++-- src/Widgets.c | 10 +++--- 7 files changed, 86 insertions(+), 73 deletions(-) diff --git a/src/Drawer2D.c b/src/Drawer2D.c index 6f10202ea..0e4478351 100644 --- a/src/Drawer2D.c +++ b/src/Drawer2D.c @@ -281,13 +281,6 @@ void Drawer2D_Clear(Bitmap* bmp, BitmapCol col, int x, int y, int width, int hei } -int Drawer2D_FontHeight(const FontDesc* font, bool useShadow) { - const static String text = String_FromConst("I"); - struct DrawTextArgs args; - DrawTextArgs_Make(&args, &text, font, useShadow); - return Drawer2D_MeasureText(&args).Height; -} - void Drawer2D_MakeTextTexture(struct Texture* tex, struct DrawTextArgs* args, int X, int Y) { static struct Texture empty = { GFX_NULL, Tex_Rect(0,0, 0,0), Tex_UV(0,0, 1,1) }; Size2D size = Drawer2D_MeasureText(args); @@ -511,16 +504,14 @@ static void Drawer2D_DrawBitmapText(Bitmap* bmp, struct DrawTextArgs* args, int Drawer2D_DrawCore(bmp, args, x, y, false); } -static Size2D Drawer2D_MeasureBitmapText(struct DrawTextArgs* args) { +static int Drawer2D_MeasureBitmapWidth(struct DrawTextArgs* args) { int i, point = args->Font.Size; - int offset, xPadding; - Size2D total; + int xPadding, width; String text; /* adjust coords to make drawn text match GDI fonts */ - xPadding = Drawer2D_XPadding(point); - total.Width = 0; - total.Height = Drawer2D_AdjHeight(point); + xPadding = Drawer2D_XPadding(point); + width = 0; text = args->Text; for (i = 0; i < text.length; i++) { @@ -528,26 +519,22 @@ static Size2D Drawer2D_MeasureBitmapText(struct DrawTextArgs* args) { if (c == '&' && Drawer2D_ValidColCodeAt(&text, i + 1)) { i++; continue; /* skip over the colour code */ } - total.Width += Drawer2D_Width(point, c) + xPadding; + width += Drawer2D_Width(point, c) + xPadding; } /* TODO: this should be uncommented */ /* Remove padding at end */ - /*if (total.Width > 0) total.Width -= xPadding;*/ + /*if (width) width -= xPadding; */ - if (args->UseShadow) { - offset = Drawer2D_ShadowOffset(point); - total.Width += offset; total.Height += offset; - } - return total; + if (args->UseShadow) { width += Drawer2D_ShadowOffset(point); } + return width; } void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y) { BitmapCol col, backCol, black = BITMAPCOL_CONST(0, 0, 0, 255); - Size2D partSize; String value = args->Text; char colCode, nextCol = 'f'; - int i; + int i, partWidth; if (Drawer2D_IsEmptyText(&args->Text)) return; if (Drawer2D_BitmappedText) { Drawer2D_DrawBitmapText(bmp, args, x, y); return; } @@ -563,45 +550,68 @@ void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y) { Platform_TextDraw(args, bmp, x + DRAWER2D_OFFSET, y + DRAWER2D_OFFSET, backCol); } - partSize = Platform_TextDraw(args, bmp, x, y, col); - x += partSize.Width; + partWidth = Platform_TextDraw(args, bmp, x, y, col); + x += partWidth; } args->Text = value; } -Size2D Drawer2D_MeasureText(struct DrawTextArgs* args) { - Size2D size, partSize; +int Drawer2D_TextWidth(struct DrawTextArgs* args) { String value = args->Text; char nextCol = 'f'; - int i; + int i, width; - size.Width = 0; size.Height = 0; - if (Drawer2D_IsEmptyText(&args->Text)) return size; - if (Drawer2D_BitmappedText) return Drawer2D_MeasureBitmapText(args); + if (Drawer2D_IsEmptyText(&args->Text)) return 0; + if (Drawer2D_BitmappedText) return Drawer2D_MeasureBitmapWidth(args); + width = 0; for (i = 0; i < value.length; ) { i = Drawer2D_NextPart(i, &value, &args->Text, &nextCol); - if (!args->Text.length) continue; - partSize = Platform_TextMeasure(args); - size.Width += partSize.Width; - size.Height = max(size.Height, partSize.Height); + if (!args->Text.length) continue; + width += Platform_TextWidth(args); } /* TODO: Is this font shadow offset right? */ - if (args->UseShadow) { size.Width += DRAWER2D_OFFSET; size.Height += DRAWER2D_OFFSET; } + if (args->UseShadow) { width += DRAWER2D_OFFSET; } + args->Text = value; + return width; +} + +int Drawer2D_FontHeight(const FontDesc* font, bool useShadow) { + int height, point; + if (Drawer2D_BitmappedText) { + point = font->Size; + /* adjust coords to make drawn text match GDI fonts */ + height = Drawer2D_AdjHeight(point); + + if (useShadow) { height += Drawer2D_ShadowOffset(point); } + } else { + height = Platform_FontHeight(font); + /* TODO: Is this font shadow offset right? */ + if (useShadow) { height += DRAWER2D_OFFSET; } + } + return height; +} + +Size2D Drawer2D_MeasureText(struct DrawTextArgs* args) { + Size2D size; + size.Width = Drawer2D_TextWidth(args); + size.Height = Drawer2D_FontHeight(&args->Font, args->UseShadow); + + if (!size.Width) size.Height = 0; return size; } void Drawer2D_DrawClippedText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y, int maxWidth) { String str; char strBuffer[512]; struct DrawTextArgs part; - int i; + int i, width; - Size2D size = Drawer2D_MeasureText(args); + width = Drawer2D_TextWidth(args); /* No clipping needed */ - if (size.Width <= maxWidth) { Drawer2D_DrawText(bmp, args, x, y); return; } + if (width <= maxWidth) { Drawer2D_DrawText(bmp, args, x, y); return; } String_InitArray(str, strBuffer); String_Copy(&str, &args->Text); @@ -614,14 +624,14 @@ void Drawer2D_DrawClippedText(Bitmap* bmp, struct DrawTextArgs* args, int x, int /* skip over trailing spaces */ if (str.buffer[i - 1] == ' ') continue; part.Text = String_UNSAFE_Substring(&str, 0, i + 2); - size = Drawer2D_MeasureText(&part); - if (size.Width <= maxWidth) { Drawer2D_DrawText(bmp, &part, x, y); return; } + width = Drawer2D_TextWidth(&part); + if (width <= maxWidth) { Drawer2D_DrawText(bmp, &part, x, y); return; } /* If down to <= 2 chars, try omit trailing .. */ if (i > 2) continue; part.Text = String_UNSAFE_Substring(&str, 0, i); - size = Drawer2D_MeasureText(&part); - if (size.Width <= maxWidth) { Drawer2D_DrawText(bmp, &part, x, y); return; } + width = Drawer2D_TextWidth(&part); + if (width <= maxWidth) { Drawer2D_DrawText(bmp, &part, x, y); return; } } } diff --git a/src/Drawer2D.h b/src/Drawer2D.h index 35ac2da4c..2995aabe9 100644 --- a/src/Drawer2D.h +++ b/src/Drawer2D.h @@ -57,6 +57,7 @@ void Drawer2D_Clear(Bitmap* bmp, BitmapCol col, int x, int y, int width, int hei void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, BitmapCol col); void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y); +int Drawer2D_TextWidth(struct DrawTextArgs* args); Size2D Drawer2D_MeasureText(struct DrawTextArgs* args); void Drawer2D_DrawClippedText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y, int maxWidth); int Drawer2D_FontHeight(const FontDesc* font, bool useShadow); diff --git a/src/LWidgets.c b/src/LWidgets.c index 3951fec32..4649de454 100644 --- a/src/LWidgets.c +++ b/src/LWidgets.c @@ -342,14 +342,14 @@ Rect2D LInput_MeasureCaret(struct LInput* w) { r.Y = w->Y + w->Height - 5; r.Height = 2; if (w->CaretPos == -1) { - r.X += Drawer2D_MeasureText(&args).Width; + r.X += Drawer2D_TextWidth(&args); r.Width = 10; } else { args.Text = String_UNSAFE_Substring(&text, 0, w->CaretPos); - r.X += Drawer2D_MeasureText(&args).Width; + r.X += Drawer2D_TextWidth(&args); args.Text = String_UNSAFE_Substring(&text, w->CaretPos, 1); - r.Width = Drawer2D_MeasureText(&args).Width; + r.Width = Drawer2D_TextWidth(&args); } return r; } @@ -374,16 +374,16 @@ void LInput_SetCaretToCursor(struct LInput* w, int x, int y) { x -= w->X; y -= w->Y; DrawTextArgs_Make(&args, &text, &w->Font, true); - if (x >= Drawer2D_MeasureText(&args).Width) { + if (x >= Drawer2D_TextWidth(&args)) { w->CaretPos = -1; return; } for (i = 0; i < text.length; i++) { args.Text = String_UNSAFE_Substring(&text, 0, i); - charX = Drawer2D_MeasureText(&args).Width; + charX = Drawer2D_TextWidth(&args); args.Text = String_UNSAFE_Substring(&text, i, 1); - charWidth = Drawer2D_MeasureText(&args).Width; + charWidth = Drawer2D_TextWidth(&args); if (x >= charX && x < charX + charWidth) { w->CaretPos = i; return; } diff --git a/src/Launcher.c b/src/Launcher.c index 3eaf7c725..7cf599551 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -480,7 +480,7 @@ void Launcher_ResetPixels(void) { Drawer2D_BitmappedText = (useBitmappedFont || Launcher_ClassicBackground) && fontBmp.Scan0; DrawTextArgs_Make(&args, &title_fore, &logoFont, false); - x = Game_Width / 2 - Drawer2D_MeasureText(&args).Width / 2; + x = Game_Width / 2 - Drawer2D_TextWidth(&args) / 2; args.Text = title_back; Drawer2D_DrawText(&Launcher_Framebuffer, &args, x + 4, 4); diff --git a/src/Platform.c b/src/Platform.c index 23c58cece..0365c5558 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -1036,23 +1036,24 @@ static void Font_DirCallback(const String* path, void* obj) { } #define TEXT_CEIL(x) (((x) + 63) >> 6) -Size2D Platform_TextMeasure(struct DrawTextArgs* args) { +int Platform_TextWidth(struct DrawTextArgs* args) { FT_Face face = args->Font.Handle; String text = args->Text; - Size2D s = { 0, 0 }; + int i, width = 0; Codepoint cp; - int i; for (i = 0; i < text.length; i++) { cp = Convert_CP437ToUnicode(text.buffer[i]); FT_Load_Char(face, cp, 0); /* TODO: Check error */ - s.Width += face->glyph->advance.x; + width += face->glyph->advance.x; } + return TEXT_CEIL(width); +} - s.Height = face->size->metrics.height; - s.Width = TEXT_CEIL(s.Width); - s.Height = TEXT_CEIL(s.Height); - return s; +int Platform_FontHeight(const FontDesc* font) { + FT_Face face = font->Handle; + int height = face->size->metrics.height; + return TEXT_CEIL(height); } static void Platform_GrayscaleGlyph(FT_Bitmap* img, Bitmap* bmp, int x, int y, BitmapCol col) { @@ -1103,25 +1104,24 @@ static void Platform_BlackWhiteGlyph(FT_Bitmap* img, Bitmap* bmp, int x, int y, } } -Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col) { +int Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col) { FT_Face face = args->Font.Handle; - String text = args->Text; - Size2D s = { 0, 0 }; - int descender, begX = x; + String text = args->Text; + int descender, height, begX = x; /* glyph state */ FT_Bitmap* img; int i, offset; Codepoint cp; - s.Height = TEXT_CEIL(face->size->metrics.height); + height = TEXT_CEIL(face->size->metrics.height); descender = TEXT_CEIL(face->size->metrics.descender); for (i = 0; i < text.length; i++) { cp = Convert_CP437ToUnicode(text.buffer[i]); FT_Load_Char(face, cp, FT_LOAD_RENDER); /* TODO: Check error */ - offset = (s.Height + descender) - face->glyph->bitmap_top; + offset = (height + descender) - face->glyph->bitmap_top; x += face->glyph->bitmap_left; y += offset; img = &face->glyph->bitmap; @@ -1140,11 +1140,11 @@ Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, B int ul_thick = FT_MulFix(face->underline_thickness, face->size->metrics.y_scale); int ulHeight = TEXT_CEIL(ul_thick); - int ulY = s.Height + TEXT_CEIL(ul_pos); + int ulY = height + TEXT_CEIL(ul_pos); Drawer2D_Underline(bmp, begX, ulY + y, x - begX, ulHeight, col); } - s.Width = x - begX; return s; + return x - begX; } static void* FT_AllocWrapper(FT_Memory memory, long size) { diff --git a/src/Platform.h b/src/Platform.h index 2f67e1f0c..963efd4c4 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -181,10 +181,12 @@ CC_EXPORT void Font_GetNames(StringsBuffer* buffer); CC_EXPORT void Font_Make(FontDesc* desc, const String* fontName, int size, int style); /* Frees an allocated font. */ CC_EXPORT void Font_Free(FontDesc* desc); -/* Measures dimensions of the given text, if it was drawn with the given font. */ -CC_EXPORT Size2D Platform_TextMeasure(struct DrawTextArgs* args); +/* Measures width of the given text when drawn with the given font. */ +int Platform_TextWidth(struct DrawTextArgs* args); +/* Measures height of any text when drawn with the given font. */ +int Platform_FontHeight(const FontDesc* font); /* Draws the given text with the given font onto the given bitmap. */ -CC_EXPORT Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col); +int Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col); /* Allocates a new socket. */ void Socket_Create(SocketHandle* socket); diff --git a/src/Widgets.c b/src/Widgets.c index a39fe9b86..7dca63933 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -955,13 +955,13 @@ static void InputWidget_UpdateCaret(struct InputWidget* w) { InputWidget_FormatLine(w, w->CaretY, &line); args.Text = String_UNSAFE_Substring(&line, 0, w->CaretX); - lineWidth = Drawer2D_MeasureText(&args).Width; + lineWidth = Drawer2D_TextWidth(&args); if (w->CaretY == 0) lineWidth += w->PrefixWidth; if (w->CaretX < line.length) { args.Text = String_UNSAFE_Substring(&line, w->CaretX, 1); args.UseShadow = true; - w->CaretTex.Width = Drawer2D_MeasureText(&args).Width; + w->CaretTex.Width = Drawer2D_TextWidth(&args); } } @@ -1260,11 +1260,11 @@ static bool InputWidget_MouseDown(void* widget, int x, int y, MouseButton button for (cx = 0; cx < line.length; cx++) { args.Text = String_UNSAFE_Substring(&line, 0, cx); - charX = Drawer2D_MeasureText(&args).Width; + charX = Drawer2D_TextWidth(&args); if (cy == 0) charX += w->PrefixWidth; args.Text = String_UNSAFE_Substring(&line, cx, 1); - charWidth = Drawer2D_MeasureText(&args).Width; + charWidth = Drawer2D_TextWidth(&args); if (Gui_Contains(charX, cy * charHeight, charWidth, charHeight, x, y)) { w->CaretPos = offset + cx; @@ -2489,7 +2489,7 @@ static bool TextGroupWidget_GetUrl(struct TextGroupWidget* w, String* text, int args.Text = String_UNSAFE_Substring(&line, bit.LineBeg, bit.LineLen); args.Font = (bit.Len & TEXTGROUPWIDGET_URL) ? w->UnderlineFont : w->Font; - width = Drawer2D_MeasureText(&args).Width; + width = Drawer2D_TextWidth(&args); if ((bit.Len & TEXTGROUPWIDGET_URL) && mouseX >= x && mouseX < x + width) { bit.Len &= TEXTGROUPWIDGET_PACKED_LEN; url = String_Init(&chars[bit.Beg], bit.Len, bit.Len);