mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 07:45:46 -04:00
Initial community commit
This commit is contained in:
7
Src/Wasabi/api/font/FontCreator.h
Normal file
7
Src/Wasabi/api/font/FontCreator.h
Normal file
@ -0,0 +1,7 @@
|
||||
#include <api/service/svcs/svc_font.h>
|
||||
template <class T>
|
||||
class FontCreator : public waServiceFactoryT<svc_font, T>
|
||||
{
|
||||
public:
|
||||
FontCreator(GUID myGuid = INVALID_GUID) : waServiceFactoryT<svc_font, T>(myGuid) {}
|
||||
};
|
18
Src/Wasabi/api/font/FontSvcEnum.h
Normal file
18
Src/Wasabi/api/font/FontSvcEnum.h
Normal file
@ -0,0 +1,18 @@
|
||||
#include <bfc/string/StringW.h>
|
||||
#include <api/service/svc_enum.h>
|
||||
|
||||
class FontSvcEnum : public SvcEnumT<svc_font> {
|
||||
public:
|
||||
FontSvcEnum(const wchar_t *_svc_name = NULL) : svc_name(_svc_name) {}
|
||||
protected:
|
||||
virtual int testService(svc_font *svc)
|
||||
{
|
||||
if (!svc_name.len())
|
||||
return 1; // blank name returns all services.
|
||||
return (!WCSICMP(svc->getFontSvcName(),svc_name));
|
||||
}
|
||||
private:
|
||||
StringW svc_name;
|
||||
};
|
||||
|
||||
|
11
Src/Wasabi/api/font/api_font.cpp
Normal file
11
Src/Wasabi/api/font/api_font.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include <precomp.h>
|
||||
#include "api_font.h"
|
||||
|
||||
#ifdef CBCLASS
|
||||
#undef CBCLASS
|
||||
#endif
|
||||
#define CBCLASS api_fontI
|
||||
START_DISPATCH;
|
||||
VCB(API_FONT_FONT_TEXTOUT, font_textOut);
|
||||
CB(API_FONT_FONT_GETINFO, font_getInfo);
|
||||
END_DISPATCH;
|
36
Src/Wasabi/api/font/api_font.h
Normal file
36
Src/Wasabi/api/font/api_font.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef __API_FONT_H
|
||||
#define __API_FONT_H
|
||||
|
||||
#include <bfc/dispatch.h>
|
||||
|
||||
class ifc_canvas;
|
||||
|
||||
class NOVTABLE api_font : public Dispatchable
|
||||
{
|
||||
public:
|
||||
void font_textOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt);
|
||||
int font_getInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h);
|
||||
|
||||
enum {
|
||||
API_FONT_FONT_TEXTOUT = 0,
|
||||
API_FONT_FONT_GETINFO = 10,
|
||||
};
|
||||
};
|
||||
|
||||
inline void api_font::font_textOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt)
|
||||
{
|
||||
_voidcall(API_FONT_FONT_TEXTOUT, c, style, x, y, w, h, txt);
|
||||
}
|
||||
|
||||
inline int api_font::font_getInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h)
|
||||
{
|
||||
return _call(API_FONT_FONT_GETINFO, (int)0, c, font, infoid, txt, w, h);
|
||||
}
|
||||
|
||||
// {1FCA9C7E-5923-4b9c-8906-0F8C331DF21C}
|
||||
static const GUID fontApiServiceGuid =
|
||||
{ 0x1fca9c7e, 0x5923, 0x4b9c, { 0x89, 0x6, 0xf, 0x8c, 0x33, 0x1d, 0xf2, 0x1c } };
|
||||
|
||||
extern api_font *fontApi;
|
||||
|
||||
#endif
|
394
Src/Wasabi/api/font/bitmapfont.cpp
Normal file
394
Src/Wasabi/api/font/bitmapfont.cpp
Normal file
@ -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': /*<2A>*/ ic = L'0'; break;
|
||||
case L'\u00C6':/*<2A>*/ ic = L'A'; break;
|
||||
// case '\u00C1':/*<2A>*/ ic = L'A'; break;
|
||||
// case '\u00C2': ic = L'A'; break;
|
||||
case L'\u00C7': /*<2A>*/ ic = L'C'; break;
|
||||
case L'\u00C9':/*<2A>*/ ic = L'E'; break;
|
||||
|
||||
case L'\u00E0': /*<2A>*/ case L'\u00E1': /*<2A>*/ case L'\u00E2': /*<2A>*/ ic = L'a'; break;
|
||||
case L'\u00E6':/*<2A>*/ ic = L'a'; break;
|
||||
case L'\u00E7': /*<2A>*/ ic = L'c'; break;
|
||||
case L'\u00E8': /*<2A>*/ case L'\u00E9': /*<2A>*/ case L'\u00EB': /*<2A>*/case L'\u00EA':/*<2A>*/ ic = L'e'; break;
|
||||
case L'\u00EC':/*<2A>*/ case L'\u00ED':/*<2A>*/ case L'\u00EE':/*<2A>*/ case L'\u00EF':/*<2A>*/ ic = L'i'; break;
|
||||
|
||||
#ifdef _WIN32
|
||||
case L'<EFBFBD>':/*<2A>*/ case L'<EFBFBD>':/*<2A>*/ case L'<EFBFBD>':/*<2A>*/ ic = L'o'; break;
|
||||
case L'<EFBFBD>':/*<2A>*/ case L'<EFBFBD>':/*<2A>*/ case L'<EFBFBD>':/*<2A>*/ ic = L'u'; break;
|
||||
case L'<EFBFBD>':/*<2A>*/ ic = L'y'; break;
|
||||
case L'<EFBFBD>':/*<2A>*/ ic = L'U'; break;
|
||||
#else
|
||||
#warning change these to \u
|
||||
#endif
|
||||
case L'\u00D1':/*<2A>*/ ic = L'N'; break;
|
||||
case L'\u00F1':/*<2A>*/ ic = L'n'; break;
|
||||
case L'\u00FC': /*<2A>*/ ic = L'u'; break;
|
||||
case L'\u0192':/*<2A>*/ 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'<EFBFBD>' || ic == L'<EFBFBD>') c = 0;
|
||||
else if (ic == L'<EFBFBD>' || ic == L'<EFBFBD>') c = 1;
|
||||
else if (ic == L'<EFBFBD>' || ic == L'<EFBFBD>') 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
|
||||
}
|
||||
|
70
Src/Wasabi/api/font/bitmapfont.h
Normal file
70
Src/Wasabi/api/font/bitmapfont.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef __BITMAPFONT_H
|
||||
#define __BITMAPFONT_H
|
||||
|
||||
#include <api/font/svc_fonti.h>
|
||||
|
||||
//#include "font.h"
|
||||
|
||||
#include <bfc/platform/platform.h>
|
||||
#include <bfc/ptrlist.h>
|
||||
#include <bfc/stack.h>
|
||||
#include <tataki/bitmap/autobitmap.h>
|
||||
#include <bfc/string/StringW.h>
|
||||
|
||||
class Font;
|
||||
|
||||
class BitmapFont : public svc_fontI
|
||||
{
|
||||
friend class Font;
|
||||
public:
|
||||
|
||||
virtual void 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);
|
||||
virtual void 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);
|
||||
virtual void 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);
|
||||
virtual void 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);
|
||||
virtual void 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);
|
||||
virtual void 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);
|
||||
virtual int getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased);
|
||||
virtual int getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased);
|
||||
virtual int getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialiased);
|
||||
virtual void getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialiased);
|
||||
virtual int isBitmap();
|
||||
|
||||
virtual void setFontBitmap(const wchar_t *name_or_element, const wchar_t *path);
|
||||
virtual void setFontMetrics(int char_width, int char_height, int hor_spacing, int vert_spacing);
|
||||
virtual const wchar_t *getFaceName();
|
||||
|
||||
virtual void setFontId(const wchar_t *id) { font_id = id; }
|
||||
virtual const wchar_t *getFontId() { return font_id; }
|
||||
virtual int getScriptId() { return scriptid; }
|
||||
virtual void setScriptId(int id) { scriptid = id; }
|
||||
virtual void setFontFace(const wchar_t *face) {}
|
||||
virtual int addFontResource(OSFILETYPE f, const wchar_t *name) { return 0; /*failure*/}
|
||||
virtual int addFontResource2(void *mem, int datalen, const wchar_t *name) { return 0; /*failure*/}
|
||||
|
||||
virtual const wchar_t *getFontSvcName() { return L"Bitmap Font"; }
|
||||
|
||||
protected:
|
||||
BitmapFont();
|
||||
virtual ~BitmapFont();
|
||||
|
||||
AutoSkinBitmap *getCharTable();
|
||||
int getCharWidth();
|
||||
int getCharHeight();
|
||||
int getHorizontalSpacing();
|
||||
int getVerticalSpacing();
|
||||
void getXYfromChar(wchar_t ic, int *x, int *y);
|
||||
|
||||
protected:
|
||||
StringW font_id;
|
||||
int scriptid;
|
||||
|
||||
private:
|
||||
AutoSkinBitmap table;
|
||||
int char_width, char_height, hor_spacing, vert_spacing;
|
||||
static void 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 int getWordLength(const wchar_t *p);
|
||||
static wchar_t *makeLine(const wchar_t *t, BitmapFont *font, int line, int physwidth, int style);
|
||||
};
|
||||
|
||||
#endif
|
637
Src/Wasabi/api/font/font.cpp
Normal file
637
Src/Wasabi/api/font/font.cpp
Normal file
@ -0,0 +1,637 @@
|
||||
#include "precomp.h"
|
||||
// ============================================================================================================================================================
|
||||
// Font abstract class + statics to install TT fonts and Bitmap fonts
|
||||
// ============================================================================================================================================================
|
||||
|
||||
#include <api/font/font.h>
|
||||
#include <api/font/bitmapfont.h>
|
||||
#include <bfc/parse/pathparse.h>
|
||||
|
||||
#ifdef WASABI_COMPILE_SKIN
|
||||
#include <api/skin/skin.h>
|
||||
#include <api/skin/skinparse.h>
|
||||
#endif
|
||||
|
||||
#include <tataki/canvas/ifc_canvas.h>
|
||||
#include <api/wnd/fontdef.h>
|
||||
|
||||
#ifdef WASABI_COMPILE_FONT
|
||||
#include <api/service/svcs/svc_font.h>
|
||||
//#include "services/svc_fontmaker.h"
|
||||
#endif
|
||||
|
||||
#ifdef WASABI_API_CONFIG
|
||||
#include <api/config/options.h>
|
||||
#include <api/config/items/attrint.h>
|
||||
#include <api/config/items/attrstr.h>
|
||||
#include <api/config/items/attrbool.h>
|
||||
#endif
|
||||
#include <api/memmgr/api_memmgr.h>
|
||||
#include <api/font/FontSvcEnum.h>
|
||||
|
||||
extern _bool cfg_options_usefontmapper;
|
||||
extern _string cfg_options_ttfoverridefont;
|
||||
extern _int cfg_options_defaultfontscale;
|
||||
|
||||
PtrList<svc_font> Font::fontlist;
|
||||
PtrList<FontDef> Font::fontdefs;
|
||||
|
||||
void Font::init()
|
||||
{
|
||||
#ifdef WASABI_API_CONFIG
|
||||
Wasabi::Std::setDefaultFont(cfg_options_defaultfont.getValue());
|
||||
Wasabi::Std::setDefaultFontScale(cfg_options_defaultfontscale.getValueAsInt());
|
||||
#endif
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void Font::dispatchTextOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt)
|
||||
{
|
||||
int isoverride = 0;
|
||||
if (WASABI_API_APP->main_isShuttingDown()) return;
|
||||
|
||||
int size = c->getTextSize();
|
||||
|
||||
svc_font *f = requestSkinFont(c->getTextFont(), &size);
|
||||
|
||||
ASSERT(f != NULL);
|
||||
|
||||
// After we get the font we want, check to see if it is bitmap.
|
||||
// If bitmap fonts are disallowed, use the truetype override font.
|
||||
if (f->isBitmap() && useTrueTypeOverride(txt))
|
||||
{
|
||||
int gotdefault=0;
|
||||
svc_font *ttFont = requestSkinFont(getTrueTypeOverride(), &size, &gotdefault);
|
||||
if (ttFont != NULL)
|
||||
{
|
||||
if (!gotdefault)
|
||||
isoverride = 1;
|
||||
f = ttFont;
|
||||
}
|
||||
}
|
||||
|
||||
if (isoverride)
|
||||
{
|
||||
double f = (double)getTrueTypeOverrideScale() / 100.0f;
|
||||
size = (int)(size*f);
|
||||
}
|
||||
int bold = c->getTextBold();
|
||||
int opaque = c->getTextOpaque();
|
||||
int underline = c->getTextUnderline();
|
||||
int italic = c->getTextItalic();
|
||||
int align = c->getTextAlign();
|
||||
int antialiased = c->getTextAntialias();
|
||||
ARGB32 color = c->getTextColor();
|
||||
ARGB32 bkcolor = c->getTextBkColor();
|
||||
int xoffset=0, yoffset=0;
|
||||
c->getOffsets(&xoffset, &yoffset);
|
||||
/* if (!f->isBitmap() && _intVal(Main::enumRootCfgItem(0), "Force antialias on all TTF"))
|
||||
antialiased = 1;*/
|
||||
switch (style)
|
||||
{
|
||||
case WA_FONT_TEXTOUT_NORMAL:
|
||||
f->textOut(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, antialiased);
|
||||
break;
|
||||
case WA_FONT_TEXTOUT_RECT:
|
||||
f->textOut(c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
|
||||
break;
|
||||
case WA_FONT_TEXTOUT_ELLIPSED:
|
||||
f->textOutEllipsed(c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
|
||||
break;
|
||||
case WA_FONT_TEXTOUT_WRAPPED:
|
||||
f->textOutWrapped(c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
|
||||
break;
|
||||
case WA_FONT_TEXTOUT_WRAPPEDPATHED:
|
||||
f->textOutWrappedPathed(c, x, y, w, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
|
||||
break;
|
||||
case WA_FONT_TEXTOUT_CENTERED:
|
||||
RECT r;
|
||||
r.left = x;
|
||||
r.top = y;
|
||||
r.right = w;
|
||||
r.bottom = h;
|
||||
f->textOutCentered(c, &r, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int Font::dispatchGetInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h)
|
||||
{
|
||||
int isoverride = 0;
|
||||
if (WASABI_API_APP->main_isShuttingDown()) return 0;
|
||||
// mig: Let's not crash if we want to see how big a NULL pointer is.
|
||||
if (txt == NULL) {
|
||||
if ( infoid == WA_FONT_GETINFO_WIDTHHEIGHT ) {
|
||||
if (w != NULL) {
|
||||
*w = 0;
|
||||
}
|
||||
if (h != NULL) {
|
||||
*h = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int size = c->getTextSize();
|
||||
|
||||
svc_font *f = requestSkinFont(font, &size);
|
||||
ASSERT(f != NULL);
|
||||
|
||||
// After we get the font we want, check to see if it is bitmap.
|
||||
// If bitmap fonts are disallowed, use the truetype override font.
|
||||
if (f->isBitmap() && useTrueTypeOverride(txt))
|
||||
{
|
||||
int gotdefault = 0;
|
||||
svc_font *ttFont = requestSkinFont(getTrueTypeOverride(), &size, &gotdefault);
|
||||
if (ttFont != NULL)
|
||||
{
|
||||
if (!gotdefault)
|
||||
isoverride = 1;
|
||||
f = ttFont;
|
||||
}
|
||||
}
|
||||
|
||||
if (isoverride) {
|
||||
double f = (double)getTrueTypeOverrideScale() / 100.0f;
|
||||
size = (int)(size*f);
|
||||
}
|
||||
int bold = c->getTextBold();
|
||||
int underline = c->getTextUnderline();
|
||||
int italic = c->getTextItalic();
|
||||
int antialiased = c->getTextAntialias();
|
||||
switch (infoid) {
|
||||
case WA_FONT_GETINFO_WIDTH:
|
||||
return f->getTextWidth(c, txt, size, bold, underline, italic, antialiased);
|
||||
case WA_FONT_GETINFO_HEIGHT:
|
||||
return f->getTextHeight(c, txt, size, bold, underline, italic, antialiased);
|
||||
case WA_FONT_GETINFO_WIDTHHEIGHT:
|
||||
f->getTextExtent(c, txt, w, h, size, bold, underline, italic, antialiased);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Install a truetype font from its filename and associate a script_id to it
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
svc_font *Font::installTrueTypeFont(const wchar_t *filename, const wchar_t *path, const wchar_t *id, int scriptid, int allowmapping, int isttfreload) {
|
||||
|
||||
if (!isttfreload)
|
||||
{
|
||||
FontDef *fd = new FontDef;
|
||||
fd->filename = filename;
|
||||
fd->path = path;
|
||||
fd->id = id;
|
||||
fd->scriptid = scriptid;
|
||||
fd->isbitmap = 0;
|
||||
fd->allowmapping = allowmapping;
|
||||
fontdefs.addItem(fd);
|
||||
}
|
||||
|
||||
StringW file;
|
||||
|
||||
OSFILETYPE ff=OPEN_FAILED;
|
||||
if (wcschr(filename, ':'))
|
||||
ff = WFOPEN(filename, WF_READONLY_BINARY);
|
||||
|
||||
if (ff == OPEN_FAILED)
|
||||
{
|
||||
file = StringPathCombine(path, filename);
|
||||
ff = WFOPEN(file, WF_READONLY_BINARY);
|
||||
}
|
||||
#ifdef WASABI_COMPILE_SKIN
|
||||
if (ff == OPEN_FAILED)
|
||||
{
|
||||
file = StringPathCombine(SkinParser::getXmlRootPath(), filename);
|
||||
ff = WFOPEN(file, WF_READONLY_BINARY);
|
||||
if (ff == OPEN_FAILED)
|
||||
{
|
||||
file = StringPathCombine(Skin::getDefaultSkinPath(), filename);
|
||||
ff = WFOPEN(file, WF_READONLY_BINARY);
|
||||
if (ff == OPEN_FAILED)
|
||||
{
|
||||
DebugString("Font not found %s\n", filename);
|
||||
// todo: do something if still not found
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (ff == OPEN_FAILED) {
|
||||
DebugString("Could not install font %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
StringW fs = filename;
|
||||
wchar_t *p = wcschr(fs.getNonConstVal(), '.');
|
||||
if (p)
|
||||
*p = 0;
|
||||
PathParserW pp(fs);
|
||||
fs = pp.getLastString();
|
||||
|
||||
svc_font *f = newTrueTypeFont();
|
||||
if (f && f->addFontResource( ff, fs) )
|
||||
{
|
||||
f->setFontId(id);
|
||||
f->setScriptId(scriptid);
|
||||
fontlist.addItem(f);
|
||||
} else {
|
||||
DebugString("font.cpp ====== CAN'T LOAD FONT FILE.\n");
|
||||
}
|
||||
|
||||
FCLOSE(ff);
|
||||
return f;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Uninstall all installed fonts
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void Font::uninstallAll(int ttfreload) {
|
||||
int i;
|
||||
// delete all by hand
|
||||
for (i = 0; i < fontlist.getNumItems(); i++) {
|
||||
svc_font *f = fontlist.enumItem(i);
|
||||
if (ttfreload && f->isBitmap()) continue;
|
||||
deleteFont(f);
|
||||
fontlist.removeByPos(i);
|
||||
i--;
|
||||
}
|
||||
if (!ttfreload) fontdefs.deleteAll();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Uninstall by scriptid
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void Font::uninstallByScriptId(int scriptid) {
|
||||
for (int i=0;i<fontlist.getNumItems();i++) {
|
||||
svc_font *f = fontlist.enumItem(i);
|
||||
if (f->getScriptId() == scriptid) {
|
||||
fontlist.removeByPos(i);
|
||||
deleteFont(f);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
for (int i=0;i<fontdefs.getNumItems();i++) {
|
||||
FontDef *fd = fontdefs.enumItem(i);
|
||||
if (fd->scriptid == scriptid) {
|
||||
fontdefs.removeByPos(i);
|
||||
delete fd;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Install a bitmap font and associates a script_id to it
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void Font::installBitmapFont(const wchar_t *filename, const wchar_t *path, const wchar_t *id, int cw, int ch, int hs, int vs, int scriptid, int allowmapping)
|
||||
{
|
||||
FontDef *fd = new FontDef;
|
||||
fd->filename = filename;
|
||||
fd->path = path;
|
||||
fd->id = id;
|
||||
fd->scriptid = scriptid;
|
||||
fd->isbitmap = 1;
|
||||
fd->allowmapping = allowmapping;
|
||||
fontdefs.addItem(fd);
|
||||
|
||||
BitmapFont *f = new BitmapFont;
|
||||
f->setFontBitmap(filename, path);
|
||||
f->setFontId(id);
|
||||
f->setFontMetrics(cw, ch, hs, vs);
|
||||
f->setScriptId(scriptid);
|
||||
fontlist.addItem(f);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Requests a Font* from its id
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
svc_font *Font::requestSkinFont(const wchar_t *id, int *size, int *gotdefault)
|
||||
{
|
||||
if (gotdefault) *gotdefault = 0;
|
||||
int oldsize = size ? *size : -1;
|
||||
const wchar_t *mapped_id = getFontMapping(id, size);
|
||||
if (mapped_id != NULL)
|
||||
id = mapped_id;
|
||||
|
||||
// First try to get a font by that id
|
||||
foreach_reverse(fontlist)
|
||||
const wchar_t *thisid = fontlist.getfor()->getFontId();
|
||||
if (thisid && !WCSICMP(thisid, id))
|
||||
return fontlist.getfor();
|
||||
endfor
|
||||
// if it wasnt found, try to load a wa-installed ttfont with this face name
|
||||
foreach_reverse(fontlist)
|
||||
const wchar_t *facename=fontlist.getfor()->getFaceName();
|
||||
if (facename && !WCSICMP(facename, id)) return fontlist.getfor();
|
||||
endfor
|
||||
|
||||
// not found, try to reload it front the list of fonts defined by the skin
|
||||
foreach(fontdefs)
|
||||
FontDef *fd = fontdefs.getfor();
|
||||
if (!WCSICMP(fd->id, id))
|
||||
{
|
||||
if (!fd->isbitmap)
|
||||
{
|
||||
svc_font *f = installTrueTypeFont(fd->filename, fd->path, fd->id, fd->scriptid, fd->allowmapping, 1);
|
||||
if (f) return f;
|
||||
}
|
||||
}
|
||||
endfor;
|
||||
|
||||
/*
|
||||
for (i=fontlist.getNumItems()-1;i>=0;i--) {
|
||||
const char *thisid = fontlist.enumItem(i)->getFontId();
|
||||
if (thisid && STRCASEEQL(thisid, "wasabi.font.ttf.default" ))
|
||||
return fontlist.enumItem(i);
|
||||
}
|
||||
*/
|
||||
|
||||
// not found ? try to find it in the windows fonts directory
|
||||
{
|
||||
wchar_t *fp = WMALLOC(WA_MAX_PATH);
|
||||
Wasabi::Std::getFontPath(WA_MAX_PATH, fp);
|
||||
StringW file;
|
||||
file.own(fp);
|
||||
// FREE(fp); // benski> no need because we now own it
|
||||
file.AppendPath(StringPrintfW(L"%s%s", id, WCSCASESTR(id, L".ttf") == NULL ? L".ttf":L""));
|
||||
|
||||
if (!WACCESS(file, 0))
|
||||
{
|
||||
svc_font *f = newTrueTypeFont();
|
||||
f->setFontFace(id);
|
||||
f->setFontId(id);
|
||||
OSFILETYPE ff = WFOPEN(file, WF_READONLY_BINARY);
|
||||
if (ff != OPEN_FAILED)
|
||||
{
|
||||
if (f->addFontResource(ff, id))
|
||||
{
|
||||
DebugStringW(L"font.cpp ====== FONT FOR ID=%s NOT FOUND. USING WIN FONT FILE:\n%s\n", id, file.getValue());
|
||||
fontlist.addItem(f);
|
||||
}
|
||||
} else {
|
||||
DebugStringW(L"font.cpp ====== FONT FOR ID=%s NOT FOUND. CANNOT OPEN WIN FONT FILE:\n%s\n", id, file.getValue());
|
||||
delete f;
|
||||
f = NULL;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
// not found ? ask the Std:: interface for the folder and the
|
||||
// default fontname (ie: one you know will always be in the OS)
|
||||
svc_font *f = newTrueTypeFont();
|
||||
if (f) {
|
||||
if (gotdefault) *gotdefault = 1;
|
||||
if (oldsize != -1 && size) {
|
||||
*size = oldsize;
|
||||
double f = (double)Wasabi::Std::getDefaultFontScale() / 100.0;
|
||||
*size = (int)(*size*f);
|
||||
}
|
||||
// Query Std:: and build the path to the default font file.
|
||||
wchar_t *fontPath = WMALLOC(WA_MAX_PATH);
|
||||
Wasabi::Std::getFontPath(WA_MAX_PATH, fontPath);
|
||||
wchar_t fontFile[WA_MAX_PATH] = {0};
|
||||
Wasabi::Std::getDefaultFont(WA_MAX_PATH, fontFile);
|
||||
StringW defaultFont;
|
||||
defaultFont.own(fontPath);
|
||||
defaultFont.AppendPath(fontFile);
|
||||
// FREE(fontFile);
|
||||
StringW fs = defaultFont;
|
||||
wchar_t *p = wcschr(fs.getNonConstVal(), '.');
|
||||
if (p) *p = 0;
|
||||
PathParserW pp(fs);
|
||||
fs = pp.getLastString();
|
||||
f->setFontFace(fs);
|
||||
f->setFontId(id);
|
||||
// Open it and load it as the font resource.
|
||||
OSFILETYPE ff = WFOPEN(defaultFont, WF_READONLY_BINARY);
|
||||
if (ff != OPEN_FAILED) {
|
||||
if (f->addFontResource(ff, fs))
|
||||
{
|
||||
DebugStringW(L"font.cpp ====== FONT FOR ID=%s NOT FOUND. USING DEFAULT FONT FILE:\n%s\n", id, defaultFont);
|
||||
fontlist.addItem(f);
|
||||
}
|
||||
} else {
|
||||
DebugStringW(L"font.cpp ====== FONT FOR ID=%s NOT FOUND. CANNOT OPEN FONT FILE:\n%s\n", id, defaultFont);
|
||||
delete f;
|
||||
f = NULL;
|
||||
}
|
||||
} else {
|
||||
DebugString("font.cpp ====== CAN'T GET NEW FONT FILE.\n");
|
||||
delete f;
|
||||
f = NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
if (f == NULL) {
|
||||
// not found :((((( grab the default font data and use this, whatever it is
|
||||
f = newTrueTypeFont();
|
||||
if (f)
|
||||
{
|
||||
HDC dc = GetDC(GetDesktopWindow());
|
||||
HDC dc2 = CreateCompatibleDC(dc);
|
||||
SelectObject(dc2, GetStockObject(DEFAULT_GUI_FONT));
|
||||
|
||||
int datalen = GetFontData(dc2, 0, 0, NULL, 0);
|
||||
if (datalen > 0) {
|
||||
void *mem = WASABI_API_MEMMGR->sysMalloc(datalen+1); // freed by the service !!
|
||||
ASSERT(mem != NULL);
|
||||
GetFontData(dc2, 0, 0, mem, datalen);
|
||||
|
||||
f->setFontFace(id);
|
||||
f->setFontId(id);
|
||||
f->addFontResource2(mem, datalen, id);
|
||||
|
||||
ReleaseDC(GetDesktopWindow(), dc);
|
||||
DeleteDC(dc2);
|
||||
fontlist.addItem(f);
|
||||
return f;
|
||||
}
|
||||
delete f;
|
||||
f = NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#warning port me
|
||||
#endif
|
||||
|
||||
if (f == NULL) {
|
||||
// ok, NOW I'm getting pissed
|
||||
wchar_t fp[WA_MAX_PATH] = {0};
|
||||
Wasabi::Std::getFontPath(WA_MAX_PATH, fp);
|
||||
#ifdef _WIN32
|
||||
Wasabi::Std::messageBox(StringPrintfW(L"Fatal error trying to load truetype fonts.\n\nYou need arial.ttf at the very least, but it does not appear to be in %s", fp), L"Fatal Error", MB_ICONERROR);
|
||||
#else
|
||||
#warning port me
|
||||
#endif
|
||||
}
|
||||
|
||||
//if (f == NULL) DebugString("font.cpp ====== FALLBACK FOR FONT %s CANNOT BE FOUND IN OUR LISTS.\n",f->getFontId());
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Intelligently delete the font
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void Font::deleteFont(svc_font *f)
|
||||
{
|
||||
if (f)
|
||||
{
|
||||
if (f->isBitmap())
|
||||
{
|
||||
delete static_cast<BitmapFont *>(f); // we delete our own bitmap fonts.
|
||||
}
|
||||
else
|
||||
{
|
||||
SvcEnum::release(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Intelligently make a new truetype font from the service interfaces
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
svc_font *Font::newTrueTypeFont()
|
||||
{
|
||||
/*#ifdef WASABI_COMPILE_CONFIG
|
||||
const GUID options_guid =
|
||||
{ 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
|
||||
CfgItem *options = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
|
||||
#endif*/
|
||||
|
||||
svc_font *retval = NULL;
|
||||
const wchar_t *name = NULL;
|
||||
|
||||
#ifdef WASABI_COMPILE_CONFIG
|
||||
//const wchar_t *attr = L"Font Renderer";
|
||||
// First, try to find a font service that matches the attribute.
|
||||
// if (options) {
|
||||
// char buf[256]; // WHEEE for stack arrays
|
||||
// if (options->getData(attr, buf, sizeof buf)) {
|
||||
if (WASABI_API_SKIN->skin_getVersion() >= 1.3) // hardcode win32 renderer for v1.3+ skins
|
||||
retval = FontSvcEnum(L"Win32 TextOut").getFirst();
|
||||
else
|
||||
retval = FontSvcEnum(cfg_options_fontrenderer.getValue()).getFirst();
|
||||
|
||||
#else
|
||||
#ifndef WASABI_FONT_RENDERER
|
||||
#error You need to define WASABI_FONT_RENDERER (ie: #define WASABI_FONT_RENDERER "Freetype")
|
||||
#endif
|
||||
retval = FontSvcEnum(WASABI_FONT_RENDERER).getFirst();
|
||||
#endif
|
||||
#ifdef WASABI_COMPILE_CONFIG
|
||||
// }
|
||||
// }
|
||||
|
||||
// If we can't find one, fallback and just take the first.
|
||||
if (!retval)
|
||||
{
|
||||
retval = FontSvcEnum().getFirst();
|
||||
if (retval != NULL)
|
||||
name = retval->getFontSvcName();
|
||||
}
|
||||
|
||||
// If we had to fallback, remember the fallback service in the attribute.
|
||||
if (name/* && options*/)
|
||||
{
|
||||
//options->setData(attr, name);
|
||||
cfg_options_fontrenderer.setValue(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Test whether to forbid bitmap fonts.
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int Font::useTrueTypeOverride(const wchar_t *txt)
|
||||
|
||||
{
|
||||
if (cfg_options_no7bitsttfoverride.getValueAsInt())
|
||||
{
|
||||
const wchar_t *p = (const wchar_t *)txt;
|
||||
while (p && *p)
|
||||
{
|
||||
// TODO: benski> some characters above 127 can be handled by the bitmap fonts - it might be worth checking those explicitly
|
||||
if (*p & 0xFF80)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
if (!*p) return 0;
|
||||
}
|
||||
#ifdef WASABI_COMPILE_CONFIG
|
||||
/* // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
|
||||
const GUID options_guid =
|
||||
{ 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
|
||||
return !_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), "Use bitmap fonts (no international support)", 1);*/
|
||||
return !cfg_options_allowbitmapfonts.getValueAsInt();
|
||||
#else
|
||||
return WASABI_FONT_TTFOVERRIDE;
|
||||
#endif
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Get the font to be used to override bitmap fonts.
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
const wchar_t *Font::getTrueTypeOverride()
|
||||
{
|
||||
#ifdef WASABI_COMPILE_CONFIG
|
||||
return cfg_options_ttfoverridefont.getValue();
|
||||
#else
|
||||
return L"Arial";
|
||||
#warning TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
int Font::getTrueTypeOverrideScale()
|
||||
{
|
||||
#ifdef WASABI_COMPILE_CONFIG
|
||||
return cfg_options_ttfoverridescale.getValueAsInt();
|
||||
#else
|
||||
return 1;
|
||||
#warning TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Returns the font mapping for this font & skin, if font mapper is on and if there is a mapping, otherwise returns null
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
const wchar_t *Font::getFontMapping(const wchar_t *id, int *size)
|
||||
{
|
||||
if (cfg_options_usefontmapper.getValueAsInt())
|
||||
{
|
||||
wchar_t t[256]=L"";
|
||||
StringW tmp;
|
||||
tmp.printf(L"Skin:%s/Font Mapping/%s",WASABI_API_SKIN->getSkinName(), id);
|
||||
WASABI_API_CONFIG->getStringPrivate(tmp, t, 256, L"");
|
||||
|
||||
tmp.printf(L"Skin:%s/Font Mapping/%s_scale",WASABI_API_SKIN->getSkinName(), id);
|
||||
int v = WASABI_API_CONFIG->getIntPrivate(tmp, -1);
|
||||
if (!*t)
|
||||
{
|
||||
tmp.printf(L"Font Mapping/%s", id);
|
||||
WASABI_API_CONFIG->getStringPrivate(tmp, t, 256, L"");
|
||||
tmp.printf(L"Font Mapping/%s_scale", id);
|
||||
v = WASABI_API_CONFIG->getIntPrivate(tmp, -1);
|
||||
}
|
||||
mapping = t;
|
||||
if (mapping.isempty()) return NULL;
|
||||
if (size != NULL)
|
||||
{
|
||||
if (v != -1)
|
||||
{
|
||||
double f = (double)v / 100.0;
|
||||
*size = (int)((double)*size * f);
|
||||
}
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StringW Font::mapping;
|
55
Src/Wasabi/api/font/font.h
Normal file
55
Src/Wasabi/api/font/font.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef __FONT_H
|
||||
#define __FONT_H
|
||||
|
||||
#include <bfc/ptrlist.h>
|
||||
#include <bfc/string/StringW.h>
|
||||
|
||||
class ifc_canvas;
|
||||
class svc_font;
|
||||
class svc_fontMaker;
|
||||
|
||||
class FontDef {
|
||||
public:
|
||||
StringW filename;
|
||||
StringW path;
|
||||
StringW id;
|
||||
int allowmapping;
|
||||
int isbitmap;
|
||||
int scriptid;
|
||||
};
|
||||
|
||||
class Font {
|
||||
public:
|
||||
static void init();
|
||||
|
||||
static svc_font *installTrueTypeFont(const wchar_t *filename, const wchar_t *path, const wchar_t *id, int scriptid, int allowmapping, int isreload); // call this to install a new font
|
||||
static void installBitmapFont(const wchar_t *filename, const wchar_t *path, const wchar_t *id, int charwidth, int charheight, int hspacing, int vspacing, int scriptid, int allowmapping);
|
||||
static void uninstallAll(int isttfreload=0);
|
||||
static void uninstallByScriptId(int scriptid);
|
||||
|
||||
static svc_font *requestSkinFont(const wchar_t *id, int *size=NULL, int *gotdefault=NULL); // call this to get a Font pointer to a font id, pass your size if you have one, so that the mapper can do its job.
|
||||
static void dispatchTextOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt);
|
||||
static int dispatchGetInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h);
|
||||
|
||||
static int useTrueTypeOverride(const wchar_t *txt);
|
||||
static const wchar_t *getTrueTypeOverride();
|
||||
static int getTrueTypeOverrideScale();
|
||||
static int getNumFonts() { return fontlist.getNumItems(); }
|
||||
|
||||
static FontDef *enumFontDef(int n) { return fontdefs.enumItem(n); }
|
||||
static int getNumFontDefs() { return fontdefs.getNumItems(); }
|
||||
|
||||
static const wchar_t *getFontMapping(const wchar_t *id, int *size);
|
||||
|
||||
private:
|
||||
static void deleteFont(svc_font *font);
|
||||
static svc_font *newTrueTypeFont();
|
||||
|
||||
static PtrList<svc_font> fontlist;
|
||||
static PtrList<FontDef> fontdefs;
|
||||
StringW font_id;
|
||||
int scriptid;
|
||||
static StringW mapping;
|
||||
};
|
||||
|
||||
#endif
|
32
Src/Wasabi/api/font/fontapi.cpp
Normal file
32
Src/Wasabi/api/font/fontapi.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include <precomp.h>
|
||||
#include "fontapi.h"
|
||||
#include <api/font/font.h>
|
||||
|
||||
api_font *fontApi = NULL;
|
||||
|
||||
FontApi::FontApi()
|
||||
{
|
||||
Font::init();
|
||||
}
|
||||
|
||||
FontApi::~FontApi()
|
||||
{
|
||||
Font::uninstallAll();
|
||||
}
|
||||
|
||||
void FontApi::font_textOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt)
|
||||
{
|
||||
Font::dispatchTextOut(c, style, x, y, w, h, txt);
|
||||
}
|
||||
|
||||
int FontApi::font_getInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h)
|
||||
{
|
||||
return Font::dispatchGetInfo(c, font, infoid, txt, w, h);
|
||||
}
|
||||
|
||||
#define CBCLASS FontApi
|
||||
START_DISPATCH;
|
||||
VCB(API_FONT_FONT_TEXTOUT, font_textOut);
|
||||
CB(API_FONT_FONT_GETINFO, font_getInfo);
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
20
Src/Wasabi/api/font/fontapi.h
Normal file
20
Src/Wasabi/api/font/fontapi.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef __FONTAPI_H
|
||||
#define __FONTAPI_H
|
||||
|
||||
#include <api/font/api_font.h>
|
||||
|
||||
class FontApi : public api_font
|
||||
{
|
||||
public:
|
||||
FontApi();
|
||||
~FontApi();
|
||||
void font_textOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt);
|
||||
int font_getInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h);
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
extern api_font *fontApi;
|
||||
|
||||
#endif
|
472
Src/Wasabi/api/font/linux/truetypefont_linux.cpp
Normal file
472
Src/Wasabi/api/font/linux/truetypefont_linux.cpp
Normal file
@ -0,0 +1,472 @@
|
||||
// ============================================================================================================================================================
|
||||
// Font abstract class + statics to install TT fonts and Bitmap fonts
|
||||
// ============================================================================================================================================================
|
||||
|
||||
// what other linux headers need be made?
|
||||
|
||||
#include "truetypefont_linux.h"
|
||||
|
||||
#include <tataki/canvas/ifc_canvas.h>
|
||||
#include "../../bitmap.h"
|
||||
|
||||
// ============================================================================================================================================================
|
||||
// TrueTypeFont_Linux implementation.
|
||||
// ============================================================================================================================================================
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
TrueTypeFont_Linux::TrueTypeFont_Linux() {
|
||||
font = NULL;
|
||||
antialias_canvas = NULL;
|
||||
DColdstate = NULL;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
TrueTypeFont_Linux::~TrueTypeFont_Linux() {
|
||||
ASSERT(fontstack.isempty());
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Linux::isBitmap() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::addFontResource(FILE *in){
|
||||
ASSERT(in != NULL);
|
||||
OutputDebugString( "portme -- TrueTypeFont_Linux::addFontResource\n" );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::setFontFace(const char *face) {
|
||||
face_name = face;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
const char *TrueTypeFont_Linux::getFaceName() {
|
||||
return face_name;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::prepareCanvas(ifc_canvas *c, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor) {
|
||||
String fontname = StringPrintf( "-*-%s-%s-%s-*--%d-*-*-*-*-*-*-*",
|
||||
(const char *)face_name,
|
||||
bold?"bold":"medium",
|
||||
italic?"i":"r", size * 3/4 );
|
||||
font = XLoadQueryFont( Linux::getDisplay(), (const char *)fontname );
|
||||
if ( font == NULL ) {
|
||||
fontname = StringPrintf( "-*-arial-%s-%s-*--%d-*-*-*-*-*-*-*",
|
||||
bold?"bold":"medium",
|
||||
italic?"i":"r", size * 3/4 );
|
||||
font = XLoadQueryFont( Linux::getDisplay(), (const char *)fontname );
|
||||
|
||||
if ( font == NULL ) {
|
||||
fontname = StringPrintf( "-*-courier-%s-%s-*--%d-*-*-*-*-*-*-*",
|
||||
bold?"bold":"medium",
|
||||
italic?"i":"r", size * 3/4 );
|
||||
font = XLoadQueryFont( Linux::getDisplay(), (const char *)fontname );
|
||||
}
|
||||
}
|
||||
ASSERTPR( font != NULL, fontname );
|
||||
XSetFont( Linux::getDisplay(), c->getHDC()->gc, font->fid );
|
||||
XSetForeground( Linux::getDisplay(), c->getHDC()->gc, color );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::restoreCanvas(ifc_canvas *c) {
|
||||
if ( font != NULL ) {
|
||||
XFreeFont( Linux::getDisplay(), font );
|
||||
font = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
ifc_canvas *TrueTypeFont_Linux::prepareAntialias(ifc_canvas *c, int x, int y, const char *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int w, int h) {
|
||||
ASSERT(antialias_canvas == NULL);
|
||||
BaseCloneCanvas canvas(c);
|
||||
prepareCanvas(&canvas, size, bold, opaque, underline, italic, color, bkcolor);
|
||||
al_w = MAX(2,canvas.getTextWidth(txt) * 2 + xoffset*2);
|
||||
al_h = MAX(2,canvas.getTextHeight()*2 + yoffset*2);
|
||||
restoreCanvas(&canvas);
|
||||
if (w != -1) {
|
||||
al_w = w * 2;
|
||||
al_dw = w;
|
||||
} else al_dw = w;
|
||||
if (h != -1) {
|
||||
al_h = h * 2;
|
||||
al_dh = h;
|
||||
} else al_dh = h;
|
||||
al_mask=RGB(0,0,0);
|
||||
if (color == al_mask) al_mask=RGB(255,255,255);
|
||||
antialias_canvas = new BltCanvas(al_w, al_h);
|
||||
antialias_canvas->fillBits(0);
|
||||
prepareCanvas(antialias_canvas, size*2, bold, opaque, underline, italic, color, bkcolor);
|
||||
if (al_mask != 0) antialias_canvas->fillBits(al_mask);
|
||||
al_x = x; al_y = y; al_xo = xoffset; al_yo = yoffset;
|
||||
return antialias_canvas;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::completeAntialias(ifc_canvas *c) {
|
||||
BaseCloneCanvas canvas(c);
|
||||
antialias_canvas->maskColor(al_mask, RGB(0,0,0));
|
||||
BltCanvas *ac = new BltCanvas(al_w/2, al_h/2);
|
||||
antialias_canvas->antiAliasTo(ac, al_w/2, al_h/2, 2);
|
||||
SkinBitmap *b = ac->getSkinBitmap();
|
||||
RECT src={0,0,al_w/2,al_h/2};
|
||||
RECT dst={al_x+al_xo,al_y+al_yo,al_x+al_xo+al_dw,al_y+al_yo+al_dh};
|
||||
b->blitToRect(&canvas, &src, &dst);
|
||||
delete ac;
|
||||
restoreCanvas(antialias_canvas);
|
||||
delete antialias_canvas;
|
||||
antialias_canvas = NULL;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::textOut(ifc_canvas *c, int x, int y, const char *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
|
||||
if (antialiased) {
|
||||
ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, -1, -1);
|
||||
|
||||
HDC hdc = c->getHDC();
|
||||
XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, 0, 0, txt, STRLEN(txt) );
|
||||
|
||||
completeAntialias(c);
|
||||
} else {
|
||||
prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
|
||||
|
||||
int dir, ascent, descent;
|
||||
XCharStruct overall;
|
||||
XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
|
||||
|
||||
HDC hdc = c->getHDC();
|
||||
XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, x+xoffset, y+yoffset+ascent, txt, STRLEN(txt) );
|
||||
|
||||
|
||||
restoreCanvas(c);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::textOut(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
|
||||
if (antialiased) {
|
||||
ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, w, h);
|
||||
RECT al_r={0,0,w*2,h*2};
|
||||
|
||||
HDC hdc = c->getHDC();
|
||||
XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, al_r.left, al_r.top, txt, STRLEN(txt) );
|
||||
|
||||
completeAntialias(c);
|
||||
} else {
|
||||
RECT r;
|
||||
r.left = x+xoffset;
|
||||
r.top = y+yoffset;
|
||||
r.right = r.left + w;
|
||||
r.bottom = r.top + h;
|
||||
prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
|
||||
|
||||
int dir, ascent, descent;
|
||||
XCharStruct overall;
|
||||
XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
|
||||
int xstart = r.left;
|
||||
|
||||
if ( align == DT_RIGHT ) {
|
||||
int width = XTextWidth( font, txt, STRLEN( txt ) );
|
||||
xstart = r.right - width;
|
||||
|
||||
} else if ( align == DT_CENTER ) {
|
||||
int width = XTextWidth( font, txt, STRLEN( txt ) );
|
||||
xstart = (r.right + r.left - width) / 2;
|
||||
}
|
||||
|
||||
HDC hdc = c->getHDC();
|
||||
XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, xstart, r.top + ascent, txt, STRLEN(txt) );
|
||||
|
||||
restoreCanvas(c);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
|
||||
if (antialiased) {
|
||||
ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, w, h);
|
||||
RECT al_r={0,0,w*2,h*2};
|
||||
|
||||
OutputDebugString( "portme -- TrueTypeFont_Linux::textoutEllipsed (antialiased)\n" );
|
||||
|
||||
completeAntialias(c);
|
||||
} else {
|
||||
RECT r;
|
||||
r.left = x+xoffset;
|
||||
r.top = y+yoffset;
|
||||
r.right = r.left + w;
|
||||
r.bottom = r.top + h;
|
||||
prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
|
||||
|
||||
if ( txt == NULL )
|
||||
return;
|
||||
|
||||
int dir, ascent, descent;
|
||||
XCharStruct overall;
|
||||
XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
|
||||
|
||||
char *tmp = (char *)MALLOC( STRLEN( txt ) + 3 );
|
||||
STRCPY( tmp, txt );
|
||||
|
||||
if ( XTextWidth( font, tmp, STRLEN( tmp ) ) > r.right - r.left ) {
|
||||
int len = STRLEN( tmp );
|
||||
char *p = tmp + len;
|
||||
int width = r.right - r.left - XTextWidth( font, "...", 3 );
|
||||
while( XTextWidth( font, tmp, len ) > width ) {
|
||||
*p-- = '\0';
|
||||
len--;
|
||||
}
|
||||
STRCPY( p, "..." );
|
||||
}
|
||||
|
||||
HDC hdc = c->getHDC();
|
||||
XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, r.left, r.top + ascent, tmp, STRLEN(tmp) );
|
||||
|
||||
FREE( tmp );
|
||||
|
||||
restoreCanvas(c);
|
||||
}
|
||||
}
|
||||
|
||||
const char *find_break( int (*width_func)(void *, const char *, int ),
|
||||
void *f, const char *str, int width ) {
|
||||
const char *softret, *lastsoft, *hardret;
|
||||
|
||||
if ( width_func( f, str, STRLEN( str ) ) <= width )
|
||||
return str + STRLEN( str );
|
||||
|
||||
for( hardret = str; *hardret; hardret ++ )
|
||||
if ( *hardret == '\r' || *hardret == '\n' )
|
||||
break;
|
||||
|
||||
if ( hardret && width_func( f, str, hardret - str ) <= width ) {
|
||||
return hardret;
|
||||
}
|
||||
for( softret = str; *softret && !isspace( *softret ); softret++ )
|
||||
;
|
||||
|
||||
if ( width_func( f, str, softret - str ) <= width ) {
|
||||
do {
|
||||
lastsoft = softret;
|
||||
|
||||
for( softret = lastsoft+1; *softret && !isspace( *softret ); softret++ )
|
||||
;
|
||||
|
||||
} while ( *lastsoft && width_func( f, str, softret - str ) <= width );
|
||||
|
||||
softret = lastsoft;
|
||||
} else {
|
||||
for( softret = str; *softret; softret++ )
|
||||
if ( width_func( f, str, softret - str ) > width )
|
||||
break;
|
||||
|
||||
softret--;
|
||||
}
|
||||
|
||||
return softret;
|
||||
}
|
||||
|
||||
int xlib_width( void *data, const char *str, int len ) {
|
||||
return XTextWidth( (XFontStruct *)data, str, len );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
|
||||
if (antialiased) {
|
||||
ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, w, h);
|
||||
RECT al_r={0,0,w*2,h*2};
|
||||
|
||||
OutputDebugString( "portme -- TrueTypeFont_Linux::textoutWrapped (antialiased)\n" );
|
||||
|
||||
completeAntialias(c);
|
||||
} else {
|
||||
RECT r;
|
||||
r.left = x+xoffset;
|
||||
r.top = y+yoffset;
|
||||
r.right = r.left + w;
|
||||
r.bottom = r.top + h;
|
||||
prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
|
||||
|
||||
|
||||
int dir, ascent, descent;
|
||||
XCharStruct overall;
|
||||
XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
|
||||
HDC hdc = c->getHDC();
|
||||
|
||||
int yoff = r.top + ascent;
|
||||
const char *cur = txt, *next;
|
||||
int length = STRLEN( txt );
|
||||
for (int yoff = r.top + ascent; yoff < r.bottom - descent; yoff += ascent + descent) {
|
||||
next = find_break(xlib_width, font, cur, r.right - r.left);
|
||||
XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, r.left, yoff, cur, next - cur );
|
||||
for ( cur = next; *cur && isspace( *cur ); cur++ )
|
||||
;
|
||||
if ( cur >= txt + length )
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
restoreCanvas(c);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
|
||||
prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
|
||||
RECT r;
|
||||
char *ptr, *d;
|
||||
const char *s;
|
||||
ptr = (char *)MALLOC(STRLEN(txt)+1+4);
|
||||
for (s = txt, d = ptr; *s; s++, d++) {
|
||||
if (*s == '/') *d = '\\';
|
||||
else *d = *s;
|
||||
}
|
||||
r.left = x+xoffset;
|
||||
r.top = y+yoffset;
|
||||
r.right = r.left + w;
|
||||
r.bottom = r.top + getTextHeight(c, size, bold, underline, italic, antialiased);
|
||||
|
||||
OutputDebugString( "portme -- TrueTypeFont_Linux::textoutWrappedPathed\n" );
|
||||
|
||||
for (d = ptr; *d; d++) {
|
||||
if (*d == '\\') *d = '/';
|
||||
}
|
||||
|
||||
if (antialiased) {
|
||||
restoreCanvas(c);
|
||||
|
||||
ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, w, -1);
|
||||
RECT al_r={0,0,w*2,al_h};
|
||||
|
||||
OutputDebugString( "portme -- TrueTypeFont_Linux::textoutWrappedPathed (antialised)\n" );
|
||||
|
||||
completeAntialias(c);
|
||||
} else {
|
||||
int dir, ascent, descent;
|
||||
XCharStruct overall;
|
||||
XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
|
||||
|
||||
HDC hdc = c->getHDC();
|
||||
XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, r.left, r.top + ascent, txt, STRLEN(txt) );
|
||||
OutputDebugString( "portme -- TrueTypeFont_Linux::textoutWrappedPathed\n" );
|
||||
|
||||
restoreCanvas(c);
|
||||
}
|
||||
|
||||
FREE(ptr);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::textOutCentered(ifc_canvas *c, RECT *r, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
|
||||
ASSERT(r != NULL);
|
||||
ASSERT(txt != NULL);
|
||||
RECT rr=*r;
|
||||
rr.left += xoffset;
|
||||
rr.right += xoffset;
|
||||
rr.top += yoffset;
|
||||
rr.bottom += yoffset;
|
||||
|
||||
if (antialiased) {
|
||||
ifc_canvas *canvas = prepareAntialias(c, r->left, r->top, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, r->right-r->left, r->bottom-r->top);
|
||||
RECT al_r={0,0,(r->right-r->left)*2,(r->bottom-r->top)*2};
|
||||
|
||||
OutputDebugString( "portme -- TrueTypeFont_Linux::textoutCentered (antialiased)\n" );
|
||||
|
||||
completeAntialias(c);
|
||||
} else {
|
||||
prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
|
||||
|
||||
int dir, ascent, descent, width;
|
||||
XCharStruct overall;
|
||||
XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
|
||||
width = XTextWidth( font, txt, STRLEN( txt ) );
|
||||
|
||||
HDC hdc = c->getHDC();
|
||||
XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, (rr.right + rr.left - width) / 2, rr.top + ascent, txt, STRLEN(txt) );
|
||||
|
||||
restoreCanvas(c);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Linux::getTextWidth(ifc_canvas *c, const char *text, int size, int bold, int underline, int italic, int antialiased) {
|
||||
int w;
|
||||
getTextExtent(c, text, &w, NULL, size, bold, underline, italic, antialiased);
|
||||
return w;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Linux::getTextHeight(ifc_canvas *c, const char *text, int size, int bold, int underline, int italic, int antialiased) {
|
||||
int h;
|
||||
getTextExtent(c, text, NULL, &h, size, bold, underline, italic, antialiased);
|
||||
{
|
||||
// calcul for multiline text
|
||||
const char *p=text;
|
||||
int n=0;
|
||||
while(*p!=0) if(*p++=='\n') n++;
|
||||
if(n) h*=(n+1);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Linux::getTextExtent(ifc_canvas *c, const char *txt, int *w, int *h, int size, int bold, int underline, int italic, int antialiased) {
|
||||
SIZE rsize={0,0};
|
||||
ASSERT(txt != NULL);
|
||||
if (*txt == 0) {
|
||||
if (w != NULL) *w = 0;
|
||||
if (h != NULL) *h = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (antialiased)
|
||||
prepareCanvas(c, size*2, bold, 0, underline, italic, 0, 0);
|
||||
else
|
||||
prepareCanvas(c, size, bold, 0, underline, italic, 0, 0);
|
||||
|
||||
int dir, ascent, descent;
|
||||
XCharStruct overall;
|
||||
XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
|
||||
rsize.cy = ascent + descent;
|
||||
rsize.cx = XTextWidth( font, txt, STRLEN( txt ) );
|
||||
|
||||
if (w != NULL) *w = rsize.cx;
|
||||
if (h != NULL) *h = rsize.cy;
|
||||
|
||||
if (antialiased) {
|
||||
if (w != NULL) *w /= 2;
|
||||
if (h != NULL) *h /= 2;
|
||||
}
|
||||
|
||||
restoreCanvas(c);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Linux::getTextHeight(ifc_canvas *c, int size, int bold, int underline, int italic, int antialiased) {
|
||||
return getTextHeight(c, "My", size, bold, underline, italic, antialiased);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// code from ftp.microsoft.com/Softlib/MSLFILES/FONTINST.EXE
|
||||
// retrieves the friendly font name from its filename
|
||||
char *TrueTypeFont_Linux::filenameToFontFace(const char *pszFile) {
|
||||
static char lpszLongName[256];
|
||||
unsigned i;
|
||||
char namebuf[255];
|
||||
int fp;
|
||||
unsigned short numNames;
|
||||
long curseek;
|
||||
unsigned cTables;
|
||||
sfnt_OffsetTable OffsetTable;
|
||||
sfnt_DirectoryEntry Table;
|
||||
sfnt_NamingTable NamingTable;
|
||||
sfnt_NameRecord NameRecord;
|
||||
|
||||
OutputDebugString( "portme -- TrueTypeFont_Linux::filenameToFontFace\n" );
|
||||
|
||||
return FALSE;
|
||||
}
|
65
Src/Wasabi/api/font/linux/truetypefont_linux.h
Normal file
65
Src/Wasabi/api/font/linux/truetypefont_linux.h
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef __TRUETYPEFONT_LINUX_H
|
||||
#define __TRUETYPEFONT_LINUX_H
|
||||
|
||||
#include "../../../studio/services/svc_font.h"
|
||||
|
||||
#include "../../string.h"
|
||||
#include "../../stack.h"
|
||||
#include "../truetypefontdef.h"
|
||||
|
||||
class ifc_canvas;
|
||||
class BltCanvas;
|
||||
|
||||
class TrueTypeFont_Linux : public svc_fontI {
|
||||
public:
|
||||
TrueTypeFont_Linux();
|
||||
virtual ~TrueTypeFont_Linux();
|
||||
|
||||
virtual void textOut(ifc_canvas *c, int x, int y, const char *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void textOut2(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void textOutCentered(ifc_canvas *c, RECT *r, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual int getTextWidth(ifc_canvas *c, const char *text, int size, int bold, int underline, int italic, int antialias);
|
||||
virtual int getTextHeight(ifc_canvas *c, const char *text, int size, int bold, int underline, int italic, int antialias);
|
||||
virtual int getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialias);
|
||||
virtual void getTextExtent(ifc_canvas *c, const char *text, int *w, int *h, int size, int bold, int underline, int italic, int antialias);
|
||||
|
||||
virtual void setFontId(const char *id) { font_id = id; }
|
||||
virtual const char *getFontId() { return font_id; }
|
||||
virtual int getScriptId() { return scriptid; }
|
||||
virtual void setScriptId(int id) { scriptid = id; }
|
||||
|
||||
virtual int isBitmap();
|
||||
virtual void setFontFace(const char *face);
|
||||
virtual int addFontResource(FILE *f);
|
||||
virtual const char *getFaceName();
|
||||
|
||||
virtual const wchar_t *getFontSvcName() { return "Linux"; }
|
||||
static const char *getServiceName() { return "Linux font renderer"; }
|
||||
|
||||
protected:
|
||||
static char *filenameToFontFace(const wchar_t *filename);
|
||||
void prepareCanvas(ifc_canvas *c, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor);
|
||||
void restoreCanvas(ifc_canvas *c);
|
||||
|
||||
protected:
|
||||
String font_id;
|
||||
int scriptid;
|
||||
|
||||
private:
|
||||
ifc_canvas *prepareAntialias(ifc_canvas *c, int x, int y, const char *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int w, int h);
|
||||
void completeAntialias(ifc_canvas *c);
|
||||
|
||||
String face_name;
|
||||
String tmpfilename;
|
||||
int DColdstate;
|
||||
XFontStruct *font;
|
||||
Stack<fontslot*> fontstack;
|
||||
BltCanvas *antialias_canvas;
|
||||
int al_w, al_h, al_x, al_y, al_xo, al_yo, al_dw, al_dh;
|
||||
COLORREF al_mask;
|
||||
};
|
||||
|
||||
#endif
|
43
Src/Wasabi/api/font/skinfont.cpp
Normal file
43
Src/Wasabi/api/font/skinfont.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "precomp.h"
|
||||
#include "skinfont.h"
|
||||
#include "api.h"
|
||||
#include "../bfc/std.h"
|
||||
|
||||
SkinFont::SkinFont() {
|
||||
}
|
||||
|
||||
SkinFont::~SkinFont() {
|
||||
if (!tempFn.isempty()) {
|
||||
#ifdef WIN32
|
||||
RemoveFontResource(tempFn);
|
||||
#else
|
||||
DebugString( "portme -- SkinFont::~SkinFont\n" );
|
||||
#endif
|
||||
UNLINK(tempFn);
|
||||
}
|
||||
}
|
||||
|
||||
int SkinFont::setXmlOption(const char *paramname, const char *strvalue) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SkinFont::installFont(OSFNSTR filename, OSFNSTR path) {
|
||||
FILE *in,*out;
|
||||
StringPrintf temp("%s%s", path, filename);
|
||||
in = WFOPEN(temp, L"rb");
|
||||
if (!in) return;
|
||||
int len = FGETSIZE(in);
|
||||
MemBlock<char> m(len);
|
||||
FREAD(m.getMemory(), len, 1, in);
|
||||
tempFn = TMPNAM(NULL);
|
||||
out = FOPEN(tempFn, "wb");
|
||||
ASSERT(out);
|
||||
FWRITE(m.getMemory(), len, 1, out);
|
||||
FCLOSE(out);
|
||||
FCLOSE(in);
|
||||
#ifdef WIN32
|
||||
AddFontResource(tempFn);
|
||||
#else
|
||||
DebugString( "portme -- SkinFont::installFont\n" );
|
||||
#endif
|
||||
}
|
17
Src/Wasabi/api/font/skinfont.h
Normal file
17
Src/Wasabi/api/font/skinfont.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _SKINFONT_H
|
||||
#define _SKINFONT_H
|
||||
|
||||
#include <api/skin/xmlobject.h>
|
||||
|
||||
class SkinFont : public XmlObjectI
|
||||
{
|
||||
public:
|
||||
SkinFont();
|
||||
~SkinFont();
|
||||
void installFont(const wchar_t *filename, const wchar_t *path);
|
||||
virtual int setXmlOption(const wchar_t *name, const wchar_t *val);
|
||||
private:
|
||||
StringW tempFn;
|
||||
};
|
||||
|
||||
#endif
|
39
Src/Wasabi/api/font/svc_fontI.h
Normal file
39
Src/Wasabi/api/font/svc_fontI.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef NULLSOFT_WASABI_SVC_FONTI_H
|
||||
#define NULLSOFT_WASABI_SVC_FONTI_H
|
||||
|
||||
#include <api/service/svcs/svc_font.h>
|
||||
//#include <tataki/canvas/canvas.h>
|
||||
class ifc_canvas;
|
||||
// implementor derives from this one
|
||||
class NOVTABLE svc_fontI : public svc_font {
|
||||
public:
|
||||
|
||||
virtual void 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 antialias)=0; // abstract interface
|
||||
virtual void 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 antialias)=0;
|
||||
virtual void 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 antialias)=0;
|
||||
virtual void 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 antialias)=0;
|
||||
virtual void 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 antialias)=0;
|
||||
virtual void 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 antialias)=0;
|
||||
virtual int getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias)=0;
|
||||
virtual int getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias)=0;
|
||||
virtual int getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialias)=0;
|
||||
virtual void getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialias)=0;
|
||||
|
||||
virtual void setFontId(const wchar_t *id)=0;
|
||||
virtual const wchar_t *getFontId()=0;
|
||||
virtual const wchar_t *getFaceName()=0;
|
||||
virtual int isBitmap()=0;
|
||||
virtual int getScriptId()=0;
|
||||
virtual void setScriptId(int id)=0;
|
||||
|
||||
virtual void setFontFace(const wchar_t *face)=0;
|
||||
virtual int addFontResource(OSFILETYPE f, const wchar_t *name)=0;
|
||||
virtual int addFontResource2(void *mem, int datalen, const wchar_t *name)=0;
|
||||
|
||||
virtual const wchar_t * getFontSvcName()=0;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
#endif
|
56
Src/Wasabi/api/font/truetypefontdef.h
Normal file
56
Src/Wasabi/api/font/truetypefontdef.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef __TRUETYPEFONTDEF_H
|
||||
#define __TRUETYPEFONTDEF_H
|
||||
|
||||
// Macros for TrueType portability
|
||||
#define FS_2BYTE(p) ( ((unsigned short)((p)[0]) << 8) | (p)[1])
|
||||
#define FS_4BYTE(p) ( FS_2BYTE((p)+2) | ( (FS_2BYTE(p)+0L) << 16) )
|
||||
#define SWAPW(a) ((short) FS_2BYTE( (unsigned char FAR*)(&a) ))
|
||||
#define SWAPL(a) ((long) FS_4BYTE( (unsigned char FAR*)(&a) ))
|
||||
|
||||
typedef short int16;
|
||||
typedef unsigned short uint16;
|
||||
typedef long int32;
|
||||
typedef unsigned long uint32;
|
||||
typedef long sfnt_TableTag;
|
||||
|
||||
typedef struct {
|
||||
uint16 platformID;
|
||||
uint16 specificID;
|
||||
uint16 languageID;
|
||||
uint16 nameID;
|
||||
uint16 length;
|
||||
uint16 offset;
|
||||
} sfnt_NameRecord;
|
||||
|
||||
typedef struct {
|
||||
uint16 format;
|
||||
uint16 count;
|
||||
uint16 stringOffset;
|
||||
} sfnt_NamingTable;
|
||||
|
||||
typedef struct {
|
||||
sfnt_TableTag tag;
|
||||
uint32 checkSum;
|
||||
uint32 offset;
|
||||
uint32 length;
|
||||
} sfnt_DirectoryEntry;
|
||||
|
||||
typedef struct {
|
||||
int32 version;
|
||||
uint16 numOffsets;
|
||||
uint16 searchRange;
|
||||
uint16 entrySelector;
|
||||
uint16 rangeShift;
|
||||
sfnt_DirectoryEntry table[1];
|
||||
} sfnt_OffsetTable;
|
||||
#define OFFSETTABLESIZE 12
|
||||
|
||||
typedef struct {
|
||||
int dcstate;
|
||||
HFONT font;
|
||||
HFONT prevfont;
|
||||
} fontslot;
|
||||
|
||||
#define tag_NamingTable 0x656d616e /* 'name' */
|
||||
|
||||
#endif
|
561
Src/Wasabi/api/font/win32/truetypefont_win32.cpp
Normal file
561
Src/Wasabi/api/font/win32/truetypefont_win32.cpp
Normal file
@ -0,0 +1,561 @@
|
||||
#include "precomp.h"
|
||||
// ============================================================================================================================================================
|
||||
// Font abstract class + statics to install TT fonts and Bitmap fonts
|
||||
// ============================================================================================================================================================
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <fcntl.h>
|
||||
#include "../nu/ns_wc.h"
|
||||
#include "truetypefont_win32.h"
|
||||
|
||||
#include <tataki/canvas/bltcanvas.h>
|
||||
#include <tataki/bitmap/bitmap.h>
|
||||
#include <bfc/file/tmpnamestr.h>
|
||||
#include <api/memmgr/api_memmgr.h>
|
||||
#if UTF8
|
||||
#ifdef WANT_UTF8_WARNINGS
|
||||
#pragma CHAT("mig", "all", "UTF8 is enabled in std.cpp -- Things might be screwy till it's all debugged?")
|
||||
#endif
|
||||
# include <bfc/string/encodedstr.h>
|
||||
#endif
|
||||
#define VERTICAL_LPADDING 0
|
||||
#define VERTICAL_RPADDING 2
|
||||
#define VERTICAL_TPADDING 1
|
||||
#define VERTICAL_BPADDING 1
|
||||
|
||||
/** ============================================================================================================================================================
|
||||
** TrueTypeFont_Win32 implementation.
|
||||
**
|
||||
** TODO:
|
||||
** use GDI transformation to draw in 72 DPI
|
||||
** fractional point sizes?
|
||||
** ===========================================================================================================================================================
|
||||
*/
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
TrueTypeFont_Win32::TrueTypeFont_Win32()
|
||||
{
|
||||
scriptid = 0;
|
||||
font = oldFont = NULL;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
TrueTypeFont_Win32::~TrueTypeFont_Win32()
|
||||
{
|
||||
if (!tmpfilename.isempty())
|
||||
{
|
||||
RemoveFontResourceW(tmpfilename);
|
||||
// explict call to this instead of UNLINK allows correct removal of the temp files
|
||||
_wunlink(tmpfilename);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Win32::isBitmap()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Win32::addFontResource(OSFILETYPE in, const wchar_t *name)
|
||||
{
|
||||
ASSERT(in != NULL);
|
||||
|
||||
int len = (int)FGETSIZE(in);
|
||||
OSFILETYPE out;
|
||||
char *m = (char *)MALLOC(len);
|
||||
ASSERT(m != NULL);
|
||||
FREAD(m, len, 1, in);
|
||||
TmpNameStrW tempfn;
|
||||
out = WFOPEN(tempfn, L"wb");
|
||||
ASSERT(out != OPEN_FAILED);
|
||||
FWRITE(m, len, 1, out);
|
||||
FCLOSE(out);
|
||||
AddFontResourceW(tempfn);
|
||||
FREE(m);
|
||||
tmpfilename = tempfn;
|
||||
setFontFace(filenameToFontFace(tempfn));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Win32::addFontResource2(void *data, int datalen, const wchar_t *name)
|
||||
{
|
||||
TmpNameStrW tempfn;
|
||||
OSFILETYPE out = WFOPEN(tempfn, L"wb");
|
||||
ASSERT(out != OPEN_FAILED);
|
||||
FWRITE(data, datalen, 1, out);
|
||||
FCLOSE(out);
|
||||
AddFontResourceW(tempfn);
|
||||
tmpfilename = tempfn;
|
||||
setFontFace(filenameToFontFace(tempfn));
|
||||
|
||||
WASABI_API_MEMMGR->sysFree(data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::setFontFace(const wchar_t *face)
|
||||
{
|
||||
face_name = face;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
const wchar_t *TrueTypeFont_Win32::getFaceName()
|
||||
{
|
||||
return face_name;
|
||||
}
|
||||
|
||||
static int IsXp_or_higher()
|
||||
{
|
||||
static int checked=0;
|
||||
static int isXp=0;
|
||||
if (!checked)
|
||||
{
|
||||
OSVERSIONINFO osver;
|
||||
osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
|
||||
isXp = ( ::GetVersionEx(&osver) && osver.dwPlatformId == VER_PLATFORM_WIN32_NT && (osver.dwMajorVersion >= 5 )) ? 1 : 0;
|
||||
checked=1;
|
||||
}
|
||||
return isXp;
|
||||
}
|
||||
|
||||
#ifndef CLEARTYPE_QUALITY
|
||||
#define CLEARTYPE_QUALITY 5
|
||||
#endif
|
||||
HFONT TrueTypeFont_Win32::MakeFont(int size, int bold, int underline, int italic, int antialiased)
|
||||
{
|
||||
// TODO: we got the height to be in 72 DPI, but how can we get the width???
|
||||
int nHeight = MulDiv(size, 72, 96); // this is lame, but we have to do it to match freetype
|
||||
|
||||
int quality;
|
||||
if (antialiased)
|
||||
{
|
||||
if (IsXp_or_higher())
|
||||
quality=CLEARTYPE_QUALITY;
|
||||
else
|
||||
quality=ANTIALIASED_QUALITY;
|
||||
}
|
||||
else
|
||||
quality=NONANTIALIASED_QUALITY;
|
||||
|
||||
return CreateFontW(-nHeight, 0, 0, 0, bold ? FW_BOLD : FW_NORMAL,
|
||||
italic, underline, FALSE, DEFAULT_CHARSET,
|
||||
OUT_TT_ONLY_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
quality,
|
||||
DEFAULT_PITCH | FF_DONTCARE, face_name);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::prepareCanvas(BltCanvas *canvas, int size, int bold, int opaque, int underline, int italic, int antialiased)
|
||||
{
|
||||
HDC canvasHDC = canvas->getHDC();
|
||||
|
||||
font = MakeFont(size, bold, underline, italic, antialiased);
|
||||
oldFont = (HFONT)SelectObject(canvasHDC, font);
|
||||
|
||||
SetBkColor(canvasHDC, RGB(0, 0, 0));
|
||||
//SetBkMode(canvasHDC, TRANSPARENT);
|
||||
SetTextColor(canvasHDC, RGB(255, 255, 255));
|
||||
}
|
||||
|
||||
typedef DWORD ARGB;
|
||||
|
||||
#define MIN_TONE 100.0
|
||||
//BYTE min = 255, max=0;
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::restoreCanvas(BltCanvas *canvas, ifc_canvas *dest, int w, int h, COLORREF color, COLORREF bkcolor, int antialiased, int _x, int _y)
|
||||
{
|
||||
#ifndef FE_FONTSMOOTHINGCLEARTYPE
|
||||
#define FE_FONTSMOOTHINGCLEARTYPE 0x0002
|
||||
#endif
|
||||
|
||||
#ifndef SPI_GETFONTSMOOTHINGTYPE
|
||||
#define SPI_GETFONTSMOOTHINGTYPE 0x200A
|
||||
#endif
|
||||
|
||||
bool clearType = false;
|
||||
UINT fontSmoothing;
|
||||
if (antialiased && SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &fontSmoothing, 0))
|
||||
clearType = fontSmoothing == FE_FONTSMOOTHINGCLEARTYPE;
|
||||
|
||||
ARGB32 *buf = static_cast<ARGB32 *>(canvas->getBits());
|
||||
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
int linewidth = y * w;
|
||||
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
|
||||
ARGB32* prgb = &buf[linewidth + x];
|
||||
unsigned char *pixel = (unsigned char *)prgb;
|
||||
if (*prgb == 0)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE alpha = 255;
|
||||
BYTE rAlpha = 255;
|
||||
BYTE gAlpha = 255;
|
||||
BYTE bAlpha = 255;
|
||||
|
||||
if (*prgb != 0xFFFFFF)
|
||||
{
|
||||
if (clearType)
|
||||
{
|
||||
rAlpha = pixel[2];
|
||||
gAlpha = pixel[1];
|
||||
bAlpha = pixel[0];
|
||||
}
|
||||
|
||||
UINT value = pixel[0] + pixel[1] + pixel[2];
|
||||
value = value / 3;
|
||||
alpha = (BYTE)value;
|
||||
|
||||
if (!clearType)
|
||||
{
|
||||
rAlpha = alpha;
|
||||
gAlpha = alpha;
|
||||
bAlpha = alpha;
|
||||
}
|
||||
|
||||
//alpha=pixel[0];
|
||||
//alpha = (((float)pixel[0] - MIN_TONE) / (255.0 - MIN_TONE)) * 255 ;
|
||||
|
||||
//min = (min > value) ? value : min;
|
||||
//max = (max < value) ? value : max;
|
||||
}
|
||||
|
||||
pixel[3] = (BYTE)alpha;
|
||||
pixel[2] = ((GetRValue(color) * rAlpha) + 128) / 255;
|
||||
pixel[1] = ((GetGValue(color) * gAlpha) + 128) / 255;
|
||||
pixel[0] = ((GetBValue(color) * bAlpha) + 128) / 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
canvas->blitAlpha(dest, _x + VERTICAL_LPADDING, _y + VERTICAL_TPADDING);
|
||||
//SkinBitmap *bitmap = canvas->getSkinBitmap();
|
||||
//bitmap->blitAlpha(dest, _x + VERTICAL_LPADDING, _y + VERTICAL_TPADDING);
|
||||
|
||||
SelectObject(canvas->getHDC(), oldFont);
|
||||
oldFont = 0;
|
||||
DeleteObject(font);
|
||||
font = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
|
||||
{
|
||||
int w, h;
|
||||
c->getDim(&w, &h);
|
||||
|
||||
if (!h || !w) return;
|
||||
|
||||
BltCanvas canvas;
|
||||
prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
|
||||
canvas.DestructiveResize(w, h);
|
||||
|
||||
TextOutW(canvas.getHDC(), x + xoffset, y + yoffset, txt, wcslen(txt));
|
||||
|
||||
restoreCanvas(&canvas, c, w, h, color, bkcolor, antialiased);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::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, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
|
||||
{
|
||||
if (!h || !w) return;
|
||||
|
||||
BltCanvas canvas;
|
||||
prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
|
||||
canvas.DestructiveResize(/*x +*/ w, /*y +*/ h);
|
||||
|
||||
RECT r = {
|
||||
/*x +*/ xoffset,
|
||||
/*y + */yoffset,
|
||||
/*x + */w,
|
||||
/*y + */h
|
||||
};
|
||||
|
||||
DrawTextW(canvas.getHDC(), txt, -1, &r, align | DT_NOPREFIX | DT_NOCLIP);
|
||||
|
||||
restoreCanvas(&canvas, c, /*x + */w, /*y + */h, color, bkcolor, antialiased, x, y);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::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, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
|
||||
{
|
||||
if (!h || !w) return;
|
||||
|
||||
BltCanvas canvas;
|
||||
prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
|
||||
canvas.DestructiveResize(/*x + */w, /*y + */h);
|
||||
|
||||
RECT r = {
|
||||
/*x + */xoffset,
|
||||
/*y + */yoffset,
|
||||
/*x + */w,
|
||||
/*y + */ h
|
||||
};
|
||||
|
||||
DrawTextW(canvas.getHDC(), txt, -1, &r, align | DT_NOPREFIX | DT_END_ELLIPSIS | DT_NOCLIP);
|
||||
restoreCanvas(&canvas, c,/* x + */w, /*y + */h, color, bkcolor, antialiased, x, y);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::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, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
|
||||
{
|
||||
if (!h || !w) return;
|
||||
|
||||
BltCanvas canvas;
|
||||
prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
|
||||
canvas.DestructiveResize(w, h);
|
||||
|
||||
RECT r;
|
||||
r.left = x + xoffset;
|
||||
r.top = y + yoffset;
|
||||
r.right = r.left + w;
|
||||
r.bottom = r.top + h;
|
||||
|
||||
DrawTextW(canvas.getHDC(), txt, -1, &r, align | DT_NOPREFIX | DT_WORDBREAK);
|
||||
|
||||
restoreCanvas(&canvas, c, w, h, color, bkcolor, antialiased);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::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, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
|
||||
{
|
||||
int w_dummy, h;
|
||||
c->getDim(&w_dummy, &h);
|
||||
|
||||
if (!h || !w) return;
|
||||
|
||||
BltCanvas canvas;
|
||||
prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
|
||||
canvas.DestructiveResize(w, h);
|
||||
|
||||
RECT r;
|
||||
wchar_t *ptr, *d;
|
||||
const wchar_t *s;
|
||||
ptr = (wchar_t *)MALLOC(sizeof(wchar_t) * (wcslen(txt) + 1 + 4));
|
||||
for (s = txt, d = ptr; *s; s++, d++)
|
||||
{
|
||||
if (*s == '/') *d = '\\';
|
||||
else *d = *s;
|
||||
}
|
||||
r.left = x + xoffset;
|
||||
r.top = y + yoffset;
|
||||
r.right = r.left + w;
|
||||
r.bottom = r.top + getTextHeight2(c, size, bold, underline, italic, antialiased);
|
||||
|
||||
DrawTextW(canvas.getHDC(), ptr, -1, &r, align | DT_NOPREFIX | DT_PATH_ELLIPSIS | DT_SINGLELINE | DT_MODIFYSTRING | DT_CALCRECT);
|
||||
|
||||
for (d = ptr; *d; d++)
|
||||
{
|
||||
if (*d == '\\') *d = '/';
|
||||
}
|
||||
|
||||
DrawTextW(canvas.getHDC(), ptr, -1, &r, align | DT_NOPREFIX | DT_PATH_ELLIPSIS | DT_SINGLELINE);
|
||||
restoreCanvas(&canvas, c, w, h, color, bkcolor, antialiased);
|
||||
|
||||
FREE(ptr);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
|
||||
{
|
||||
yoffset += 1;
|
||||
ASSERT(r != NULL);
|
||||
ASSERT(txt != NULL);
|
||||
RECT rr = *r;
|
||||
rr.left += xoffset;
|
||||
rr.right += xoffset;
|
||||
rr.top += yoffset;
|
||||
rr.bottom += yoffset;
|
||||
|
||||
int w = rr.right - rr.left;
|
||||
int h = rr.bottom - rr.top;
|
||||
|
||||
RECT r2 = {0, 0, w, h};
|
||||
|
||||
BltCanvas canvas;
|
||||
prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
|
||||
canvas.DestructiveResize(w, h);
|
||||
|
||||
DrawTextW(canvas.getHDC(), txt, -1, &r2, align | DT_CENTER | /*DT_VCENTER | */DT_NOPREFIX | DT_WORDBREAK | DT_SINGLELINE);
|
||||
|
||||
restoreCanvas(&canvas, c, w, h, color, bkcolor, antialiased, rr.left, rr.top);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Win32::getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased)
|
||||
{
|
||||
int w = 0;
|
||||
getTextExtent(c, text, &w, NULL, size, bold, underline, italic, antialiased);
|
||||
return w;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Win32::getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased)
|
||||
{
|
||||
int h = 0;
|
||||
getTextExtent(c, text, NULL, &h, size, bold, underline, italic, antialiased);
|
||||
{
|
||||
// calcul for multiline text
|
||||
const wchar_t *p = text;
|
||||
int n = 0;
|
||||
while (p && *p != 0) if (*p++ == '\n') n++;
|
||||
if (n) h *= (n + 1);
|
||||
}
|
||||
return h ;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void TrueTypeFont_Win32::getTextExtent(ifc_canvas *c, const wchar_t *txt, int *w, int *h, int size, int bold, int underline, int italic, int antialiased)
|
||||
{
|
||||
SIZE rsize = {0, 0};
|
||||
ASSERT(txt != NULL);
|
||||
if (*txt == 0)
|
||||
{
|
||||
if (w != NULL) *w = 0;
|
||||
if (h != NULL) *h = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
HFONT newFont = MakeFont(size, bold, underline, italic, antialiased);
|
||||
HFONT theOldFont = (HFONT)SelectObject(c->getHDC(), newFont);
|
||||
GetTextExtentPoint32W(c->getHDC(), txt, wcslen(txt), &rsize);
|
||||
|
||||
SelectObject(c->getHDC(), theOldFont);
|
||||
DeleteObject(newFont);
|
||||
|
||||
if (w != NULL) *w = rsize.cx + VERTICAL_LPADDING + VERTICAL_RPADDING;
|
||||
if (h != NULL) *h = rsize.cy + VERTICAL_TPADDING + VERTICAL_BPADDING;
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
int TrueTypeFont_Win32::getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialiased)
|
||||
{
|
||||
return getTextHeight(c, L"Mg", size, bold, underline, italic, antialiased);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// code from ftp.microsoft.com/Softlib/MSLFILES/FONTINST.EXE
|
||||
// retrieves the friendly font name from its filename
|
||||
wchar_t *TrueTypeFont_Win32::filenameToFontFace(const wchar_t *pszFile)
|
||||
{
|
||||
static wchar_t lpszLongName[256];
|
||||
unsigned i;
|
||||
char namebuf[255] = {0};
|
||||
int fp;
|
||||
unsigned short numNames;
|
||||
long curseek;
|
||||
unsigned cTables;
|
||||
sfnt_OffsetTable OffsetTable;
|
||||
sfnt_DirectoryEntry Table;
|
||||
sfnt_NamingTable NamingTable;
|
||||
sfnt_NameRecord NameRecord;
|
||||
|
||||
|
||||
lpszLongName[0] = '\0';
|
||||
if ((fp = _wopen(pszFile, O_RDONLY | O_BINARY)) == -1)
|
||||
return NULL;
|
||||
|
||||
/* First off, read the initial directory header on the TTF. We're only
|
||||
* interested in the "numOffsets" variable to tell us how many tables
|
||||
* are present in this file.
|
||||
*
|
||||
* Remember to always convert from Motorola format (Big Endian to
|
||||
* Little Endian).
|
||||
*/
|
||||
_read(fp, &OffsetTable, sizeof(OffsetTable) - sizeof
|
||||
(sfnt_DirectoryEntry));
|
||||
cTables = (int) SWAPW(OffsetTable.numOffsets);
|
||||
|
||||
for (i = 0; i < cTables && i < 40; i++)
|
||||
{
|
||||
if ((read(fp, &Table, sizeof(Table))) != sizeof(Table)) return NULL;
|
||||
if (Table.tag == tag_NamingTable) /* defined in sfnt_en.h */ {
|
||||
/* Now that we've found the entry for the name table, seek to that * position in the file and read in the initial header for this * particular table. See "True Type Font Files" for information * on this record layout.
|
||||
*/
|
||||
lseek(fp, SWAPL(Table.offset), SEEK_SET);
|
||||
read(fp, &NamingTable, sizeof(NamingTable));
|
||||
numNames = SWAPW(NamingTable.count);
|
||||
while (numNames--)
|
||||
{
|
||||
read(fp, &NameRecord, sizeof(NameRecord));
|
||||
curseek = tell(fp);
|
||||
if (SWAPW(NameRecord.platformID) == 1 &&
|
||||
SWAPW(NameRecord.nameID) == 4)
|
||||
{
|
||||
lseek(fp, SWAPW(NameRecord.offset) +
|
||||
SWAPW(NamingTable.stringOffset) +
|
||||
SWAPL(Table.offset), SEEK_SET);
|
||||
read(fp, &namebuf, MIN(255, (int)SWAPW(NameRecord.length)));
|
||||
namebuf[MIN(255, (int)SWAPW(NameRecord.length))] = '\0';
|
||||
MultiByteToWideCharSZ(1252, 0, namebuf, -1, lpszLongName, 256); // TODO: benski> what codepage is TTF using internally?
|
||||
//CUT: lstrcpy(lpszLongName, namebuf);
|
||||
lseek(fp, curseek, SEEK_SET);
|
||||
}
|
||||
}
|
||||
close(fp);
|
||||
return lpszLongName;
|
||||
}
|
||||
}
|
||||
close(fp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TODO:
|
||||
in order to do anti-aliased stuff, we need to draw onto a Compatible Bitmap, and then get the DIB bits out
|
||||
we might also be able to create a Compatible HBITMAP and then pass it as the constructor parameter to SkinBitmap
|
||||
|
||||
sample code:
|
||||
void RenderFont(int x, int y, int size, char *str, char *fontname,
|
||||
void *buf, int w, int h)
|
||||
{
|
||||
|
||||
HDC hdc=GetDC(NULL);
|
||||
HDC mdc = CreateCompatibleDC(hdc);
|
||||
HBITMAP bm = CreateCompatibleBitmap(hdc,w,h);
|
||||
|
||||
HFONT hf=CreateFont(size, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
||||
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
ANTIALIASED_QUALITY, DEFAULT_PITCH, fontname);
|
||||
|
||||
RECT r;
|
||||
r.top=0;
|
||||
r.left=0;
|
||||
r.right=w;
|
||||
r.bottom=h;
|
||||
|
||||
SelectObject(mdc, bm);
|
||||
FillRect(mdc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
||||
|
||||
SelectObject(mdc, hf);
|
||||
SetBkMode(mdc, TRANSPARENT);
|
||||
SetTextColor(mdc, 0xFFFFFF);
|
||||
TextOut(mdc, 0, 0, str, strlen(str));
|
||||
|
||||
BITMAPINFO bmi;
|
||||
|
||||
bmi.bmiHeader.biSize=sizeof(bmi.bmiHeader);
|
||||
bmi.bmiHeader.biWidth=256;
|
||||
bmi.bmiHeader.biHeight=256;
|
||||
bmi.bmiHeader.biPlanes=1;
|
||||
bmi.bmiHeader.biBitCount=32;
|
||||
bmi.bmiHeader.biCompression=BI_RGB;
|
||||
|
||||
GetDIBits(mdc,bm,0,256,buf,&bmi,DIB_RGB_COLORS);
|
||||
|
||||
DeleteObject(hf);
|
||||
DeleteObject(bm);
|
||||
}
|
||||
*/
|
61
Src/Wasabi/api/font/win32/truetypefont_win32.h
Normal file
61
Src/Wasabi/api/font/win32/truetypefont_win32.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef __TRUETYPEFONT_WN32_H
|
||||
#define __TRUETYPEFONT_WN32_H
|
||||
|
||||
#include <api/font/svc_fonti.h>
|
||||
|
||||
#include <bfc/stack.h>
|
||||
#include <api/font/truetypefontdef.h>
|
||||
#include <tataki/canvas/bltcanvas.h>
|
||||
class ifc_canvas;
|
||||
class BltCanvas;
|
||||
|
||||
class TrueTypeFont_Win32 : public svc_fontI {
|
||||
public:
|
||||
TrueTypeFont_Win32();
|
||||
virtual ~TrueTypeFont_Win32();
|
||||
|
||||
virtual void textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void 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, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void 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, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void 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, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void 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, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual void textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
|
||||
virtual int getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias);
|
||||
virtual int getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias);
|
||||
virtual int getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialias);
|
||||
virtual void getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialias);
|
||||
|
||||
virtual void setFontId(const wchar_t *id) { font_id = id; }
|
||||
virtual const wchar_t *getFontId() { return font_id; }
|
||||
virtual int getScriptId() { return scriptid; }
|
||||
virtual void setScriptId(int id) { scriptid = id; }
|
||||
|
||||
virtual int isBitmap();
|
||||
virtual void setFontFace(const wchar_t *face);
|
||||
virtual int addFontResource(OSFILETYPE f, const wchar_t *name);
|
||||
virtual int addFontResource2( void *data, int datalen, const wchar_t *name );
|
||||
virtual const wchar_t *getFaceName();
|
||||
|
||||
virtual const wchar_t *getFontSvcName() { return L"Win32 TextOut"; }
|
||||
static const char *getServiceName() { return "Win32 Truetype font renderer"; }
|
||||
|
||||
static wchar_t *filenameToFontFace(const wchar_t *filename);
|
||||
|
||||
protected:
|
||||
void prepareCanvas(BltCanvas *canvas, int size, int bold, int opaque, int underline, int italic, int antialiased);
|
||||
void restoreCanvas(BltCanvas *canvas, ifc_canvas *dest, int w, int h, COLORREF color, COLORREF bkcolor, int antialiased, int x=0, int y=0);
|
||||
HFONT MakeFont(int size, int bold, int underline, int italic, int antialiased);
|
||||
|
||||
protected:
|
||||
StringW font_id;
|
||||
int scriptid;
|
||||
|
||||
private:
|
||||
StringW face_name;
|
||||
StringW tmpfilename;
|
||||
|
||||
HFONT font, oldFont;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user