From ebf8af66c9ef27a706dde42124e0fa42d594d04e Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Fri, 1 Apr 2005 07:00:32 +0000 Subject: [PATCH] Added support for BFont::GetGlyphShapes. Not finished yet and untested, delivery method as to be changed. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12214 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/servers/app/ServerFont.h | 1 + src/kits/interface/Font.cpp | 10 ++- src/servers/app/FontFamily.cpp | 2 +- src/servers/app/ServerApp.cpp | 79 +++++++++++++++++ src/servers/app/ServerFont.cpp | 108 +++++++++++++++++++++++ 5 files changed, 197 insertions(+), 3 deletions(-) diff --git a/headers/private/servers/app/ServerFont.h b/headers/private/servers/app/ServerFont.h index 61728c3b90..3e96c9205e 100644 --- a/headers/private/servers/app/ServerFont.h +++ b/headers/private/servers/app/ServerFont.h @@ -71,6 +71,7 @@ public: int32 TunedCount(void) const { return fStyle->TunedCount(); } uint16 GlyphCount(void) const { return fStyle->GlyphCount(); } uint16 CharMapCount(void) const { return fStyle->CharMapCount(); } + BShape **GetGlyphShapes(const char charArray[], int32 numChars) const; FT_Face GetFTFace() const { return fStyle->GetFTFace(); }; diff --git a/src/kits/interface/Font.cpp b/src/kits/interface/Font.cpp index f775dd52f1..4fbf5dd126 100644 --- a/src/kits/interface/Font.cpp +++ b/src/kits/interface/Font.cpp @@ -1147,9 +1147,15 @@ BFont::GetGlyphShapes(const char charArray[], int32 numChars, BShape *glyphShape link.StartMessage(AS_GET_GLYPH_SHAPES); - link.Attach(numChars); + link.Attach(fFamilyID); + link.Attach(fStyleID); + link.Attach(fSize); + link.Attach(fShear); + link.Attach(fRotation); + link.Attach(fFlags); - for(int32 i=0; i(numChars); + for(int32 i = 0; i < numChars; i++) link.Attach(charArray[i]); link.FlushWithReply(&code); diff --git a/src/servers/app/FontFamily.cpp b/src/servers/app/FontFamily.cpp index 1d266a833f..6a5f8573f0 100644 --- a/src/servers/app/FontFamily.cpp +++ b/src/servers/app/FontFamily.cpp @@ -146,7 +146,6 @@ uint16 FontStyle::TranslateStyleToFace(const char *name) const if(str.IFindFirst("bold")!=B_ERROR) return B_BOLD_FACE; - if(str.IFindFirst("italic")!=B_ERROR) return B_ITALIC_FACE; if(str.IFindFirst("oblique")!=B_ERROR) @@ -155,6 +154,7 @@ uint16 FontStyle::TranslateStyleToFace(const char *name) const return B_REGULAR_FACE; } + /*! \brief Constructor \param namestr Name of the family diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 58f8ad9775..d1dc500092 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "AppServer.h" @@ -1684,6 +1685,84 @@ void ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg) break; } + case AS_GET_GLYPH_SHAPES: + { + // Attached Data: + // 1) uint16 - family ID + // 2) uint16 - style ID + // 3) float - point size + // 4) float - shear + // 5) float - rotation + // 6) uint32 - flags + // 7) int32 - numChars + // 8) char - chars (numChars times) + // 9) port_id - reply port + + // Returns: + // 1) size_t - message size + // 2) flattened BMessage containing archived BShape + // numChars times + + uint16 famid, styid; + uint32 flags; + float ptsize, shear, rotation; + + msg.Read(&famid); + msg.Read(&styid); + msg.Read(&ptsize); + msg.Read(&shear); + msg.Read(&rotation); + msg.Read(&flags); + + int32 numChars; + msg.Read(&numChars); + + char charArray[numChars]; + for (int32 i = 0; i < numChars; i++) + msg.Read(&charArray[i]); + + port_id replyport; + msg.Read(&replyport); + replylink.SetSendPort(replyport); + + ServerFont font; + if (font.SetFamilyAndStyle(famid, styid) == B_OK) { + font.SetSize(ptsize); + font.SetShear(shear); + font.SetRotation(rotation); + font.SetFlags(flags); + + BShape **shapes = font.GetGlyphShapes(charArray, numChars); + if (shapes) { + replylink.StartMessage(SERVER_TRUE); + for (int32 i = 0; i < numChars; i++) { + BMessage message; + if (shapes[i]->Archive(&message) != B_OK) + break; + delete shapes[i]; + + size_t size = message.FlattenedSize(); + char *buffer = new char[size]; + if (message.Flatten(buffer, size) != B_OK) { + delete buffer; + break; + } + + replylink.Attach(size); + replylink.Attach(buffer, size); + } + replylink.Flush(); + } else { + replylink.StartMessage(SERVER_FALSE); + replylink.Flush(); + } + } else { + replylink.StartMessage(SERVER_FALSE); + replylink.Flush(); + } + + break; + } default: { STRACE(("ServerApp %s received unhandled message code offset %s\n",fSignature.String(), diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp index 2a6de1e197..532f358a1f 100644 --- a/src/servers/app/ServerFont.cpp +++ b/src/servers/app/ServerFont.cpp @@ -24,8 +24,12 @@ // Description: Shadow BFont class // //------------------------------------------------------------------------------ +#include #include "ServerFont.h" #include "FontServer.h" +#include "Angle.h" +#include FT_FREETYPE_H +#include FT_OUTLINE_H /*! \brief Constructor @@ -171,6 +175,110 @@ void ServerFont::Height(font_height *fh) *fh=fStyle->GetHeight(fSize); } +// functions needed to convert a freetype vector graphics to a BShape +inline BPoint +VectorToPoint(FT_Vector *vector) +{ + BPoint result; + result.x = float(int32(vector->x)) / 2097152; + result.y = -float(int32(vector->y)) / 2097152; + return result; +} + +int +MoveToFunc(FT_Vector *to, void *user) +{ + ((BShape *)user)->MoveTo(VectorToPoint(to)); + return 0; +} + +int +LineToFunc(FT_Vector *to, void *user) +{ + ((BShape *)user)->LineTo(VectorToPoint(to)); + return 0; +} + +int +ConicToFunc(FT_Vector *control, FT_Vector *to, void *user) +{ + BPoint controls[3]; + + controls[0] = VectorToPoint(control); + controls[1] = VectorToPoint(to); + controls[2] = controls[1]; + + ((BShape *)user)->BezierTo(controls); + return 0; +} + +int +CubicToFunc(FT_Vector *control1, FT_Vector *control2, FT_Vector *to, void *user) +{ + BPoint controls[3]; + + controls[0] = VectorToPoint(control1); + controls[1] = VectorToPoint(control2); + controls[2] = VectorToPoint(to); + + ((BShape *)user)->BezierTo(controls); + return 0; +} + +BShape ** +ServerFont::GetGlyphShapes(const char charArray[], int32 numChars) const +{ + if (!charArray || numChars <= 0) + return NULL; + + FT_Outline_Funcs funcs; + funcs.move_to = MoveToFunc; + funcs.line_to = LineToFunc; + funcs.conic_to = ConicToFunc; + funcs.cubic_to = CubicToFunc; + + FT_Face face = fStyle->GetFTFace(); + if (!face) + return NULL; + + FT_Set_Char_Size(face, 0, int32(fSize) * 64, 72, 72); + + Angle rotation(frotation); + Angle shear(fshear); + + // First, rotate + FT_Matrix rmatrix; + rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000); + rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000); + rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000); + rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000); + + // Next, shear + FT_Matrix smatrix; + smatrix.xx = (FT_Fixed)(0x10000); + smatrix.xy = (FT_Fixed)(-shear.Cosine()*0x10000); + smatrix.yx = (FT_Fixed)(0); + smatrix.yy = (FT_Fixed)(0x10000); + + // Multiply togheter + FT_Matrix_Multiply(&rmatrix, &smatrix); + + FT_Vector pen; + FT_Set_Transform(face, &smatrix, &pen); + + BShape **shapes = (BShape **)malloc(sizeof(BShape *) * numChars); + for (int i = 0; i < numChars; i++) { + shapes[i] = new BShape(); + shapes[i]->Clear(); + FT_Load_Char(face, charArray[i], FT_LOAD_NO_BITMAP); + FT_Outline outline = face->glyph->outline; + FT_Outline_Decompose(&outline, &funcs, shapes[i]); + shapes[i]->Close(); + } + + return shapes; +} + /*! \brief Sets the ServerFont instance to whatever font is specified \param familyID ID number of the family to set