allow measuring just text width and font height in drawer2D

This commit is contained in:
UnknownShadow200 2018-12-13 08:20:12 +11:00
parent c44fb9948c
commit b297fc44e4
7 changed files with 86 additions and 73 deletions

View File

@ -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);
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; }
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
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) {

View File

@ -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);

View File

@ -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);