mirror of
https://github.com/zetaPRIME/libstarlight.git
synced 2025-06-26 05:32:46 +00:00
new text measurement stuffs in working order!
This commit is contained in:
parent
bca1adc6eb
commit
5960a56f60
@ -171,6 +171,6 @@ void OSK::DrawPreview(DrawLayerProxy& layer) {
|
|||||||
void OSK::OnPreviewTap(DrawLayerProxy& layer) {
|
void OSK::OnPreviewTap(DrawLayerProxy& layer) {
|
||||||
Vector2 tpos = InputManager::TouchPos() - layer.ScreenRect().pos;
|
Vector2 tpos = InputManager::TouchPos() - layer.ScreenRect().pos;
|
||||||
auto& tc = PreviewTC();
|
auto& tc = PreviewTC();
|
||||||
handler->SetCursor(tc.font->GetCursorFromPoint(layer.rect, handler->GetPreviewText(), tpos + layer.rect.pos));
|
handler->SetCursor(tc.font->GetCursorFromPoint(layer.rect, handler->GetPreviewText(), tpos));
|
||||||
preview->Refresh();
|
preview->Refresh();
|
||||||
}
|
}
|
||||||
|
@ -87,111 +87,73 @@ float BitmapFont::DrawText(const Vector2& penStart, std::string& msg, float scal
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector2 BitmapFont::MeasureTo(std::string& msg, bool total, unsigned int end, float maxWidth) {
|
Vector2 BitmapFont::MeasureTo(std::string& msg, bool total, unsigned int end, float maxWidth) {
|
||||||
auto len = msg.length();
|
if (total) {
|
||||||
if (end > len) end = len;
|
Vector2 measure = Vector2::zero;
|
||||||
|
|
||||||
|
ForChar(msg, [&, this](auto& s){
|
||||||
|
if (s.i > end) return true;
|
||||||
|
if (s.iline > 0) return false;
|
||||||
|
measure.x = std::max(measure.x, s.lineWidth);
|
||||||
|
measure.y += lineHeight;
|
||||||
|
return false;
|
||||||
|
}, maxWidth);
|
||||||
|
|
||||||
|
return measure;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 pen = Vector2::zero;
|
Vector2 measure;
|
||||||
Vector2 oPen = pen;
|
bool found = false;
|
||||||
float longest = 0;
|
|
||||||
float wordlen = 0;
|
|
||||||
float plen = 0;
|
|
||||||
|
|
||||||
float space = Char(' ').advX;
|
ForChar(msg, [&, this, total, end](auto& s){
|
||||||
|
measure = Vector2(s.lineAcc + s.cc->advX, lineHeight * s.lineNum);
|
||||||
for (unsigned int i = 0; i < len; i++) {
|
if (s.i == end-1) {
|
||||||
char& c = msg[i];
|
found = true;
|
||||||
if (c == ' ' || c == '\n') {
|
if (s.i == s.lineEnd) measure = Vector2(0, lineHeight * (s.lineNum + 1)); // linebreak == next line
|
||||||
bool lb = (c == '\n' || pen.x + wordlen > maxWidth);
|
return true;
|
||||||
oPen = pen;
|
|
||||||
|
|
||||||
if (lb) {
|
|
||||||
if (c == '\n') pen.x += space + wordlen; // previous word
|
|
||||||
longest = std::max(pen.x - space, longest);
|
|
||||||
pen.x = (c == ' ') ? (space + wordlen) : 0;
|
|
||||||
pen.y += lineHeight;
|
|
||||||
} else {
|
|
||||||
pen.x += space + wordlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!total && i >= end) {
|
|
||||||
return Vector2(pen.x - (wordlen - plen) - space, pen.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
wordlen = plen = 0;
|
|
||||||
} else {
|
|
||||||
float adv = Char(c).advX;
|
|
||||||
wordlen += adv;
|
|
||||||
if (i < end) plen += adv;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
longest = std::max(pen.x - space, longest);
|
return false;
|
||||||
|
}, maxWidth);
|
||||||
|
|
||||||
if (pen.x + space + wordlen > maxWidth) {
|
if (!found) { // catch newline-at-end
|
||||||
pen.x = wordlen;
|
measure.x = 0;
|
||||||
pen.y += lineHeight;
|
measure.y += lineHeight;
|
||||||
} else {
|
|
||||||
pen.x += wordlen + space;
|
|
||||||
}
|
|
||||||
longest = std::max(pen.x - space, longest); // do I need two of these?
|
|
||||||
|
|
||||||
if (!total) {
|
|
||||||
return Vector2(pen.x - (wordlen - plen) - space, pen.y); // return cursor position
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Vector2(longest, pen.y + lineHeight); // total size
|
return measure;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int BitmapFont::PointToIndex(std::string& msg, Vector2 pt, float maxWidth) {
|
unsigned int BitmapFont::PointToIndex(std::string& msg, Vector2 pt, float maxWidth) {
|
||||||
|
//pt -= Vector2(padX, 0*padY);
|
||||||
if (pt.y < 0) return 0;
|
if (pt.y < 0) return 0;
|
||||||
auto len = msg.length();
|
unsigned int tl = std::floor(pt.y / lineHeight);
|
||||||
|
|
||||||
unsigned int line = 0;
|
unsigned int idx;
|
||||||
unsigned int tLine = std::max(0.0f, std::floor(pt.y / lineHeight));
|
|
||||||
|
|
||||||
unsigned int le = 0; // line end
|
ForChar(msg, [&, this, pt, tl](auto& s){
|
||||||
unsigned int ti = 4294967295; // target index
|
if (s.lineNum < tl) return false; // skip
|
||||||
|
if (s.lineNum > tl) { // huh.
|
||||||
Vector2 pen = Vector2::zero;
|
return true;
|
||||||
float wordlen = 0;
|
|
||||||
|
|
||||||
float space = Char(' ').advX;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < len; i++) {
|
|
||||||
char& c = msg[i];
|
|
||||||
if (c == ' ' || c == '\n') {
|
|
||||||
// linebreak on newline or wrap needed
|
|
||||||
bool lb = (c == '\n' || pen.x + space + wordlen > maxWidth);
|
|
||||||
|
|
||||||
if (lb) {
|
|
||||||
if (c == '\n') le = i; // not wrapped
|
|
||||||
if (line == tLine) return std::min(le, ti);
|
|
||||||
pen.x = (c == ' ') ? wordlen : 0;
|
|
||||||
line++;
|
|
||||||
} else {
|
|
||||||
pen.x += wordlen + space;
|
|
||||||
if (line == tLine && ti == 4294967295 && pen.x - space*0.5f >= pt.x) ti = i;
|
|
||||||
le = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
wordlen = 0; // HERP DERP.
|
|
||||||
} else {
|
|
||||||
float cw = Char(c).advX;
|
|
||||||
wordlen += cw;
|
|
||||||
if (line == tLine && ti == 4294967295 && pen.x + wordlen - cw*0.5f >= pt.x) ti = i;
|
|
||||||
}
|
}
|
||||||
}
|
if (s.i == s.lineEnd) {
|
||||||
// oh right, process last word
|
if (s.i == s.lineStart) { // if blank line...
|
||||||
if (pen.x + space + wordlen > maxWidth) {
|
idx = s.i;
|
||||||
if (line == tLine) return std::min(le, ti);
|
return true;
|
||||||
pen.x = wordlen;
|
}
|
||||||
line++;
|
return false; // skip newlines on non-blank lines
|
||||||
} else {
|
}
|
||||||
le = len;
|
|
||||||
}
|
if ((s.iline == 0 || pt.x >= s.lineAcc) && pt.x < s.lineAcc + s.cc->advX) {
|
||||||
|
idx = s.i;
|
||||||
|
if (pt.x > s.lineAcc + s.cc->advX * 0.5f) idx++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = s.i+1;
|
||||||
|
return false;
|
||||||
|
}, maxWidth);
|
||||||
|
|
||||||
if (line == tLine) return std::min(le, ti);
|
return idx;
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitmapFont::ForChar(const std::string& msg, std::function<bool(CharLoopState&)> func, float maxWidth) {
|
void BitmapFont::ForChar(const std::string& msg, std::function<bool(CharLoopState&)> func, float maxWidth) {
|
||||||
@ -201,6 +163,7 @@ void BitmapFont::ForChar(const std::string& msg, std::function<bool(CharLoopStat
|
|||||||
float width;
|
float width;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned int len = msg.length();
|
||||||
float space = Char(' ').advX;
|
float space = Char(' ').advX;
|
||||||
|
|
||||||
std::vector<LineStat> lines;
|
std::vector<LineStat> lines;
|
||||||
@ -209,7 +172,6 @@ void BitmapFont::ForChar(const std::string& msg, std::function<bool(CharLoopStat
|
|||||||
LineStat cl = {0, 0, 0};
|
LineStat cl = {0, 0, 0};
|
||||||
float ww = 0;
|
float ww = 0;
|
||||||
unsigned int ws = 0;
|
unsigned int ws = 0;
|
||||||
unsigned int len = msg.length();
|
|
||||||
for (unsigned int i = 0; i <= len; i++) {
|
for (unsigned int i = 0; i <= len; i++) {
|
||||||
char c = (i == len) ? '\n' : msg[i];
|
char c = (i == len) ? '\n' : msg[i];
|
||||||
char pc = (i == 0) ? '\n' : msg[i-1];
|
char pc = (i == 0) ? '\n' : msg[i-1];
|
||||||
@ -262,9 +224,9 @@ void BitmapFont::ForChar(const std::string& msg, std::function<bool(CharLoopStat
|
|||||||
state.lineAcc = 0;
|
state.lineAcc = 0;
|
||||||
state.c = '\n';
|
state.c = '\n';
|
||||||
|
|
||||||
for (unsigned int i = cl.start; i < cl.end; i++) {
|
for (unsigned int i = cl.start; i <= cl.end; i++) {
|
||||||
char pc = state.c;
|
char pc = state.c;
|
||||||
state.c = msg[i];
|
state.c = (i >= len) ? '\n' : msg[i];
|
||||||
state.cc = &(Char(state.c));
|
state.cc = &(Char(state.c));
|
||||||
|
|
||||||
state.i = i;
|
state.i = i;
|
||||||
|
@ -34,7 +34,7 @@ void FontBMF::Print(Vector2 position, std::string& text, float scale, Color colo
|
|||||||
Vector2 uvScale = Vector2::one / font->txMain->txSize;
|
Vector2 uvScale = Vector2::one / font->txMain->txSize;
|
||||||
Vector2 ppen = Vector2(-font->padX, -font->padY /*- (font->lineHeight - font->baseY)*/);
|
Vector2 ppen = Vector2(-font->padX, -font->padY /*- (font->lineHeight - font->baseY)*/);
|
||||||
font->ForChar(text, [&, this, ppen, justification, qn, scale, uvScale](auto& s){
|
font->ForChar(text, [&, this, ppen, justification, qn, scale, uvScale](auto& s){
|
||||||
if (s.c == ' ') return false; // skip spaces
|
if (s.c == ' ' || s.c == '\n') return false; // skip spaces/newlines
|
||||||
Vector2 pen = (ppen + Vector2(s.lineAcc - s.lineWidth * justification.x, font->lineHeight * ((float)s.lineNum - (float)s.numLines * justification.y))) * scale;
|
Vector2 pen = (ppen + Vector2(s.lineAcc - s.lineWidth * justification.x, font->lineHeight * ((float)s.lineNum - (float)s.numLines * justification.y))) * scale;
|
||||||
auto& ci = *s.cc;
|
auto& ci = *s.cc;
|
||||||
VRect crect(ci.imgX, ci.imgY, ci.width, ci.height);
|
VRect crect(ci.imgX, ci.imgY, ci.width, ci.height);
|
||||||
@ -64,7 +64,7 @@ void FontBMF::Print(VRect rect, std::string& text, float scale, Color color, Vec
|
|||||||
Vector2 uvScale = Vector2::one / font->txMain->txSize;
|
Vector2 uvScale = Vector2::one / font->txMain->txSize;
|
||||||
Vector2 ppen = Vector2(-font->padX, -font->padY /*- (font->lineHeight - font->baseY)*/);
|
Vector2 ppen = Vector2(-font->padX, -font->padY /*- (font->lineHeight - font->baseY)*/);
|
||||||
font->ForChar(text, [&, this, ppen, justification, qn, scale, uvScale](auto& s){
|
font->ForChar(text, [&, this, ppen, justification, qn, scale, uvScale](auto& s){
|
||||||
if (s.c == ' ') return false; // skip spaces
|
if (s.c == ' ' || s.c == '\n') return false; // skip spaces/newlines
|
||||||
Vector2 pen = (ppen + Vector2(s.lineAcc - s.lineWidth * justification.x, font->lineHeight * ((float)s.lineNum - (float)s.numLines * justification.y))) * scale;
|
Vector2 pen = (ppen + Vector2(s.lineAcc - s.lineWidth * justification.x, font->lineHeight * ((float)s.lineNum - (float)s.numLines * justification.y))) * scale;
|
||||||
auto& ci = *s.cc;
|
auto& ci = *s.cc;
|
||||||
VRect crect(ci.imgX, ci.imgY, ci.width, ci.height);
|
VRect crect(ci.imgX, ci.imgY, ci.width, ci.height);
|
||||||
|
@ -7,13 +7,7 @@ roadmap to first release, in no particular order {
|
|||||||
- make backspace and enter actually do something
|
- make backspace and enter actually do something
|
||||||
- abstract osk input actions into a separate object/class heirarchy
|
- abstract osk input actions into a separate object/class heirarchy
|
||||||
- preview where applicable
|
- preview where applicable
|
||||||
fix desync between cursor position, tap-cursor and display when a single word overflows a line
|
|
||||||
(cursor doesn't wrap until the next word!?)
|
|
||||||
fix font glyph padding to eliminate slight "crosstalk" in bordered variants
|
fix font glyph padding to eliminate slight "crosstalk" in bordered variants
|
||||||
... reimplement as a per-character lambda-"loop" {
|
|
||||||
status object with stuff
|
|
||||||
precalculate line stats, then loop through each
|
|
||||||
}
|
|
||||||
polish!
|
polish!
|
||||||
InputManager::OpenKeyboard
|
InputManager::OpenKeyboard
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user