aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/font/bitmapfont.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api/font/bitmapfont.cpp')
-rw-r--r--Src/Wasabi/api/font/bitmapfont.cpp394
1 files changed, 394 insertions, 0 deletions
diff --git a/Src/Wasabi/api/font/bitmapfont.cpp b/Src/Wasabi/api/font/bitmapfont.cpp
new file mode 100644
index 00000000..fe85abda
--- /dev/null
+++ b/Src/Wasabi/api/font/bitmapfont.cpp
@@ -0,0 +1,394 @@
+#include "precomp.h"
+// ============================================================================================================================================================
+// Font abstract class + statics to install TT fonts and Bitmap fonts
+// ============================================================================================================================================================
+#include "bitmapfont.h"
+#include <api/wnd/fontdef.h>
+#include <api/config/items/cfgitem.h>
+#ifdef WASABI_COMPILE_SKIN
+#include <api/skin/skin.h>
+#endif
+#ifdef WA3COMPATIBILITY
+#endif
+
+#include <tataki/canvas/ifc_canvas.h>
+#include <tataki/region/api_region.h>
+#include <api/skin/skinparse.h>
+
+// ============================================================================================================================================================
+// BitmapFont implementation.
+// ============================================================================================================================================================
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+BitmapFont::BitmapFont() : scriptid(0), char_width(0), char_height(0), hor_spacing(0), vert_spacing(0) {
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+BitmapFont::~BitmapFont() {
+
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::isBitmap() {
+ return 1;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+const wchar_t *BitmapFont::getFaceName() {
+ return getFontId();
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, -1, -1, txt, size, bold, opaque, underline, italic, STDFONT_LEFT, color, WA_FONT_TEXTOUT_NORMAL);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOut2(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, x+xoffset+w, y+yoffset+h, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_RECT);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, x+xoffset+w, y+yoffset+h, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_ELLIPSED);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, x+xoffset+w, y+yoffset+h, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_WRAPPED);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, x+xoffset+w, -1, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_WRAPPEDPATHED);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, r->left, r->top, r->right-r->left, r->bottom-r->top, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_CENTERED);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased)
+{
+ return wcslen(text) * char_width + wcslen(text)*hor_spacing;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased)
+{
+ return char_height;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialiased)
+{
+ return char_height;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialiased)
+{
+ if (w) *w = getTextWidth(c, text, size, bold, underline, italic, antialiased);
+ if (h) *h = char_height;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::setFontBitmap(const wchar_t *name_or_element, const wchar_t *path)
+{
+ StringW pathfile;
+ if (!wcschr(name_or_element, L':'))
+ {
+ pathfile = path;
+ pathfile.AddBackslash();
+ }
+ pathfile.cat(name_or_element);
+ if (!WACCESS(pathfile, 0))
+ table = pathfile;
+ else
+ table = name_or_element;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::setFontMetrics(int _char_width, int _char_height, int _hor_spacing, int _vert_spacing) {
+ char_width = _char_width;
+ char_height = _char_height;
+ hor_spacing = _hor_spacing;
+ vert_spacing = _vert_spacing;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getHorizontalSpacing() {
+ return hor_spacing;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getVerticalSpacing() {
+ return vert_spacing;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getCharWidth() {
+ return char_width;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getCharHeight() {
+ return char_height;
+}
+
+AutoSkinBitmap *BitmapFont::getCharTable() {
+ return &table;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::getXYfromChar(wchar_t ic, int *x, int *y)
+{
+ int c,c2=0;
+ switch (ic)
+ {
+ case L'\u00B0': /**/ ic = L'0'; break;
+ case L'\u00C6':/**/ ic = L'A'; break;
+ // case '\u00C1':/**/ ic = L'A'; break;
+ // case '\u00C2': ic = L'A'; break;
+ case L'\u00C7': /**/ ic = L'C'; break;
+ case L'\u00C9':/**/ ic = L'E'; break;
+
+ case L'\u00E0': /**/ case L'\u00E1': /**/ case L'\u00E2': /**/ ic = L'a'; break;
+ case L'\u00E6':/**/ ic = L'a'; break;
+ case L'\u00E7': /**/ ic = L'c'; break;
+ case L'\u00E8': /**/ case L'\u00E9': /**/ case L'\u00EB': /**/case L'\u00EA':/**/ ic = L'e'; break;
+ case L'\u00EC':/**/ case L'\u00ED':/**/ case L'\u00EE':/**/ case L'\u00EF':/**/ ic = L'i'; break;
+
+#ifdef _WIN32
+ case L'':/**/ case L'':/**/ case L'':/**/ ic = L'o'; break;
+ case L'':/**/ case L'':/**/ case L'':/**/ ic = L'u'; break;
+ case L'':/**/ ic = L'y'; break;
+ case L'':/**/ ic = L'U'; break;
+#else
+#warning change these to \u
+#endif
+ case L'\u00D1':/**/ ic = L'N'; break;
+ case L'\u00F1':/**/ ic = L'n'; break;
+ case L'\u00FC': /**/ ic = L'u'; break;
+ case L'\u0192':/**/ ic = L'f'; break;
+ default: break;
+ } // quick relocations
+ if (ic <= L'Z' && ic >= L'A') c = (ic-'A');
+ else if (ic <= L'z' && ic >= L'a') c = (ic-'a');
+ else if (ic == L' ') c = 30;
+ else {
+ c2 += char_height;
+ if (ic == L'\1') c=10;
+ else if (ic == L'.') c = 11;
+ else if (ic <= L'9' && ic >= L'0') c = ic - L'0';
+ else if (ic == L':') c = 12;
+ else if (ic == L'(') c = 13;
+ else if (ic == L')') c = 14;
+ else if (ic == L'-') c = 15;
+ else if (ic == L'\'' || ic=='`') c = 16;
+ else if (ic == L'!') c = 17;
+ else if (ic == L'_') c = 18;
+ else if (ic == L'+') c = 19;
+ else if (ic == L'\\') c = 20;
+ else if (ic == L'/') c = 21;
+ else if (ic == L'[' || ic == L'{' || ic == L'<') c = 22;
+ else if (ic == L']' || ic == L'}' || ic == L'>') c = 23;
+ else if (ic == L'~' || ic == L'^') c = 24;
+ else if (ic == L'&') c = 25;
+ else if (ic == L'%') c = 26;
+ else if (ic == L',') c = 27;
+ else if (ic == L'=') c = 28;
+ else if (ic == L'$') c = 29;
+ else if (ic == L'#') c = 30;
+ else
+ {
+ c2 += char_height;
+#ifdef _WIN32
+ if (ic == L'' || ic == L'') c = 0;
+ else if (ic == L'' || ic == L'') c = 1;
+ else if (ic == L'' || ic == L'') c = 2;
+ else
+#else
+#warning change these to \u
+#endif
+ if (ic == L'?') c = 3;
+ else if (ic == L'*') c = 4;
+ else {
+ c2 = 0;
+ if (ic == L'"') c = 26;
+ else if (ic == L'@') c = 27;
+ else c = 30;
+ }
+ }
+ }
+ c*=char_width;
+ *x=c;
+ *y=c2;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getWordLength(const wchar_t *p) {
+ int n=0;
+ while (p && *p && *p != L' ') {
+ p++;
+ n++;
+ }
+ return n;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+wchar_t *BitmapFont::makeLine(const wchar_t *t, BitmapFont *font, int line, int width, int style) {
+
+ static wchar_t str[4096];
+ wchar_t *p = (wchar_t *)t;
+ size_t len = wcslen(t);
+
+ switch (style) {
+ case WA_FONT_TEXTOUT_NORMAL:
+ case WA_FONT_TEXTOUT_RECT:
+ case WA_FONT_TEXTOUT_ELLIPSED:
+ case WA_FONT_TEXTOUT_CENTERED:
+ return line == 0 ? (wchar_t *)t : NULL;
+ case WA_FONT_TEXTOUT_WRAPPEDPATHED:
+ case WA_FONT_TEXTOUT_WRAPPED: {
+ size_t maxchar = width / (font->getCharWidth() + font->getVerticalSpacing());
+ for (int i = 0; i < line; i++) {
+ wchar_t *oldp = p;
+ p += maxchar;
+ if ((size_t)(p-t) >= len) return NULL;
+ while (p >= t) {
+ if (p == t || *(p-1) == L' ')
+ break;
+ p--;
+ }
+ if (p == oldp) {
+ p += maxchar;
+ while (p && *p && *p != L' ')
+ p++;
+ }
+ }
+ WCSCPYN(str, p, maxchar);
+ wchar_t *d = &str[maxchar-1];
+ int wr=0;
+ if (wcslen(p) > maxchar && *(p+maxchar) != L' ' && wcschr(str, L' '))
+ while (d >= str) {
+ if (*d == L' ') {
+ *d = 0;
+ wr=1;
+ }
+ else {
+ if (wr) break;
+ d--;
+ }
+ }
+ return str;
+ }
+ }
+ return NULL;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::do_textOut(BitmapFont *font, ifc_canvas *c, int x, int y, int x2, int y2, const wchar_t *text, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, int style)
+{
+ static wchar_t *dotdotdot=L"...";
+ if (!text) return;
+
+ BaseCloneCanvas canvas;
+ int ret = canvas.clone(c);
+ if (!ret) return;
+
+ RECT bounds;
+
+ RECT defbounds={x,y,x2,y2};
+ int __w, __h;
+ c->getDim(&__w, &__h, NULL);
+ if (x2 == -1) defbounds.right = defbounds.left + __w;
+ if (y2 == -1) defbounds.bottom = defbounds.top + __h;
+#ifdef _WIN32
+ RegionI oldclip(&canvas, &defbounds); // get clipping region in oldclip
+ RegionI *andclip=NULL;
+ oldclip.getBox(&bounds); // get boundaries
+#else
+ bounds = defbounds;
+#warning port me
+#endif
+
+/* if (x2 != -1 && y2 != -1) {
+ andclip = new RegionI(x, y, x2, y2); // create region for rect
+ andclip->andRegion(oldclip); // and them
+ canvas.selectClipRgn(andclip); // select new clipping rect
+ andclip->getBox(&bounds); // update boundaries
+ }*/
+
+ int lc=-1;
+ wchar_t *p = dotdotdot+3; // just a zero to triger next line
+
+ int _x = x+(font->getHorizontalSpacing()/2);
+ int _y = y;
+
+ if (style == WA_FONT_TEXTOUT_CENTERED) {
+ _y += (y2 - y - font->getCharHeight()) / 2;
+ }
+
+ _y -= font->getCharHeight() + font->getVerticalSpacing();
+
+ int xp, yp;
+
+ while (p) {
+
+ if (!*p) {
+ lc++;
+ p = makeLine(text, font, lc, x2-x, style);
+ if (!p || !*p) break;
+
+ _x = x+(font->getHorizontalSpacing()/2);
+ _y += font->getCharHeight() + font->getVerticalSpacing();
+ if ((align == STDFONT_RIGHT || align == STDFONT_CENTER) && x2 != -1) {
+ int l = wcslen(p);
+ _x -= l * (font->getCharWidth() + font->getHorizontalSpacing()) - (x2-x);
+ }
+ if (align == STDFONT_CENTER)
+ _x = x + (_x - x) / 2;
+
+ }
+
+ if ((style == WA_FONT_TEXTOUT_ELLIPSED || style == WA_FONT_TEXTOUT_WRAPPEDPATHED) && x2 != -1) {
+ if (_x > x2 - 4 * (font->getCharWidth() + font->getHorizontalSpacing()) && wcslen(p) > 3) {
+ p = dotdotdot;
+ }
+ }
+
+ font->getXYfromChar(*p, &xp, &yp);
+
+ RECT r;
+ r.left = xp;
+ r.top = yp;
+ r.right = xp + font->getCharWidth();
+ r.bottom = yp + font->getCharHeight();
+
+ RECT dst;
+ dst.left = _x;
+ dst.top = _y;
+ dst.right = _x + font->getCharWidth();
+ dst.bottom = _y + font->getCharHeight();
+
+ if (Wasabi::Std::rectIntersect(dst, bounds))
+// if (IntersectRect(&dummy, &dst, &bounds)) // port me / checks clipping, not passed x,y,x2,y2
+ font->getCharTable()->stretchToRectAlpha(&canvas, &r, &dst, 255);
+
+ p++;
+ _x += font->getCharWidth();
+ _x += font->getHorizontalSpacing();
+ }
+
+#ifdef _WIN32
+ if (andclip) {
+ canvas.selectClipRgn(&oldclip); // restore previously saved clipping region
+ delete andclip;
+ }
+#else
+#warning port me
+#endif
+}
+