Browse Source

- added TextStyle:: custom options
- minor fixes for operations::blit

dmuratshin 9 năm trước cách đây
mục cha
commit
9a21a1eebb

+ 6 - 6
oxygine/src/Font.cpp

@@ -39,7 +39,6 @@ namespace oxygine
     void Font::addGlyph(const glyph& gl)
     {
         _glyphs.insert(gl);
-        //_glyphs.push_back(gl);
     }
 
     bool glyphFindPred(const glyph& g, int code)
@@ -52,10 +51,11 @@ namespace oxygine
         return ob1.ch < ob2.ch;
     }
 
-    const glyph* Font::findGlyph(int code) const
+    const glyph* Font::findGlyph(int code, const glyphOptions &opt) const
     {
         glyph g;
         g.ch = code;
+        g.opt = opt;
         glyphs::const_iterator it = _glyphs.find(g);
         if (it != _glyphs.end())
         {
@@ -65,18 +65,18 @@ namespace oxygine
         return 0;
     }
 
-    const glyph* Font::getGlyph(int code) const
+    const glyph* Font::getGlyph(int code, const glyphOptions &opt) const
     {
-        const glyph* g = findGlyph(code);
+        const glyph* g = findGlyph(code, opt);
         if (g)
             return g;
 
         glyph gl;
         Font* fn = const_cast<Font*>(this);
-        if (fn->loadGlyph(code, gl))
+        if (fn->loadGlyph(code, gl, opt))
         {
             fn->_glyphs.insert(gl);
-            g = findGlyph(code);
+            g = findGlyph(code, opt);
             OX_ASSERT(g);
         }
 

+ 11 - 5
oxygine/src/Font.h

@@ -11,11 +11,14 @@ namespace oxygine
 {
     DECLARE_SMART(NativeTexture, spNativeTexture);
 
+    typedef unsigned int glyphOptions;
+
     struct glyph
     {
         RectF src;
 
         int ch;
+        glyphOptions opt;
 
         short sw;
         short sh;
@@ -28,18 +31,21 @@ namespace oxygine
 
         spNativeTexture texture;
 
-        bool operator == (const glyph& r) const {return ch == r.ch;}
+        bool operator == (const glyph& r) const {return ch == r.ch && opt == r.opt;}
+#ifdef __S3E__
         bool operator < (const glyph& r) const { return ch < r.ch; }
+#endif
     };
 
     struct GlyphHasher
     {
         std::size_t operator()(const glyph& k) const
         {
-            return std::hash<int>()(k.ch);
+            return std::hash<int>()(k.ch + k.opt);
         }
     };
 
+
     class Font: public ObjectBase
     {
     public:
@@ -53,7 +59,7 @@ namespace oxygine
 
         void setScale(float scale) { _scale = scale; }
 
-        const glyph*    getGlyph(int code) const;
+        const glyph*    getGlyph(int code, const glyphOptions &opt) const;
         int             getBaselineDistance() const;
         int             getSize() const;
         float           getScale() const;
@@ -61,9 +67,9 @@ namespace oxygine
         bool            isSDF() const;
 
     protected:
-        const glyph* findGlyph(int code) const;
+        const glyph* findGlyph(int code, const glyphOptions &opt) const;
 
-        virtual bool loadGlyph(int code, glyph&) { return false; }
+        virtual bool loadGlyph(int code, glyph&, const glyphOptions &opt) { return false; }
 
 #ifdef __S3E__
         typedef std::set<glyph> glyphs;

+ 4 - 1
oxygine/src/TextStyle.h

@@ -40,7 +40,8 @@ namespace oxygine
             breakLongWords(false),
             outline(0.0f),
             outlineColor(Color::Black),
-            weight(0.5f) {}
+            weight(0.5f),
+            options(0){}
 
         const ResFont* font;
 
@@ -49,6 +50,7 @@ namespace oxygine
 
         int linesOffset;//vertical distance offset between lines
         int kerning;//horizontal distance
+        unsigned int options;//additional flags could be used for generating custom glyphs
         bool multiline;
         bool breakLongWords;//works with multiline flag. breakLongWords = false doesn't allow to break too long words
         Color color;
@@ -90,6 +92,7 @@ namespace oxygine
         TextStyle withOutline(float outline) const { TextStyle st = *this; st.outline = outline; return st; }
         TextStyle withOutlineColor(const Color& color) const { TextStyle st = *this; st.outlineColor = color; return st; }
         TextStyle withWeight(float weight) const { TextStyle st = *this; st.weight = weight; return st; }
+        TextStyle withOptions(unsigned int opt) const { TextStyle st = *this; st.options = opt; return st; }
     };
 
     std::string dumpStyle(const TextStyle& s, bool onlydiff);

+ 24 - 0
oxygine/src/core/ImageDataOperations.cpp

@@ -1,4 +1,5 @@
 #include "ImageDataOperations.h"
+#include "math/Color.h"
 #include <string.h>
 
 namespace oxygine
@@ -102,6 +103,23 @@ namespace oxygine
             applyOperation(op, src, dest);
         }
 
+        void premultiply(ImageData& dest)
+        {
+            blitPremultiply(dest, dest);
+        }
+
+        void blitColored(const ImageData& src, ImageData& dest, const Color &c)
+        {
+            Pixel p;
+            p.r = c.r;
+            p.g = c.g;
+            p.b = c.b;
+            p.a = c.a;
+
+            op_blit_colored op(p);
+            applyOperation(op, src, dest);
+        }
+
         void flipY(const ImageData& src, ImageData& dest)
         {
             if (!check(src, dest))
@@ -124,5 +142,11 @@ namespace oxygine
                 destLine -= destpitch;
             }
         }
+
+        void blend(const ImageData& src, ImageData& dest)
+        {
+            op_blend_srcAlpha_invSrcAlpha op;
+            applyOperation(op, src, dest);
+        }
     }
 }

+ 35 - 7
oxygine/src/core/ImageDataOperations.h

@@ -4,6 +4,8 @@
 
 namespace oxygine
 {
+    class Color;
+
     namespace operations
     {
         //based on memcpy
@@ -13,19 +15,22 @@ namespace oxygine
         void move(const ImageData& src, ImageData& dest);
 
         void blit(const ImageData& src, ImageData& dest);
+        void blitColored(const ImageData& src, ImageData& dest, const Color &c);
         void blitPremultiply(const ImageData& src, ImageData& dest);
+        void premultiply(ImageData& dest);
         void flipY(const ImageData& src, ImageData& dest);
+        void blend(const ImageData& src, ImageData& dest);
 
         inline void blend_srcAlpha_invSrcAlpha(const Pixel& pS, Pixel& pD)
         {
             const unsigned int& s = pS.rgba;
             unsigned int& d = pD.rgba;
 
-            unsigned int dst_rb = d      & 0xFF00FF;
-            unsigned int dst_ag = d >> 8 & 0xFF00FF;
+            unsigned int dst_rb = d        & 0xFF00FF;
+            unsigned int dst_ag = (d >> 8) & 0xFF00FF;
 
-            unsigned int src_rb = s      & 0xFF00FF;
-            unsigned int src_ag = s >> 8 & 0xFF00FF;
+            unsigned int src_rb = s        & 0xFF00FF;
+            unsigned int src_ag = (s >> 8) & 0xFF00FF;
 
             unsigned int d_rb = src_rb - dst_rb;
             unsigned int d_ag = src_ag - dst_ag;
@@ -35,8 +40,8 @@ namespace oxygine
             d_rb >>= 8;
             d_ag >>= 8;
 
-            const unsigned int rb  = (d_rb + dst_rb)      & 0x00FF00FF;
-            const unsigned int ag  = (d_ag + dst_ag) << 8 & 0xFF00FF00;
+            const unsigned int rb  = (d_rb + dst_rb)        & 0x00FF00FF;
+            const unsigned int ag  = ((d_ag + dst_ag) << 8) & 0xFF00FF00;
 
             d = rb | ag;
         }
@@ -117,6 +122,29 @@ namespace oxygine
             }
         };
 
+        class op_blit_colored
+        {
+        public:            
+            op_blit_colored(const Pixel &clr):color(clr){}
+
+            template<class Src, class Dest>
+            void operator()(const Src& srcPixelFormat, Dest& destPixelFormat, const unsigned char* srcData, unsigned char* destData) const
+            {
+                Pixel src;
+                srcPixelFormat.getPixel(srcData, src);
+
+                Pixel dest;
+                dest.r = (src.r * color.r) / 255;
+                dest.g = (src.g * color.g) / 255;
+                dest.b = (src.b * color.b) / 255;
+                dest.a = (src.a * color.a) / 255;
+
+                destPixelFormat.setPixel(destData, dest);
+            }
+
+            Pixel color;
+        };
+
         class op_blend_srcAlpha_invSrcAlpha
         {
         public:
@@ -127,7 +155,7 @@ namespace oxygine
                 srcPixelFormat.getPixel(srcData, pS);
 
                 Pixel pD;
-                destPixelFormat.getPixel(srcData, pD);
+                destPixelFormat.getPixel(destData, pD);
 
                 blend_srcAlpha_invSrcAlpha(pS, pD);
                 destPixelFormat.setPixel(destData, pD);

+ 5 - 5
oxygine/src/res/ResFontBM.cpp

@@ -348,8 +348,6 @@ namespace oxygine
             }
         }
 
-
-
         // chars blocks
         for (int i = 0; i < numChars; i++)
         {
@@ -409,6 +407,7 @@ namespace oxygine
             int code = 0;
             ucs2_to_utf8(charID, (unsigned char*)&code);
             gl.ch = code;
+            gl.opt = 0;
             gl.texture = _pages[page_].texture;
 
             _font->addGlyph(gl);
@@ -439,11 +438,12 @@ namespace oxygine
 
     void ResFontBM::_finalize()
     {
-        const glyph *g = _font->getGlyph(0xA0);
+        glyphOptions opt = 0;
+        const glyph *g = _font->getGlyph(0xA0, opt);
         if (g)
             return;
         
-        g = _font->getGlyph(' ');
+        g = _font->getGlyph(' ', opt);
         if (!g)
             return;
 
@@ -543,7 +543,6 @@ namespace oxygine
             _font->setScale(scale);
         }
 
-
         pugi::xml_node chars = pages.next_sibling("chars");
         pugi::xml_node child = chars.first_child();
         while (!child.empty())
@@ -602,6 +601,7 @@ namespace oxygine
             int code = 0;
             ucs2_to_utf8(charID, (unsigned char*)&code);
             gl.ch = code;
+            gl.opt = 0;
             gl.texture = _pages[page].texture;
 
             font->addGlyph(gl);

+ 4 - 3
oxygine/src/text_utils/Node.cpp

@@ -168,6 +168,7 @@ namespace oxygine
             {
                 int i = 0;
                 const Font* font = rd.getStyle().font->getFont(0, rd.getStyle().fontSize);
+                glyphOptions opt = rd.getStyle().options;
 
                 while (i != (int)_data.size())
                 {
@@ -175,8 +176,8 @@ namespace oxygine
                     if (s.code == '\n')
                         rd.nextLine();
                     else
-                    {
-                        const glyph* gl = font->getGlyph(s.code);
+                    {                        
+                        const glyph* gl = font->getGlyph(s.code, opt);
                         if (gl)
                         {
                             s.gl = *gl;
@@ -184,7 +185,7 @@ namespace oxygine
                         }
                         else
                         {
-                            gl = font->getGlyph(_defMissing);
+                            gl = font->getGlyph(_defMissing, opt);
                             if (gl)//even 'missing' symbol  could be missing
                             {
                                 s.gl = *gl;