mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 22:02:58 -06:00
Developing NewDraw Font
git-svn-id: svn://ultimatepp.org/upp/trunk@1348 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
502b7fd776
commit
ade5f2aec5
6 changed files with 292 additions and 0 deletions
|
|
@ -1,6 +1,9 @@
|
|||
uses
|
||||
CtrlLib;
|
||||
|
||||
include
|
||||
gdfgsdfg;
|
||||
|
||||
file
|
||||
AccessKey.h,
|
||||
test.key,
|
||||
|
|
|
|||
36
uppdev/FontInfo/FontInfo.h
Normal file
36
uppdev/FontInfo/FontInfo.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef _FontInfo_FontInfo_h_
|
||||
#define _FontInfo_FontInfo_h_
|
||||
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
struct CommonFontInfo {
|
||||
int ascent;
|
||||
int descent;
|
||||
int external;
|
||||
int internal;
|
||||
int height;
|
||||
int lineheight;
|
||||
int overhang;
|
||||
int avewidth;
|
||||
int maxwidth;
|
||||
int firstchar;
|
||||
int charcount;
|
||||
int default_char;
|
||||
int spacebefore;
|
||||
int spaceafter;
|
||||
bool fixedpitch;
|
||||
bool scaleable;
|
||||
};
|
||||
|
||||
struct GlyphInfo {
|
||||
int16 width;
|
||||
int16 lspc;
|
||||
int16 rspc;
|
||||
};
|
||||
|
||||
GlyphInfo GetGlyphInfoSys(Font font, int chr);
|
||||
CommonFontInfo GetFontInfoSys(Font font);
|
||||
|
||||
#endif
|
||||
13
uppdev/FontInfo/FontInfo.upp
Normal file
13
uppdev/FontInfo/FontInfo.upp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
optimize_speed;
|
||||
|
||||
uses
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
FontInfo.h,
|
||||
Win32.cpp,
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
146
uppdev/FontInfo/Win32.cpp
Normal file
146
uppdev/FontInfo/Win32.cpp
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#include "FontInfo.h"
|
||||
|
||||
HFONT CreateWin32Font(Font font, int angle, int chrset)
|
||||
{
|
||||
#ifdef PLATFORM_WINCE
|
||||
LOGFONT lfnt;
|
||||
Zero(lfnt);
|
||||
lfnt.lfHeight = font.GetHeight() ? -abs(font.GetHeight()) : -12;
|
||||
lfnt.lfWeight = font.IsBold() ? FW_BOLD : FW_NORMAL;
|
||||
lfnt.lfItalic = font.IsItalic();
|
||||
lfnt.lfUnderline = font.IsUnderline();
|
||||
lfnt.lfStrikeOut = font.IsStrikeout();
|
||||
wcscpy(lfnt.lfFaceName, ToSystemCharset(font.GetFaceName()));
|
||||
return CreateFontIndirect(&lfnt);
|
||||
#else
|
||||
return CreateFont(
|
||||
font.GetHeight() ? -abs(font.GetHeight()) : -12,
|
||||
font.GetWidth(), angle, angle, font.IsBold() ? FW_BOLD : FW_NORMAL,
|
||||
font.IsItalic(), font.IsUnderline(), font.IsStrikeout(),
|
||||
chrset,
|
||||
font.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
font.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH|FF_DONTCARE,
|
||||
font.GetFaceName()
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sGetCW(HDC hdc, wchar *h, int n)
|
||||
{
|
||||
SIZE sz;
|
||||
return GetTextExtentPoint32W(hdc, h, n, &sz) ? sz.cx : 0;
|
||||
}
|
||||
|
||||
GlyphInfo GetGlyphInfoSys(Font font, int chr)
|
||||
{
|
||||
static Font last;
|
||||
static GlyphInfo li[256];
|
||||
static int lastpage = -1;
|
||||
|
||||
int page = chr >> 8;
|
||||
if(page == lastpage)
|
||||
return li[chr & 255];
|
||||
|
||||
HFONT hfont = CreateWin32Font(font, 0, 0);
|
||||
if(!hfont) {
|
||||
GlyphInfo n;
|
||||
memset(&n, 0, sizeof(GlyphInfo));
|
||||
return n;
|
||||
}
|
||||
HDC hdc = ScreenHDC();
|
||||
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
|
||||
int from = page << 8;
|
||||
GlyphInfo *t = li;
|
||||
if(page >= 32) {
|
||||
wchar h[3];
|
||||
h[0] = 'x';
|
||||
h[1] = 'x';
|
||||
h[2] = 'x';
|
||||
int w0 = sGetCW(hdc, h, 2);
|
||||
for(int i = 0; i < 256; i++) {
|
||||
h[1] = from + i;
|
||||
t[i].width = sGetCW(hdc, h, 3) - w0;
|
||||
t[i].lspc = t[i].rspc = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool abca = false, abcw = false;
|
||||
Buffer<ABC> abc(256);
|
||||
abcw = ::GetCharABCWidths(hdc, from, from + 256 - 1, abc);
|
||||
#ifndef PLATFORM_WINCE
|
||||
if(!abcw)
|
||||
abca = ::GetCharABCWidthsA(hdc, from, from + 256 - 1, abc);
|
||||
#endif
|
||||
if(abcw)
|
||||
{
|
||||
for(ABC *s = abc, *lim = abc + 256; s < lim; s++, t++)
|
||||
{
|
||||
t->width = s->abcA + s->abcB + s->abcC;
|
||||
t->lspc = s->abcA;
|
||||
t->rspc = s->abcC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer<int> wb(256);
|
||||
#ifdef PLATFORM_WINCE
|
||||
::GetCharWidth32(hdc, from, from + 256 - 1, wb);
|
||||
#else
|
||||
::GetCharWidthW(hdc, from, from + 256 - 1, wb);
|
||||
#endif
|
||||
for(int *s = wb, *lim = wb + 256; s < lim; s++, t++)
|
||||
{
|
||||
t->width = *s - GetFontInfoSys(font).overhang;
|
||||
if(abca)
|
||||
{
|
||||
ABC aa = abc[(byte)ToAscii(from++)];
|
||||
t->lspc = aa.abcA;
|
||||
t->rspc = aa.abcC;
|
||||
}
|
||||
else
|
||||
t->lspc = t->rspc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
::SelectObject(hdc, ohfont);
|
||||
return li[chr & 255];
|
||||
}
|
||||
|
||||
CommonFontInfo GetFontInfoSys(Font font)
|
||||
{
|
||||
CommonFontInfo fi;
|
||||
memset(&fi, 0, sizeof(fi));
|
||||
HFONT hfont = CreateWin32Font(font, 0, 0);
|
||||
if(hfont) {
|
||||
HDC hdc = ScreenHDC();
|
||||
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
|
||||
TEXTMETRIC tm;
|
||||
::GetTextMetrics(hdc, &tm);
|
||||
fi.ascent = tm.tmAscent;
|
||||
fi.descent = tm.tmDescent;
|
||||
fi.external = tm.tmExternalLeading;
|
||||
fi.internal = tm.tmInternalLeading;
|
||||
fi.height = fi.ascent + fi.descent;
|
||||
fi.lineheight = fi.height + fi.external;
|
||||
fi.overhang = tm.tmOverhang;
|
||||
fi.avewidth = tm.tmAveCharWidth;
|
||||
fi.maxwidth = tm.tmMaxCharWidth;
|
||||
fi.firstchar = tm.tmFirstChar;
|
||||
fi.charcount = tm.tmLastChar - tm.tmFirstChar + 1;
|
||||
fi.default_char = tm.tmDefaultChar;
|
||||
fi.fixedpitch = (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0;
|
||||
fi.scaleable = tm.tmPitchAndFamily & TMPF_TRUETYPE;
|
||||
if(fi.scaleable) {
|
||||
ABC abc;
|
||||
GetCharABCWidths(hdc, 'o', 'o', &abc);
|
||||
fi.spacebefore = abc.abcA;
|
||||
fi.spaceafter = abc.abcC;
|
||||
}
|
||||
else
|
||||
fi.spacebefore = fi.spaceafter = 0;
|
||||
::SelectObject(hdc, ohfont);
|
||||
}
|
||||
return fi;
|
||||
}
|
||||
4
uppdev/FontInfo/init
Normal file
4
uppdev/FontInfo/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _FontInfo_icpp_init_stub
|
||||
#define _FontInfo_icpp_init_stub
|
||||
#include "CtrlLib/init"
|
||||
#endif
|
||||
90
uppdev/FontInfo/main.cpp
Normal file
90
uppdev/FontInfo/main.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#include "FontInfo.h"
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
struct CharEntry {
|
||||
GlyphInfo info;
|
||||
word chr;
|
||||
Font font;
|
||||
};
|
||||
|
||||
CharEntry fc_cache_global[4096];
|
||||
|
||||
CharEntry GetGlyphEntry(Font font, int chr)
|
||||
{
|
||||
DrawLock __;
|
||||
unsigned hash = CombineHash(font.GetHashValue(), chr) & 511;
|
||||
CharEntry& e = fc_cache_global[hash];
|
||||
if(e.font != font || e.chr != chr) {
|
||||
e.font = font;
|
||||
e.chr = chr;
|
||||
e.info = GetGlyphInfoSys(font, chr);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
thread__ CharEntry fc_cache[512];
|
||||
|
||||
const GlyphInfo& GetGlyphInfo(Font font, int chr)
|
||||
{
|
||||
unsigned hash = CombineHash(font.GetHashValue(), chr) & 511;
|
||||
CharEntry& e = fc_cache[hash];
|
||||
if(e.font != font || e.chr != chr)
|
||||
e = GetGlyphEntry(font, chr);
|
||||
return e.info;
|
||||
}
|
||||
|
||||
struct FontEntry {
|
||||
CommonFontInfo info;
|
||||
Font font;
|
||||
};
|
||||
|
||||
thread__ FontEntry fi_cache[64];
|
||||
|
||||
const CommonFontInfo& GetFontInfo(Font font)
|
||||
{
|
||||
unsigned hash = font.GetHashValue() & 63;
|
||||
FontEntry& e = fi_cache[hash];
|
||||
if(e.font != font) {
|
||||
DrawLock __;
|
||||
e.font = font;
|
||||
e.info = GetFontInfoSys(font);
|
||||
}
|
||||
return e.info;
|
||||
}
|
||||
|
||||
Size GetTextSizeNew(const wchar *text, Font font, int n)
|
||||
{
|
||||
int cx = 0;
|
||||
const wchar *wtext = (const wchar *)text;
|
||||
while(n > 0) {
|
||||
cx += GetGlyphInfo(font, *wtext++).width;
|
||||
n--;
|
||||
}
|
||||
return Size(cx, GetFontInfo(font).height);
|
||||
}
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
WString x = "Just a little test!";
|
||||
RDUMP(GetTextSize(x, Arial(20), x.GetCount()));
|
||||
RDUMP(GetTextSizeNew(x, Arial(20), x.GetCount()));
|
||||
RDUMP(sizeof(GlyphInfo));
|
||||
RDUMP(sizeof(CharEntry));
|
||||
RDUMP(sizeof(CommonFontInfo));
|
||||
#ifndef _DEBUG
|
||||
int cx = 0;
|
||||
{
|
||||
RTIMING("Old");
|
||||
for(int i = 0; i < 1000000; i++) {
|
||||
cx += GetTextSize(x, Arial(20), x.GetCount()).cx;
|
||||
}
|
||||
}
|
||||
{
|
||||
RTIMING("New");
|
||||
for(int i = 0; i < 1000000; i++) {
|
||||
cx += GetTextSizeNew(x, Arial(20), x.GetCount()).cx;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue