mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 18:15:28 -04:00
allow measuring just text width and font height in drawer2D
This commit is contained in:
parent
c44fb9948c
commit
b297fc44e4
@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user