diff --git a/uppsrc/Core/Convert.cpp b/uppsrc/Core/Convert.cpp index f1a2b4c2d..37a75665f 100644 --- a/uppsrc/Core/Convert.cpp +++ b/uppsrc/Core/Convert.cpp @@ -281,10 +281,8 @@ Value Scan(dword qtype, const String& text, const Value& def) { return Null; } -#ifdef flagSO Convert::Convert() {} Convert::~Convert() {} -#endif Value Convert::Format(const Value& q) const { if(IsVoid(q) || q.IsNull()) return String(); @@ -485,6 +483,8 @@ Value MapConvert::Format(const Value& q) const { return map.Get(q, Null); } +NoConvertClass::NoConvertClass() {} + Value NoConvertClass::Format(const Value& q) const { return q; } diff --git a/uppsrc/Core/Convert.h b/uppsrc/Core/Convert.h index 9bb77d67e..ee2745af5 100644 --- a/uppsrc/Core/Convert.h +++ b/uppsrc/Core/Convert.h @@ -24,15 +24,8 @@ Value NotNullError(); class Convert { public: -#ifdef flagSO Convert(); virtual ~Convert(); -#else - #if defined(__clang__) || GCC_VERSION >= 40600 - Convert(){}; - #endif - virtual ~Convert() {} -#endif virtual Value Format(const Value& q) const; virtual Value Scan(const Value& text) const; @@ -220,9 +213,8 @@ const ConvertString& StdConvertStringNotNull(); class NoConvertClass : public Convert { public: -#ifdef __clang__ - NoConvertClass(){}; -#endif + NoConvertClass(); + virtual Value Format(const Value& q) const; }; diff --git a/uppsrc/CtrlLib/EditCtrl.h b/uppsrc/CtrlLib/EditCtrl.h index 07dacec65..3ec3461af 100644 --- a/uppsrc/CtrlLib/EditCtrl.h +++ b/uppsrc/CtrlLib/EditCtrl.h @@ -225,6 +225,8 @@ public: EditField& AutoSize(int maxcx = INT_MAX) { autosize = maxcx; Finish(); return *this; } EditField& NoBackground(bool b = true) { nobg = b; Transparent(); Refresh(); return *this; } EditField& AlignRight(bool b = true) { alignright = b; Refresh(); return *this; } + bool IsNoBackground() const { return nobg; } + bool IsAlignRight() const { return alignright; } CharFilter GetFilter() const { return filter; } const Convert& GetConvert() const { return *convert; } @@ -279,6 +281,7 @@ typedef EditMinMax EditDouble; typedef EditMinMax EditDate; typedef EditMinMax EditTime; typedef EditMinMaxNotNull EditIntNotNull; +typedef EditMinMaxNotNull EditInt64NotNull; typedef EditMinMaxNotNull EditDoubleNotNull; typedef EditMinMaxNotNull EditDateNotNull; typedef EditMinMaxNotNull EditTimeNotNull; diff --git a/uppsrc/CtrlLib/PushCtrl.h b/uppsrc/CtrlLib/PushCtrl.h index 5aab7ffd6..8094dcd80 100644 --- a/uppsrc/CtrlLib/PushCtrl.h +++ b/uppsrc/CtrlLib/PushCtrl.h @@ -42,6 +42,7 @@ public: Pusher& SetLabel(const char *text); Pusher& ClickFocus(bool cf = true); Pusher& NoClickFocus() { return ClickFocus(false); } + bool IsClickFocus() const { return clickfocus; } Font GetFont() const { return font; } String GetLabel() const { return label; } @@ -146,6 +147,7 @@ public: Button dec; void Show(bool s = true); + bool IsVisible() const { return visible; } static const Style& StyleDefault(); diff --git a/uppsrc/Draw/FontCR.cpp b/uppsrc/Draw/FontCR.cpp index c5652376b..da53157f0 100644 --- a/uppsrc/Draw/FontCR.cpp +++ b/uppsrc/Draw/FontCR.cpp @@ -1,311 +1,311 @@ -#include "Draw.h" - -NAMESPACE_UPP - -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; -} - -struct sRFace { - const char *name; - dword l, h; -} sFontReplacements[] = { - { "sans-serif", 0xffee0008, 0xdc000801 }, - { "Arial", 0xfffe0000, 0x09c00080 }, - { "Arial Unicode MS", 0xfffc3fef, 0xfa7ff7e7 }, - { "MS UI Gothic", 0xffc01008, 0x0fffff00 }, - { "MS Mincho", 0xffc01008, 0x0fffff00 }, - { "WenQuanYi Zen Hei Mono", 0xfd800000, 0x0ae7ff7e }, - { "WenQuanYi Zen Hei", 0xfd800000, 0x0ae7ff7e }, - { "VL Gothic", 0xfd800000, 0x09a7ff80 }, - { "VL PGothic", 0xffe00008, 0x0de7ff80 }, - { "UnDotum", 0xe5800000, 0x0aa7ff7e }, - { "UnBatang", 0xe5800000, 0x0aa7ff7e }, - { "DejaVu Sans Mono", 0xffec0004, 0x0fc00080 }, - { "DejaVu Sans", 0xfffd000c, 0x0fc40080 }, - { "AlArabiyaFreeSerif", 0xffdc0008, 0xd8000007 }, - { "Kochi Mincho", 0xffdc0008, 0xd8000007 }, - { "Kochi Gothic", 0xffdc0008, 0xd8000007 }, - { "Sazanami Mincho", 0xffdc0008, 0xd8000007 }, - { "Sazanami Gothic", 0xffdc0008, 0xd8000007 }, - { "Gulim", 0xf7c00000, 0x0ba7ff7e }, - { "SimSun", 0xfd800000, 0x09ffff00 }, - { "PMingLiU", 0xff800000, 0x09ffff00 }, - { "FreeSans", 0xfff23d00, 0x0fc00000 }, - { "FreeSerif", 0xfffd3938, 0x0fc00080 }, - { "Symbol", 0xe4000000, 0x88000002 }, -}; - -struct sFontMetricsReplacement { - Font src; - Font dst; - Font mdst; -}; - -bool Replace(Font fnt, int chr, Font& rfnt) -{ - static Vector rface; - static Vector l, h; - ONCELOCK { - for(int i = 0; i < __countof(sFontReplacements) && rface.GetCount() < 20; i++) { - int q = Font::FindFaceNameIndex(sFontReplacements[i].name); - if(q > 0) { - rface.Add(q); - l.Add(sFontReplacements[i].l); - h.Add(sFontReplacements[i].h); - } - } - } - - Font f = fnt; - dword tl = chr < 4096 ? 0x80000000 >> (chr >> 7) : 0; - dword th = 0x8000000 >> ((dword)chr >> 11); -// DDUMP(FormatIntHex(chr)); -// DDUMP(FormatIntHex(th)); - for(int i = 0; i < rface.GetCount(); i++) { -// DDUMP(Font(rface[i], 10)); -// DDUMP(FormatIntHex(h[i])); -// DDUMP(FormatIntHex(h[i] & th)); - if(((l[i] & tl) || (h[i] & th)) && IsNormal(f.Face(rface[i]), chr)) { - int a = fnt.GetAscent(); - int d = fnt.GetDescent(); - if(f.GetAscent() > a || f.GetDescent() > d) { - static sFontMetricsReplacement cache[256]; - int q = CombineHash(fnt, f) & 255; - if(cache[q].src != fnt || cache[q].dst != f) { - cache[q].src = fnt; - cache[q].dst = f; - while((f.GetAscent() > a || f.GetDescent() > d) && f.GetHeight() > 1) { - f.Height(max(1, min(f.GetHeight() - 1, f.GetHeight() * 9 / 10))); - } - cache[q].mdst = f; - } - else - f = cache[q].mdst; - } - rfnt = f; - return true; - } - } - return false; -} - -END_UPP_NAMESPACE +#include "Draw.h" + +NAMESPACE_UPP + +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; +} + +struct sRFace { + const char *name; + dword l, h; +} sFontReplacements[] = { + { "sans-serif", 0xffee0008, 0xdc000801 }, + { "Arial", 0xfffe0000, 0x09c00080 }, + { "Arial Unicode MS", 0xfffc3fef, 0xfa7ff7e7 }, + { "SimSun", 0xfd800000, 0x09ffff00 }, + { "MS UI Gothic", 0xffc01008, 0x0fffff00 }, + { "MS Mincho", 0xffc01008, 0x0fffff00 }, + { "WenQuanYi Zen Hei Mono", 0xfd800000, 0x0ae7ff7e }, + { "WenQuanYi Zen Hei", 0xfd800000, 0x0ae7ff7e }, + { "VL Gothic", 0xfd800000, 0x09a7ff80 }, + { "VL PGothic", 0xffe00008, 0x0de7ff80 }, + { "UnDotum", 0xe5800000, 0x0aa7ff7e }, + { "UnBatang", 0xe5800000, 0x0aa7ff7e }, + { "DejaVu Sans Mono", 0xffec0004, 0x0fc00080 }, + { "DejaVu Sans", 0xfffd000c, 0x0fc40080 }, + { "AlArabiyaFreeSerif", 0xffdc0008, 0xd8000007 }, + { "Kochi Mincho", 0xffdc0008, 0xd8000007 }, + { "Kochi Gothic", 0xffdc0008, 0xd8000007 }, + { "Sazanami Mincho", 0xffdc0008, 0xd8000007 }, + { "Sazanami Gothic", 0xffdc0008, 0xd8000007 }, + { "Gulim", 0xf7c00000, 0x0ba7ff7e }, + { "PMingLiU", 0xff800000, 0x09ffff00 }, + { "FreeSans", 0xfff23d00, 0x0fc00000 }, + { "FreeSerif", 0xfffd3938, 0x0fc00080 }, + { "Symbol", 0xe4000000, 0x88000002 }, +}; + +struct sFontMetricsReplacement { + Font src; + Font dst; + Font mdst; +}; + +bool Replace(Font fnt, int chr, Font& rfnt) +{ + static Vector rface; + static Vector l, h; + ONCELOCK { + for(int i = 0; i < __countof(sFontReplacements) && rface.GetCount() < 20; i++) { + int q = Font::FindFaceNameIndex(sFontReplacements[i].name); + if(q > 0) { + rface.Add(q); + l.Add(sFontReplacements[i].l); + h.Add(sFontReplacements[i].h); + } + } + } + + Font f = fnt; + dword tl = chr < 4096 ? 0x80000000 >> (chr >> 7) : 0; + dword th = 0x8000000 >> ((dword)chr >> 11); +// DDUMP(FormatIntHex(chr)); +// DDUMP(FormatIntHex(th)); + for(int i = 0; i < rface.GetCount(); i++) { +// DDUMP(Font(rface[i], 10)); +// DDUMP(FormatIntHex(h[i])); +// DDUMP(FormatIntHex(h[i] & th)); + if(((l[i] & tl) || (h[i] & th)) && IsNormal(f.Face(rface[i]), chr)) { + int a = fnt.GetAscent(); + int d = fnt.GetDescent(); + if(f.GetAscent() > a || f.GetDescent() > d) { + static sFontMetricsReplacement cache[256]; + int q = CombineHash(fnt, f) & 255; + if(cache[q].src != fnt || cache[q].dst != f) { + cache[q].src = fnt; + cache[q].dst = f; + while((f.GetAscent() > a || f.GetDescent() > d) && f.GetHeight() > 1) { + f.Height(max(1, min(f.GetHeight() - 1, f.GetHeight() * 9 / 10))); + } + cache[q].mdst = f; + } + else + f = cache[q].mdst; + } + rfnt = f; + return true; + } + } + return false; +} + +END_UPP_NAMESPACE