From d79c64e5e2ea4d590caa424b0fedba774c0197c9 Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 16 Sep 2013 09:42:06 +0000 Subject: [PATCH] .uppdev git-svn-id: svn://ultimatepp.org/upp/trunk@6355 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppdev/GlDraw/GlDraw.h | 1 - uppdev/SDL20/Ft.cpp | 422 ----------------------------------------- uppdev/SDL20/SDL20.h | 10 +- uppdev/SDL20/SDL20.upp | 7 +- uppdev/SDL20/init | 3 +- uppdev/SDL20/text.qtf | 4 +- 6 files changed, 9 insertions(+), 438 deletions(-) delete mode 100644 uppdev/SDL20/Ft.cpp diff --git a/uppdev/GlDraw/GlDraw.h b/uppdev/GlDraw/GlDraw.h index 1203703fd..32808ff0c 100644 --- a/uppdev/GlDraw/GlDraw.h +++ b/uppdev/GlDraw/GlDraw.h @@ -7,7 +7,6 @@ namespace Upp { struct GLDraw : SDraw { void SetColor(Color c); -// void SetVertexRect(const Rect& r); virtual void PutImage(Point p, const Image& m, const Rect& src); virtual void PutRect(const Rect& r, Color color); diff --git a/uppdev/SDL20/Ft.cpp b/uppdev/SDL20/Ft.cpp deleted file mode 100644 index 27dc97141..000000000 --- a/uppdev/SDL20/Ft.cpp +++ /dev/null @@ -1,422 +0,0 @@ -#include "SDL20.h" - -#include "freetype/ft2build.h" -#include FT_FREETYPE_H -#include - -#define LLOG(x) DLOG(x) -#define LTIMING(x) // TIMING(x) - -NAMESPACE_UPP - -struct FtFontStyle { - String path; - const byte *data; - int size; - - operator bool() const { return path.GetCount() || data; } - - FtFontStyle() { data = NULL; size = 0; } -}; - -struct FtFontData : Moveable { - FtFontStyle style[4]; -}; - -static Vector& sFontData() -{ - return Single >(); -} - -void sSetFont(int index, const String& path, const byte *data, int size, dword style) -{ - Vector& fd = sFontData(); - FtFontStyle& f = fd.At(index).style[style & 3]; - f.path = path; - f.data = data; - f.size = size; - if(!fd.At(index).style[0]) - sSetFont(index, path, data, size, 0); - if(!fd.At(0).style[0]) - sSetFont(0, path, data, size, 0); - InvalidateFontList(); -} - -void SetFileFont(int face, const char *path, dword style) -{ - sSetFont(face, path, NULL, 0, style); -} - -void SetMemoryFont(int face, const byte *data, int size, dword style) -{ - sSetFont(face, Null, data, size, style); -} - -void GetStdFontSys(String& name, int& height) -{ - name = "xxxx"; -} - -FtFontStyle GetFontStyle(Font font) -{ - Vector& fd = sFontData(); - int face = font.GetFace(); - if(face >= 0 && face < fd.GetCount()) { - const FtFontData& d = fd[face]; - int ii = font.IsBold() + 2 * font.IsItalic(); - if(d.style[ii]) - return d.style[ii]; - if(d.style[0]) - return d.style[0]; - } - return fd.At(0).style[0]; -} - -String GetFontDataSys(Font font) -{ - return LoadFile(font.Fi().path); -} - -static FT_Library sFTlib; - -EXITBLOCK -{ - if(sFTlib) - FT_Done_FreeType(sFTlib); -} - -bool sInitFt(void) -{ - if(sFTlib) - return true; - return FT_Init_FreeType(&sFTlib) == 0; -} - -void FT_ITALIC(FT_GlyphSlot slot) -{ - FT_Matrix transform; - FT_Outline* outline = &slot->outline; - /* only oblique outline glyphs */ - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) - return; - - /* we don't touch the advance width */ - /* For italic, simply apply a shear transform, with an angle */ - /* of about 12 degrees. */ - - transform.xx = 0x10000L; - transform.yx = 0x00000L; - - transform.xy = 0x03000L; - transform.yy = 0x10000L; - - FT_Outline_Transform( outline, &transform ); -} - -void FT_BOLD(FT_GlyphSlot slot) -{ - FT_Face face = slot->face; - FT_Pos amount; - - if(slot->format != FT_GLYPH_FORMAT_OUTLINE) - return; - - /* some reasonable strength */ - amount = FT_MulFix(face->units_per_EM, - face->size->metrics.y_scale ) / 18; - (void)FT_Outline_Embolden( &slot->outline, amount); - - if ( slot->advance.x ) - slot->advance.x += amount; - - if ( slot->advance.y ) - slot->advance.y += amount; - - slot->metrics.width += amount; - slot->metrics.height += amount; - slot->metrics.horiBearingY += amount; - slot->metrics.horiAdvance += amount; - slot->metrics.vertBearingX -= amount / 2; - slot->metrics.vertBearingY += amount; - slot->metrics.vertAdvance += amount; -} - -FT_Face CreateFTFace(Font fnt) -{ - sInitFt(); - - FtFontStyle f = GetFontStyle(fnt); - - if(!f) - return NULL; - - FT_Face face; - DDUMP(f.path); - if(IsNull(f.path) ? FT_New_Memory_Face(sFTlib, f.data, f.size, 0, &face) - : FT_New_Face(sFTlib, f.path, 0, &face)) - return NULL; - - FT_Set_Pixel_Sizes(face, 0, fnt.GetHeight()); - return face; -} - -#define FONTCACHE 37 - -struct FtFaceEntry { - Font font; - FT_Face face; -}; - -static FtFaceEntry ft_cache[FONTCACHE]; - -void ClearFtFaceCache() -{ - for(int i = 0; i < FONTCACHE; i++) - ft_cache[i].font.Height(-30000); -} - -FT_Face FTFace(Font fnt) -{ - LTIMING("FTFace"); - LLOG("FTFace " << fnt); - ONCELOCK { - ClearFtFaceCache(); - } - FtFaceEntry be; - be = ft_cache[0]; - for(int i = 0; i < FONTCACHE; i++) { - FtFaceEntry e = ft_cache[i]; - if(i) - ft_cache[i] = be; - if(e.font == fnt && e.face) { - if(i) - ft_cache[0] = e; - LLOG("Found " << e.face); - return e.face; - } - be = e; - } - LTIMING("FTFace2"); - if(be.face) { - LLOG("Removing " << be.font << " - " << (void *)be.face); - FT_Done_Face(be.face); - } - be.font = fnt; - be.face = CreateFTFace(be.font); - ft_cache[0] = be; - LLOG("Created " << be.face); - return be.face; -} - -CommonFontInfo GetFontInfoSys(Font font) -{ - sInitFt(); - CommonFontInfo fi; - FT_Face face = FTFace(font); - if(face) { - fi.ascent = face->size->metrics.ascender >> 6; - fi.descent = -(face->size->metrics.descender >> 6); - fi.height = fi.ascent + fi.descent; - fi.lineheight = face->size->metrics.height >> 6; - fi.external = 0; - fi.internal = 0; - fi.overhang = 0; - fi.maxwidth = face->size->metrics.max_advance >> 6; - fi.avewidth = fi.maxwidth; - fi.default_char = '?'; - fi.fixedpitch = font.GetFaceInfo() & Font::FIXEDPITCH; - fi.ttf = true;//strcmp(FT_Get_X11_Font_Format(face), "TrueType") == 0; // ???? - } - else - memset(&fi, 0, sizeof(fi)); - - return fi; -} - -#define FLOOR(x) ((x) & -64) -#define CEIL(x) (((x)+63) & -64) -#define TRUNC(x) ((x) >> 6) -#define ROUND(x) (((x)+32) & -64) - -static bool sLoadGlyph(Font fnt, FT_Face face, int chr) -{ - int glyph_index = FT_Get_Char_Index(face, chr); - if(!glyph_index) - return false; - if(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP)) - return false; - if(fnt.IsBold() && !(face->style_flags & FT_STYLE_FLAG_BOLD)) - FT_BOLD(face->glyph); - if(fnt.IsItalic() && !(face->style_flags & FT_STYLE_FLAG_ITALIC)) - FT_ITALIC(face->glyph); - return true; -} - -GlyphInfo GetGlyphInfoSys(Font font, int chr) -{ - LTIMING("GetGlyphInfoSys"); - GlyphInfo gi; - FT_Face face = FTFace(font); - gi.lspc = gi.rspc = 0; - gi.width = (int16)0x8000; - LLOG("GetGlyphInfoSys " << font << " " << (char)chr << " " << FormatIntHex(chr)); - if(face) { - LTIMING("GetGlyphInfoSys 2"); - if(sLoadGlyph(font, face, chr)) { - FT_Glyph_Metrics& m = face->glyph->metrics; - int left = FLOOR(m.horiBearingX); - int width = TRUNC(CEIL(m.horiBearingX + m.width) - left); - gi.width = TRUNC(ROUND(face->glyph->advance.x)); - gi.lspc = TRUNC(left); - gi.rspc = gi.width - width - gi.lspc; - } - } - return gi; -} - -Vector GetAllFacesSys() -{ - static const char *basic_fonts[] = { - "sans-serif", - "serif", - "sans-serif", - "monospace", - }; - - Vector list; - for(int i = 0; i < __countof(basic_fonts); i++) { - FaceInfo& fi = list.Add(); - fi.name = basic_fonts[i]; - fi.info = (i == 3) ? Font::SCALEABLE|Font::FIXEDPITCH : Font::SCALEABLE; - } - -// const Vector& fd = sFontData(); -// for(int i = __countof(basic_fonts); i < fd.GetCount(); i++) { -// FaceInfo& fi = list.Add(); -// } - - return list; -} - -static inline double ft_dbl(int p) -{ - return double(p) / 64.0; -} - -bool RenderOutline(const FT_Outline& outline, FontGlyphConsumer& path, double xx, double yy) -{ - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - FT_Vector* point; - FT_Vector* limit; - char* tags; - int n; // index of contour in outline - char tag; // current point's state - int first = 0; // index of first point in contour - for(n = 0; n < outline.n_contours; n++) { - int last = outline.contours[n]; - limit = outline.points + last; - v_start = outline.points[first]; - v_last = outline.points[last]; - v_control = v_start; - point = outline.points + first; - tags = outline.tags + first; - tag = FT_CURVE_TAG(tags[0]); - if(tag == FT_CURVE_TAG_CUBIC) return false; - if(tag == FT_CURVE_TAG_CONIC) { - if(FT_CURVE_TAG(outline.tags[last]) == FT_CURVE_TAG_ON) { - // start at last point if it is on the curve - v_start = v_last; - limit--; - } - else { - // if both first and last points are conic, - // start at their middle and record its position - // for closure - v_start.x = (v_start.x + v_last.x) / 2; - v_start.y = (v_start.y + v_last.y) / 2; - v_last = v_start; - } - point--; - tags--; - } - path.Move(Pointf(ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy)); - while(point < limit) { - point++; - tags++; - - tag = FT_CURVE_TAG(tags[0]); - switch(tag) { - case FT_CURVE_TAG_ON: - path.Line(Pointf(ft_dbl(point->x) + xx, -ft_dbl(point->y) + yy)); - continue; - case FT_CURVE_TAG_CONIC: - v_control.x = point->x; - v_control.y = point->y; - Do_Conic: - if(point < limit) { - FT_Vector vec; - FT_Vector v_middle; - point++; - tags++; - tag = FT_CURVE_TAG(tags[0]); - vec.x = point->x; - vec.y = point->y; - if(tag == FT_CURVE_TAG_ON) { - path.Quadratic(Pointf(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy), - Pointf(ft_dbl(vec.x) + xx, -ft_dbl(vec.y) + yy)); - continue; - } - if(tag != FT_CURVE_TAG_CONIC) return false; - v_middle.x = (v_control.x + vec.x) / 2; - v_middle.y = (v_control.y + vec.y) / 2; - path.Quadratic(Pointf(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy), - Pointf(ft_dbl(v_middle.x) + xx, -ft_dbl(v_middle.y) + yy)); - v_control = vec; - goto Do_Conic; - } - path.Quadratic(Pointf(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy), - Pointf(ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy)); - goto Close; - - default: - FT_Vector vec1, vec2; - if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) - return false; - vec1.x = point[0].x; - vec1.y = point[0].y; - vec2.x = point[1].x; - vec2.y = point[1].y; - point += 2; - tags += 2; - if(point <= limit) { - FT_Vector vec; - vec.x = point->x; - vec.y = point->y; - path.Cubic(Pointf(ft_dbl(vec1.x) + xx, -ft_dbl(vec1.y) + yy), - Pointf(ft_dbl(vec2.x) + xx, -ft_dbl(vec2.y) + yy), - Pointf(ft_dbl(vec.x) + xx, -ft_dbl(vec.y) + yy)); - continue; - } - path.Cubic(Pointf(ft_dbl(vec1.x) + xx, -ft_dbl(vec1.y) + yy), - Pointf(ft_dbl(vec2.x) + xx, -ft_dbl(vec2.y) + yy), - Pointf(ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy)); - goto Close; - } - } - Close: - path.Close(); - first = last + 1; - } - return true; -} - -void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt) -{ - FT_Face face = FTFace(fnt); - if(sLoadGlyph(fnt, face, ch)) - RenderOutline(face->glyph->outline, sw, x, y + fnt.GetAscent()); -} - -END_UPP_NAMESPACE diff --git a/uppdev/SDL20/SDL20.h b/uppdev/SDL20/SDL20.h index 7df8250f9..6888e30e9 100644 --- a/uppdev/SDL20/SDL20.h +++ b/uppdev/SDL20/SDL20.h @@ -5,6 +5,8 @@ #include +#include + using namespace Upp; #ifdef PLATFORM_POSIX @@ -13,14 +15,6 @@ using namespace Upp; NAMESPACE_UPP -enum FtStyle { - FtBOLD = 1, - FtITALIC = 2 -}; - -void SetFileFont(int face, const char *path, dword style = 0); -void SetMemoryFont(int face, const byte *data, int size, dword style = 0); - struct SDLWindow { SDL_Window *win; SDL_Renderer *ren; diff --git a/uppdev/SDL20/SDL20.upp b/uppdev/SDL20/SDL20.upp index cc7fa516b..9467cb36b 100644 --- a/uppdev/SDL20/SDL20.upp +++ b/uppdev/SDL20/SDL20.upp @@ -3,8 +3,8 @@ uses Draw, Painter, RichText, - freetype, - freetype; + plugin/FT_fontsys, + plugin/DroidFonts; library(WIN32) "SDLmain.lib SDL.lib"; @@ -12,7 +12,6 @@ library(POSIX) "SDL2 SDL2main"; file SDL20.h, - Ft.cpp, Window.cpp, SDLDraw.cpp, text.qtf, @@ -21,5 +20,5 @@ file main.conf; mainconfig - "" = "SSE2 MT CFONTS"; + "" = "SSE2 MT"; diff --git a/uppdev/SDL20/init b/uppdev/SDL20/init index b811db341..e8c259ed5 100644 --- a/uppdev/SDL20/init +++ b/uppdev/SDL20/init @@ -4,5 +4,6 @@ #include "Draw/init" #include "Painter/init" #include "RichText/init" -#include "freetype/init" +#include "plugin/FT_fontsys/init" +#include "plugin/DroidFonts/init" #endif diff --git a/uppdev/SDL20/text.qtf b/uppdev/SDL20/text.qtf index 915aa9346..8640b9551 100644 --- a/uppdev/SDL20/text.qtf +++ b/uppdev/SDL20/text.qtf @@ -24,8 +24,8 @@ Example:&] [s0; &] [s1; `\"`\1a`[x`]`\1`[`* bold`]`\"&] [s0; Normal [* Bold] [/ Italic] [*/ Bold Italic] [_ Underline] [- Stroked]&] -[Rs0; Normal [* Bold] [/ Italic] [*/ Bold Italic] [_ Underline] [- Stroked]&] -[Cs0; Normal [* Bold] [/ Italic] [*/ Bold Italic] [_ Underline] [- Stroked]&] +[R Normal [* Bold] [/ Italic] [*/ Bold Italic] [_ Underline] [- Stroked]&] +[C Normal [* Bold] [/ Italic] [*/ Bold Italic] [_ Underline] [- Stroked]&] [s0; Byte 0 represents the end of input sequence.&] [s0; &] [s0; Dimension units of QTF are dots `- one dot is defined as 1/600