From 322dfe7334d9efdf519cefbf9324ab54471334fc Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 5 Jul 2009 19:54:59 +0000 Subject: [PATCH] Developing new font metrics git-svn-id: svn://ultimatepp.org/upp/trunk@1360 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppdev/FontInfo/Compose.cpp | 225 +------------------------ uppdev/FontInfo/FontInfo.cpp | 176 +------------------ uppdev/FontInfo/FontInfo.h | 109 ++++-------- uppdev/FontInfo/FontReplace.cpp | 48 +----- uppdev/FontInfo/Win32.cpp | 290 -------------------------------- uppdev/RichEditTest/main.cpp | 4 + 6 files changed, 44 insertions(+), 808 deletions(-) diff --git a/uppdev/FontInfo/Compose.cpp b/uppdev/FontInfo/Compose.cpp index 97465e30f..8a2da65a6 100644 --- a/uppdev/FontInfo/Compose.cpp +++ b/uppdev/FontInfo/Compose.cpp @@ -1,223 +1,2 @@ -#include "FontInfo.h" - -enum { - CG_NONE, - CG_CAPITAL, - CG_SMALL -}; - -enum { - CG_GRAVE = 0x60, - CG_ACUTE = 0xb4, - CG_CEDILLA = 0xb8, - CG_MACRON = 175, - CG_CIRCUMFLEX = 0x2c6, - CG_TILDE = 0x2dc, - CG_DOT_ABOVE = 0x2d9, - CG_OGONEK = 0x2db, - CG_STROKE = '-', - CG_BREVE = 0x2d8, - CG_CARON = 0x2c7, - CG_MIDDLE_DOT = 0xb7, - CG_DOUBLE_ACUTE = 0x2dd, - CG_DIAERESIS = 0xa8, - CG_RING_ABOVE = 0x2da, - CG_COMMA_T = ',', - CG_COMMA_UR = 1, - CG_COMMA_URI, -}; - -struct CGInfo { - byte type; - char ascii; - wchar mark; -} -gc_info[128] = { - { CG_CAPITAL, 'A', CG_MACRON }, - { CG_SMALL, 'a', CG_MACRON }, - { CG_CAPITAL, 'A', CG_BREVE }, - { CG_SMALL, 'a', CG_BREVE }, - { CG_CAPITAL, 'A', CG_OGONEK }, - { CG_SMALL, 'a', CG_OGONEK }, - { CG_CAPITAL, 'C', CG_ACUTE }, - { CG_SMALL, 'c', CG_ACUTE }, - { CG_CAPITAL, 'C', CG_CIRCUMFLEX }, - { CG_SMALL, 'c', CG_CIRCUMFLEX }, - { CG_CAPITAL, 'C', CG_DOT_ABOVE }, - { CG_SMALL, 'c', CG_DOT_ABOVE }, - { CG_CAPITAL, 'C', CG_CARON }, - { CG_SMALL, 'c', CG_CARON }, - { CG_CAPITAL, 'D', CG_CARON }, - { CG_SMALL, 'd', CG_COMMA_UR }, - { CG_CAPITAL, 'D', CG_STROKE }, - { CG_SMALL, 'd', CG_STROKE }, - { CG_CAPITAL, 'E', CG_MACRON }, - { CG_SMALL, 'e', CG_MACRON }, - { CG_CAPITAL, 'E', CG_BREVE }, - { CG_SMALL, 'e', CG_BREVE }, - { CG_CAPITAL, 'E', CG_DOT_ABOVE }, - { CG_SMALL, 'e', CG_DOT_ABOVE }, - { CG_CAPITAL, 'E', CG_OGONEK }, - { CG_SMALL, 'e', CG_OGONEK }, - { CG_CAPITAL, 'E', CG_CARON }, - { CG_SMALL, 'e', CG_CARON }, - { CG_CAPITAL, 'G', CG_CIRCUMFLEX }, - { CG_SMALL, 'g', CG_CIRCUMFLEX }, - { CG_CAPITAL, 'G', CG_BREVE }, - { CG_SMALL, 'g', CG_BREVE }, - { CG_CAPITAL, 'G', CG_DOT_ABOVE }, - { CG_SMALL, 'g', CG_DOT_ABOVE }, - { CG_CAPITAL, 'G', CG_CEDILLA }, - { CG_SMALL, 'g', CG_CEDILLA }, - { CG_CAPITAL, 'H', CG_CIRCUMFLEX }, - { CG_SMALL, 'h', CG_CIRCUMFLEX }, - { CG_CAPITAL, 'H', CG_STROKE }, - { CG_SMALL, 'h', CG_STROKE }, - { CG_CAPITAL, 'I', CG_TILDE }, - { CG_SMALL, 'i', CG_TILDE }, - { CG_CAPITAL, 'I', CG_MACRON }, - { CG_SMALL, 'i', CG_MACRON }, - { CG_CAPITAL, 'I', CG_BREVE }, - { CG_SMALL, 'i', CG_BREVE }, - { CG_CAPITAL, 'I', CG_OGONEK }, - { CG_SMALL, 'i', CG_OGONEK }, - { CG_CAPITAL, 'I', CG_DOT_ABOVE }, - { CG_NONE, 0, 0 }, // , CG_SMALL, 'DOTLESS I - { CG_NONE, 0, 0 }, // LATIN CAPITAL LIGATURE IJ - { CG_NONE, 0, 0 }, // LATIN SMALL LIGATURE IJ - { CG_CAPITAL, 'J', CG_CIRCUMFLEX }, - { CG_SMALL, 'j', CG_CIRCUMFLEX }, - { CG_CAPITAL, 'K', CG_CEDILLA }, - { CG_SMALL, 'k', CG_CEDILLA }, - { CG_NONE, 0, 0 }, // CG_SMALL, 'KRA - { CG_CAPITAL, 'L', CG_ACUTE }, - { CG_SMALL, 'l', CG_ACUTE }, - { CG_CAPITAL, 'L', CG_CEDILLA }, - { CG_SMALL, 'l', CG_CEDILLA }, - { CG_CAPITAL, 'L', CG_COMMA_URI }, - { CG_SMALL, 'l', CG_COMMA_UR }, - { CG_CAPITAL, 'L', CG_MIDDLE_DOT }, - { CG_SMALL, 'l', CG_MIDDLE_DOT }, - { CG_CAPITAL, 'L', CG_STROKE }, - { CG_SMALL, 'l', CG_STROKE }, - { CG_CAPITAL, 'N', CG_ACUTE }, - { CG_SMALL, 'n', CG_ACUTE }, - { CG_CAPITAL, 'N', CG_CEDILLA }, - { CG_SMALL, 'n', CG_CEDILLA }, - { CG_CAPITAL, 'N', CG_CARON }, - { CG_SMALL, 'n', CG_CARON }, - { CG_NONE, 0, 0 }, // CG_SMALL, 'N PRECEDED BY APOSTROPHE - { CG_NONE, 0, 0 }, //CG_CAPITAL, 'ENG - { CG_NONE, 0, 0 }, //CG_SMALL, 'ENG - { CG_CAPITAL, 'O', CG_MACRON }, - { CG_SMALL, 'o', CG_MACRON }, - { CG_CAPITAL, 'O', CG_BREVE }, - { CG_SMALL, 'o', CG_BREVE }, - { CG_CAPITAL, 'O', CG_DOUBLE_ACUTE }, - { CG_SMALL, 'o', CG_DOUBLE_ACUTE }, - { CG_NONE, 0, 0 }, // LATIN CAPITAL LIGATURE OE - { CG_NONE, 0, 0 }, // LATIN SMALL LIGATURE OE - { CG_CAPITAL, 'R', CG_ACUTE }, - { CG_SMALL, 'r', CG_ACUTE }, - { CG_CAPITAL, 'R', CG_CEDILLA }, - { CG_SMALL, 'r', CG_CEDILLA }, - { CG_CAPITAL, 'R', CG_CARON }, - { CG_SMALL, 'r', CG_CARON }, - { CG_CAPITAL, 'S', CG_ACUTE }, - { CG_SMALL, 's', CG_ACUTE }, - { CG_CAPITAL, 'S', CG_CIRCUMFLEX }, - { CG_SMALL, 's', CG_CIRCUMFLEX }, - { CG_CAPITAL, 'S', CG_CEDILLA }, - { CG_SMALL, 's', CG_CEDILLA }, - { CG_CAPITAL, 'S', CG_CARON }, - { CG_SMALL, 's', CG_CARON }, - { CG_CAPITAL, 'T', CG_CEDILLA }, - { CG_SMALL, 't', CG_CEDILLA }, - { CG_CAPITAL, 'T', CG_CARON }, - { CG_SMALL, 't', CG_COMMA_T }, - { CG_CAPITAL, 'T', CG_STROKE }, - { CG_SMALL, 't', CG_STROKE }, - { CG_CAPITAL, 'U', CG_TILDE }, - { CG_SMALL, 'u', CG_TILDE }, - { CG_CAPITAL, 'U', CG_MACRON }, - { CG_SMALL, 'u', CG_MACRON }, - { CG_CAPITAL, 'U', CG_BREVE }, - { CG_SMALL, 'u', CG_BREVE }, - { CG_CAPITAL, 'U', CG_RING_ABOVE }, - { CG_SMALL, 'u', CG_RING_ABOVE }, - { CG_CAPITAL, 'U', CG_DOUBLE_ACUTE }, - { CG_SMALL, 'u', CG_DOUBLE_ACUTE }, - { CG_CAPITAL, 'U', CG_OGONEK }, - { CG_SMALL, 'u', CG_OGONEK }, - { CG_CAPITAL, 'W', CG_CIRCUMFLEX }, - { CG_SMALL, 'w', CG_CIRCUMFLEX }, - { CG_CAPITAL, 'Y', CG_CIRCUMFLEX }, - { CG_SMALL, 'y', CG_CIRCUMFLEX }, - { CG_CAPITAL, 'Y', CG_DIAERESIS }, - { CG_CAPITAL, 'Z', CG_ACUTE }, - { CG_SMALL, 'z', CG_ACUTE }, - { CG_CAPITAL, 'Z', CG_DOT_ABOVE }, - { CG_SMALL, 'z', CG_DOT_ABOVE }, - { CG_CAPITAL, 'Z', CG_CARON }, - { CG_SMALL, 'z', CG_CARON }, - { CG_NONE, 0, 0 } // CG_SMALL, 'LONG S -}; - -bool Compose(Font font, int chr, ComposedGlyph& cg) -{ - if(chr < 256 || chr > 256 + 128) - return false; - CGInfo f = gc_info[chr - 256]; - if(f.type == CG_NONE) - return false; - GlyphInfo gi = GetGlyphInfo(font, f.ascii); - if(!gi.IsNormal()) - return false; - int cw = gi.width; - CommonFontInfo fi = GetFontInfo(font); - gi = GetGlyphInfo(font, f.mark); - if(!gi.IsNormal()) - return false; - int mw = gi.width; - cg.mark_font = font; - cg.mark_pos.x = cg.mark_pos.y = 0; - cg.basic_char = f.ascii; - cg.mark_char = f.mark; - if(cg.mark_char == CG_COMMA_UR && fi.fixedpitch) - cg.mark_char = CG_CARON; - if(cg.mark_char == CG_COMMA_T) { - cg.mark_pos.y -= 3 * font.GetHeight() / 4; - cg.mark_pos.x += 4 * cw / 10; - if(font.IsItalic()) - cg.mark_pos.x += mw / 2; - } - else - if(cg.mark_char == CG_COMMA_UR) { - cg.mark_pos.y -= 2 * font.GetHeight() / 3; - cg.mark_pos.x += cw - mw / 4; - cg.mark_char = ','; - if(font.IsItalic()) - cg.mark_pos.x += mw / 3; - } - else - if(cg.mark_char == CG_COMMA_URI) { - cg.mark_pos.y -= 2 * font.GetHeight() / 3; - cg.mark_pos.x += cw - mw / 2; - cg.mark_char = ','; - if(font.IsItalic()) - cg.mark_pos.x += mw / 3; - } - else - if(cg.mark_char != CG_STROKE) { - if(cg.mark_char != CG_OGONEK && cg.mark_char != CG_CEDILLA && f.type == CG_CAPITAL) { - cg.mark_font = font(9 * font.GetHeight() / 10); - mw = GetGlyphInfo(cg.mark_font, f.mark).width; - cg.mark_pos.y -= cg.mark_char == CG_RING_ABOVE ? font.GetHeight() / 19 - : font.GetHeight() / 10; - } - cg.mark_pos.x += (cw - mw) / 2; - if(font.IsItalic()) - cg.mark_pos.x += mw / 5; - } - return true; -} +#include "FontInfo.h" + diff --git a/uppdev/FontInfo/FontInfo.cpp b/uppdev/FontInfo/FontInfo.cpp index 932b342cf..ada0aab60 100644 --- a/uppdev/FontInfo/FontInfo.cpp +++ b/uppdev/FontInfo/FontInfo.cpp @@ -1,170 +1,6 @@ -#include "FontInfo.h" - -void Std(Font& font) -{ - if(IsNull(font)) - font = StdFont(); - if(font.GetFace() == 0) - font.Face(GetStdFont.GetFace()); - if(font.GetHeight() == 0) - font.Height(GetStdFont.GetHeight()); -} - -struct CharEntry { - GlyphInfo info; - word chr; - Font font; -}; - -CharEntry fc_cache_global[4093]; - -bool IsNormal(Font font, int chr) -{ - DrawLock __; - CharEntry& e = fc_cache_global[CombineHash(font.GetHashValue(), chr) % 4093]; - if(e.font == font || e.chr == chr) - return e.info.IsNormal(); - return GetGlyphInfoSys(font, chr).IsNormal(); -} - -CharEntry GetGlyphEntry(Font font, int chr, unsigned hash) -{ - DrawLock __; - CharEntry& e = fc_cache_global[hash % 4093]; - if(e.font != font || e.chr != chr) { - e.font = font; - e.chr = chr; - e.info = GetGlyphInfoSys(font, chr); - if(!e.info.IsNormal()) { - ComposedGlyph cg; - Font rfnt; - if(Compose(font, chr, cg)) { - e.info.lspc = -1; - e.info.rspc = cg.basic_char; - } - else - if(Replace(font, chr, rfnt)) - e.info.lspc = rfnt.GetFace(); - else - e.info.lspc = -2; - } - } - return e; -} - -thread__ CharEntry fc_cache[512]; - -GlyphInfo GetGlyphInfo(Font font, int chr) -{ - Std(font); - unsigned hash = CombineHash(font.GetHashValue(), chr); - CharEntry& e = fc_cache[hash & 511]; - if(e.font != font || e.chr != chr) - e = GetGlyphEntry(font, chr, hash); - return e.info; -} - -void GlyphMetrics(GlyphInfo& f, Font font, int chr) -{ - if(f.IsReplaced()) - f = GetGlyphInfo(font().Face(f.lspc), chr); - if(f.IsComposed()) { - f = GetGlyphInfo(font, f.rspc); - if(f.IsComposedLM()) - f.rspc += f.width / 2; - } -} - -GlyphInfo GetGlyphMetrics(Font font, int chr) -{ - GlyphInfo f = GetGlyphInfo(font, chr); - if(f.IsMissing()) - f = GetGlyphInfo(font, '?'); - GlyphMetrics(f, font, chr); - return f; -} - -struct FontEntry { - CommonFontInfo info; - Font font; -}; - -thread__ FontEntry fi_cache[64]; - -const CommonFontInfo& GetFontInfo(Font font) -{ - Std(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; -} - -void DoDrawText(Draw& w, int x, int y, int angle, const wchar *text, Font font, Color ink, - int n, const int *dx) -{ - Std(font); - double sina; - double cosa; - int d = 0; - if(angle) - Draw::SinCos(angle, sina, cosa); //TODO global sin tables! - for(int i = 0; i < n; i++) { - wchar chr = text[i]; - GlyphInfo gi = GetGlyphInfo(font, chr); - if(gi.IsNormal()) - if(angle) - w.DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &chr, font, ink, 1, NULL); - else { - int c = 1; - int dd = 0; - if(!dx) - while(c < n) { - GlyphInfo gi2 = GetGlyphInfo(font, text[i + c]); - if(!gi2.IsNormal()) - break; - c++; - dd += gi.width; - gi = gi2; - } - w.DrawTextOp(x + d, y, 0, text + i, font, ink, c, NULL); - i += c - 1; - d += dd; - } - else - if(gi.IsReplaced()) { - FontInfo fi = font.Info(); - Font fnt = font; - fnt.Face(gi.lspc); - FontInfo fi2 = fnt.Info(); - if(angle) - w.DrawTextOp(int(x + cosa * d), int(y - sina * (fi.GetAscent() - fi2.GetAscent() + d)), - angle, &chr, fnt, ink, 1, NULL); - else - w.DrawTextOp(x + d, y + fi.GetAscent() - fi2.GetAscent(), 0, &chr, fnt, ink, 1, NULL); - GlyphMetrics(gi, font, chr); - } - else - if(gi.IsComposed()) { - ComposedGlyph cg; - Compose(font, chr, cg); - if(angle) { - w.DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &cg.basic_char, font, ink, 1, NULL); - w.DrawTextOp(int(x + cosa * (d + cg.mark_pos.x)), int(y - sina * (cg.mark_pos.y + d)), angle, &cg.mark_char, cg.mark_font, ink, 1, NULL); - } - else { - w.DrawTextOp(x + d, y, angle, &cg.basic_char, font, ink, 1, NULL); - w.DrawTextOp(x + cg.mark_pos.x + d, y + cg.mark_pos.y, angle, &cg.mark_char, cg.mark_font, ink, 1, NULL); - } - GlyphMetrics(gi, font, chr); - } - if(dx) - d += *dx++; - else - d += gi.width; - } -} +#include "FontInfo.h" + +void DoDrawText(Draw& w, int x, int y, int angle, const wchar *text, Font font, Color ink, + int n, const int *dx) +{ +} diff --git a/uppdev/FontInfo/FontInfo.h b/uppdev/FontInfo/FontInfo.h index 36e80b889..4b02bd827 100644 --- a/uppdev/FontInfo/FontInfo.h +++ b/uppdev/FontInfo/FontInfo.h @@ -1,79 +1,30 @@ -#ifndef _FontInfo_FontInfo_h_ -#define _FontInfo_FontInfo_h_ - -#include - -using namespace Upp; - -struct CommonFontInfo : Moveable { - 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; - -#ifdef PLATFORM_POSIX - int underline_thickness; - int underline_position; - String path; -#endif -}; - -CommonFontInfo GetFontInfoSys(Font font); - -struct GlyphInfo : Moveable { - int16 width; - int16 lspc; - int16 rspc; - - bool IsNormal() const { return (word)width != 0x8000; } - bool IsComposed() const { return !IsNormal() && (lspc == -1 || lspc == -11); } - bool IsComposedLM() const { return !IsNormal() && lspc == -11; } - bool IsReplaced() const { return !IsNormal() && lspc >= 0; } - bool IsMissing() const { return !IsNormal() && lspc == -2; } -}; - -GlyphInfo GetGlyphInfoSys(Font font, int chr); - -struct FaceInfo : Moveable { - String name; - dword info; -}; - -Vector GetAllFacesSys(); - -void Std(Font& font); - -bool IsNormal(Font font, int chr); - -GlyphInfo GetGlyphInfo(Font font, int chr); -void GlyphMetrics(GlyphInfo& f, Font font, int chr); -GlyphInfo GetGlyphMetrics(Font font, int chr); - -const CommonFontInfo& GetFontInfo(Font font); - -struct ComposedGlyph { - wchar basic_char; - Point mark_pos; - wchar mark_char; - Font mark_font; -}; - -bool Compose(Font fnt, int chr, ComposedGlyph& cs); -bool Replace(Font fnt, int chr, Font& rfnt); - -void DoDrawText(Draw& w, int x, int y, int angle, const wchar *text, Font font, Color ink, - int n, const int *dx); - -#endif +#ifndef _FontInfo_FontInfo_h_ +#define _FontInfo_FontInfo_h_ + +#include + +using namespace Upp; + +CommonFontInfo GetFontInfoSys(Font font); + +GlyphInfo GetGlyphInfoSys(Font font, int chr); + +Vector GetAllFacesSys(); + +void Std(Font& font); + +bool IsNormal(Font font, int chr); + +GlyphInfo GetGlyphInfo(Font font, int chr); +void GlyphMetrics(GlyphInfo& f, Font font, int chr); +GlyphInfo GetGlyphMetrics(Font font, int chr); + +const CommonFontInfo& GetFontInfo(Font font); + +bool Compose(Font fnt, int chr, ComposedGlyph& cs); +bool Replace(Font fnt, int chr, Font& rfnt); + +void DoDrawText(Draw& w, int x, int y, int angle, const wchar *text, Font font, Color ink, + int n, const int *dx); + +#endif diff --git a/uppdev/FontInfo/FontReplace.cpp b/uppdev/FontInfo/FontReplace.cpp index 664987bae..8a2da65a6 100644 --- a/uppdev/FontInfo/FontReplace.cpp +++ b/uppdev/FontInfo/FontReplace.cpp @@ -1,46 +1,2 @@ -#include "FontInfo.h" - -static const char *sFontReplacements[] = { - "sans-serif", - "Arial", - "Arial Unicode MS", - "Symbol", - "文泉驛等寬正黑", - "文泉驛正黑", - "MS UI Gothic", - "MS Mincho", - "Arial", - "AlArabiya" - "FreeSerif", - "Kochi Mincho", - "Kochi Gothic", - "Sazanami Mincho", - "Sazanami Gothic", - "Gulim", - "SimSun", - "PMingLiU", -}; - -bool Replace(Font fnt, int chr, Font& rfnt) -{ -// ASSERT(chr >= 0 && chr < - LOG("Replace: " << fnt << ": " << chr); - static Vector rface; - ONCELOCK { - for(int i = 0; i < __countof(sFontReplacements) && rface.GetCount() < 20; i++) { - int q = Font::FindFaceNameIndex(sFontReplacements[i]); - if(q > 0) - rface.Add(q); - } - } - - Font f = fnt; - for(int i = 0; i < rface.GetCount(); i++) - if(IsNormal(f.Face(rface[i]), chr)) { - rfnt = f; - LOG("Replacement: " << rfnt); - return true; - } - LOG("No replace"); - return false; -} +#include "FontInfo.h" + diff --git a/uppdev/FontInfo/Win32.cpp b/uppdev/FontInfo/Win32.cpp index 890480e45..0a4491a64 100644 --- a/uppdev/FontInfo/Win32.cpp +++ b/uppdev/FontInfo/Win32.cpp @@ -2,294 +2,4 @@ #ifdef PLATFORM_WIN32 -#define FONTCACHE 37 - -HFONT GetWin32Font(Font fnt, int angle, int chrset) -{ - static Font font[FONTCACHE]; - static HFONT hfont[FONTCACHE]; - ONCELOCK { - for(int i = 0; i < FONTCACHE; i++) - font[i].Face(-1); - } - int q = fnt.GetHashValue() % FONTCACHE; - if(font[q] != fnt) { - font[q] = fnt; - if(hfont[q]) - DeleteObject(hfont[q]); - #ifdef PLATFORM_WINCE - LOGFONT lfnt; - Zero(lfnt); - lfnt.lfHeight = fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12; - lfnt.lfWeight = fnt.IsBold() ? FW_BOLD : FW_NORMAL; - lfnt.lfItalic = fnt.IsItalic(); - lfnt.lfUnderline = fnt.IsUnderline(); - lfnt.lfStrikeOut = fnt.IsStrikeout(); - wcscpy(lfnt.lfFaceName, ToSystemCharset(fnt.GetFaceName())); - hfont[q] = CreateFontIndirect(&lfnt); - #else - hfont[q] = CreateFont( - fnt.GetHeight() ? -abs(fnt.GetHeight()) : -12, - fnt.GetWidth(), angle, angle, fnt.IsBold() ? FW_BOLD : FW_NORMAL, - fnt.IsItalic(), fnt.IsUnderline(), fnt.IsStrikeout(), - chrset, - fnt.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS, - fnt.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY, - DEFAULT_PITCH|FF_DONTCARE, - fnt.GetFaceName() - ); - #endif - } - return hfont[q]; -} - -int sGetCW(HDC hdc, wchar *h, int n) -{ - SIZE sz; - return GetTextExtentPoint32W(hdc, h, n, &sz) ? sz.cx : 0; -} - -static void Win32_GetGlyphIndices(HDC hdc, LPCWSTR s, int n, LPWORD r, DWORD flag) -{ - typedef DWORD (WINAPI *GGIW)(HDC, LPCWSTR, int, LPWORD, DWORD); - static GGIW fn; - ONCELOCK - if(HMODULE hDLL = LoadLibrary("gdi32")) - fn = (GGIW) GetProcAddress(hDLL, "GetGlyphIndicesW"); - if(fn) - fn(hdc, s, n, r, flag); - else - memset(r, 0, n * sizeof(WORD)); -} - -static HDC Win32_IC() -{ - static HDC hdc; - ONCELOCK { - hdc = CreateIC("DISPLAY", NULL, NULL, NULL); - } - return hdc; -} - -#define GLYPHINFOCACHE 31 - -GlyphInfo GetGlyphInfoSys(Font font, int chr) -{ - static Font fnt[GLYPHINFOCACHE]; - static int pg[GLYPHINFOCACHE]; - static GlyphInfo li[GLYPHINFOCACHE][256]; - - ONCELOCK { - for(int i = 0; i < GLYPHINFOCACHE; i++) - pg[i] = -1; - } - - int page = chr >> 8; - int q = CombineHash(font, page) % GLYPHINFOCACHE; - - if(fnt[q] != font || pg[q] != page) { - DDUMP(font); - DDUMP(q); - fnt[q] = font; - pg[q] = page; - HFONT hfont = GetWin32Font(font, 0, 0); - if(!hfont) { - GlyphInfo n; - memset(&n, 0, sizeof(GlyphInfo)); - return n; - } - HDC hdc = Win32_IC(); - HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont); - int from = page << 8; - GlyphInfo *t = li[q]; - 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(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 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; - } - } - } -#ifndef PLATFORM_WINCE - WORD pos[256]; - WCHAR wch[256]; - for(int i = 0; i < 256; i++) - wch[i] = from + i; - Win32_GetGlyphIndices(hdc, wch, 256, pos, 1); - for(int i = 0; i < 256; i++) - if(pos[i] == 0xffff) { - li[q][i].width = (int16)0x8000; - li[q][i].lspc = li[q][i].rspc = 0; - } -#endif - } - return li[q][chr & 255]; -} - -CommonFontInfo GetFontInfoSys(Font font) -{ - CommonFontInfo fi; - memset(&fi, 0, sizeof(fi)); - HFONT hfont = GetWin32Font(font, 0, 0); - if(hfont) { - HDC hdc = Win32_IC(); - 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; -} - -static Vector *sList; - -static int CALLBACK Win32_AddFace(const LOGFONT *logfont, const TEXTMETRIC *, dword type, LPARAM param) -{ -#ifdef PLATFORM_WINCE - const wchar *facename = (const wchar *)param; - if(facename && _wcsicmp(logfont->lfFaceName, facename)) - return 1; -#else - const char *facename = (const char *)param; - if(facename && stricmp(logfont->lfFaceName, facename)) - return 1; -#endif - - dword typ = 0; - if((logfont->lfPitchAndFamily & 3) == FIXED_PITCH) - typ |= Font::FIXEDPITCH; - if(type & TRUETYPE_FONTTYPE) - typ |= Font::SCALEABLE; - if(logfont->lfCharSet == SYMBOL_CHARSET) - typ |= Font::SYMBOLTYPE; - else - if(logfont->lfCharSet != 0) - typ |= Font::LOCAL; -#ifdef PLATFORM_WINCE - FontFaceInfo& f = sFontFace().Add(WString(logfont->lfFaceName).ToString()); - f.name = FromSystemCharset(logfont->lfFaceName); -#else - FaceInfo& f = sList->Add(); - f.name = FromSystemCharset(logfont->lfFaceName); - f.info = typ; -#endif - return facename ? 0 : 1; -} - -static int Win32_EnumFace(HDC hdc, const char *face) -{ -#ifdef PLATFORM_WINCE - return EnumFontFamilies(hdc, ToSystemCharset(face), Win32_AddFace, (LPARAM)~ToSystemCharset(face)); -#else - return EnumFontFamilies(hdc, face, Win32_AddFace, (LPARAM)face); -#endif -} - -static void Win32_ForceFace(HDC hdc, const char *face, const char *aface) -{ - if(!aface) - aface = "Arial"; - if(Win32_EnumFace(hdc, face) && Win32_EnumFace(hdc, aface)) - Panic("Missing font " + String(face)); -} - -Vector GetAllFacesSys() -{ - Vector list; - sList = &list; - -#ifdef PLATFORM_WINCE - HDC hdc = CreateDC(NULL, NULL, NULL, NULL); - Win32_ForceFace(hdc, "Tahoma", NULL); - Win32_ForceFace(hdc, "Tahoma", "Tahoma"); - Win32_ForceFace(hdc, "Courier New", "Tahoma"); - Win32_ForceFace(hdc, "Tahoma", "Tahoma"); - Win32_ForceFace(hdc, "Tahoma", "Tahoma"); - Win32_ForceFace(hdc, "Tahoma", "Tahoma"); - Win32_ForceFace(hdc, "Tahoma", "Tahoma"); - Win32_ForceFace(hdc, "Tahoma", "Tahoma"); - Win32_ForceFace(hdc, "Tahoma", "Tahoma"); -#else - HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL); - Win32_ForceFace(hdc, "Arial", NULL); - Win32_ForceFace(hdc, "Times New Roman", "Arial"); - Win32_ForceFace(hdc, "Courier New", "Arial"); - Win32_ForceFace(hdc, "Times New Roman", "Arial"); - Win32_ForceFace(hdc, "Arial", "Arial"); - Win32_ForceFace(hdc, "Courier New", "Arial"); - Win32_ForceFace(hdc, "Symbol", "Arial"); - Win32_ForceFace(hdc, "WingDings", "Arial"); - Win32_ForceFace(hdc, "Tahoma", "Arial"); -#endif - Win32_EnumFace(hdc, NULL); - DeleteDC(hdc); - return list; -} - #endif diff --git a/uppdev/RichEditTest/main.cpp b/uppdev/RichEditTest/main.cpp index d18a58e3c..19020433c 100644 --- a/uppdev/RichEditTest/main.cpp +++ b/uppdev/RichEditTest/main.cpp @@ -19,6 +19,10 @@ GUI_APP_MAIN DUMP(GUI_PopUpEffect()); RichEditWithToolBar e; + Vector h; + for(int i = 0; i < Font::GetFaceCount(); i++) + h.Add(i); + e.FontFaces(h); DUMP(ScrollBarSize());