Jelajahi Sumber

Merge branch 'dev' into debugactor-draggable

dmuratshin 9 tahun lalu
induk
melakukan
c28a496df7
61 mengubah file dengan 491 tambahan dan 400 penghapusan
  1. 2 1
      examples/Demo/src/TestProgressBar.h
  2. 29 14
      examples/Demo/src/TestTouches.h
  3. 0 1
      examples/HelloWorld/src/example.cpp
  4. 31 1
      oxygine/SDL/android/lib/src/org/oxygine/lib/HttpRequests.java
  5. 0 8
      oxygine/SDL/ios/oxygine/oxygine_ios.xcodeproj/project.pbxproj
  6. 0 8
      oxygine/SDL/macosx/oxygine_macosx/oxygine_macosx.xcodeproj/project.pbxproj
  7. 0 2
      oxygine/SDL/win32/oxygine.vcxproj
  8. 0 6
      oxygine/SDL/win32/oxygine.vcxproj.filters
  9. 32 51
      oxygine/src/Actor.cpp
  10. 25 18
      oxygine/src/Actor.h
  11. 2 0
      oxygine/src/AnimationFrame.cpp
  12. 1 0
      oxygine/src/AnimationFrame.h
  13. 1 1
      oxygine/src/Box9Sprite.h
  14. 15 4
      oxygine/src/Button.cpp
  15. 1 1
      oxygine/src/Button.h
  16. 5 0
      oxygine/src/ColorRectSprite.cpp
  17. 5 0
      oxygine/src/ColorRectSprite.h
  18. 8 0
      oxygine/src/EventDispatcher.h
  19. 6 13
      oxygine/src/Font.cpp
  20. 12 7
      oxygine/src/Font.h
  21. 10 0
      oxygine/src/Image.cpp
  22. 3 0
      oxygine/src/Image.h
  23. 15 1
      oxygine/src/Input.cpp
  24. 7 3
      oxygine/src/Input.h
  25. 1 1
      oxygine/src/MaskedSprite.h
  26. 3 3
      oxygine/src/PointerState.cpp
  27. 7 5
      oxygine/src/PointerState.h
  28. 4 9
      oxygine/src/ProgressBar.cpp
  29. 0 1
      oxygine/src/ProgressBar.h
  30. 2 1
      oxygine/src/SlidingActor.cpp
  31. 19 6
      oxygine/src/Sprite.cpp
  32. 2 0
      oxygine/src/Sprite.h
  33. 2 2
      oxygine/src/Stage.cpp
  34. 13 0
      oxygine/src/TextField.cpp
  35. 3 0
      oxygine/src/TextField.h
  36. 8 1
      oxygine/src/TextStyle.h
  37. 0 1
      oxygine/src/TouchEvent.h
  38. 0 153
      oxygine/src/blocking.cpp
  39. 0 41
      oxygine/src/blocking.h
  40. 12 0
      oxygine/src/core/ImageData.cpp
  41. 2 0
      oxygine/src/core/ImageData.h
  42. 24 0
      oxygine/src/core/ImageDataOperations.cpp
  43. 64 7
      oxygine/src/core/ImageDataOperations.h
  44. 2 1
      oxygine/src/core/ios/ios.h
  45. 11 1
      oxygine/src/core/ios/ios.mm
  46. 10 3
      oxygine/src/core/oxygine.cpp
  47. 3 2
      oxygine/src/core/s3e/HttpRequestTaskS3E.cpp
  48. 1 1
      oxygine/src/dev_tools/TreeInspectorPreview.cpp
  49. 0 1
      oxygine/src/oxygine-framework.h
  50. 10 2
      oxygine/src/oxygine_include.h
  51. 20 5
      oxygine/src/res/CreateResourceContext.cpp
  52. 8 0
      oxygine/src/res/ResAnim.cpp
  53. 1 0
      oxygine/src/res/ResAnim.h
  54. 2 1
      oxygine/src/res/ResAtlas.h
  55. 21 3
      oxygine/src/res/ResFontBM.cpp
  56. 1 1
      oxygine/src/res/ResFontBM.h
  57. 1 2
      oxygine/src/res/Resource.h
  58. 12 1
      oxygine/src/res/Resources.cpp
  59. 1 1
      oxygine/src/text_utils/Aligner.cpp
  60. 3 2
      oxygine/src/text_utils/Node.cpp
  61. 8 2
      tools/resbuild/xml_processor.py

+ 2 - 1
examples/Demo/src/TestProgressBar.h

@@ -19,7 +19,8 @@ public:
         bar->setResAnim(resources.getResAnim("bg"));
         bar->setAnchor(Vector2(0.5f, 0.5f));
         bar->setPosition(getSize() / 2);
-        bar->setScale(0.5f);
+
+        //bar->setSize(600, 200);
         content->addChild(bar);
     }
 

+ 29 - 14
examples/Demo/src/TestTouches.h

@@ -1,5 +1,6 @@
 #pragma once
 #include "test.h"
+#include "utils/stringUtils.h"
 
 class TestTouches: public Test
 {
@@ -35,20 +36,28 @@ public:
         tf->setY(5);
         tf->attachTo(orange);
 
-        tf = new TextField;
-        tf->setText("");
-        tf->setColor(Color::Black);
-        tf->setName("state2");
-        tf->setX(35);
-        tf->setY(5);
-        tf->attachTo(orange);
+        for (int i = 0; i < MouseButton_Num; ++i)
+        {
+            tf = new TextField;
+            tf->setText("");
+            tf->setColor(Color::Black);
+            char name[255];
+            safe_sprintf(name, "pressed %d", i);
+            tf->setName(name);
+            tf->setX(5);
+            tf->setY(15 + i * 10);
+            tf->attachTo(orange);
+        }
+
+
+
 
         tf = new TextField;
         tf->setText("");
         tf->setColor(Color::Black);
         tf->setName("local");
         tf->setX(5);
-        tf->setY(25);
+        tf->setY(50);
         tf->setMultiline(true);
         tf->setWidth(orange->getWidth());
         tf->attachTo(orange);
@@ -66,9 +75,14 @@ public:
 
     void onDownUp(Event* ev)
     {
+        TouchEvent* te = safeCast<TouchEvent*>(ev);
         spSprite s = safeSpCast<Sprite>(ev->currentTarget);
-        spTextField tf = s->getChildT<TextField>("state2");
-        tf->setText(ev->type == TouchEvent::TOUCH_DOWN ? "pressed" : "");
+
+        char name[255];
+        safe_sprintf(name, "pressed %d", (int)te->mouseButton);
+
+        spTextField tf = s->getChildT<TextField>(name);
+        tf->setText(ev->type == TouchEvent::TOUCH_DOWN ? name : "");
         updateLocalPos(ev);
     }
 
@@ -110,10 +124,10 @@ public:
         spSprite Green = createRect("Green", Color::Green, Vector2(100, 25), Vector2(100, 150));
         Green->attachTo(Orange);
 
-        spSprite Beige = createRect("Beige", Color::Beige, Vector2(150, 150), Vector2(250, 100));
+        spSprite Beige = createRect("Beige", Color::Beige, Vector2(150, 150), Vector2(260, 100));
         Beige->attachTo(Orange);
 
-        spSprite LightGreen = createRect("LightGreen", Color::LightGreen, Vector2(180, -50), Vector2(50, 200));
+        spSprite LightGreen = createRect("LightGreen", Color::LightGreen, Vector2(180, -50), Vector2(65, 200));
         LightGreen->attachTo(Beige);
 
 
@@ -174,14 +188,15 @@ public:
                      "\n"
                      "current target: %s\n"
                      "local position: %d %d\n"
+                     "button: %d\n"
                      ,
                      n,
                      eventName,
                      te->target->getName().c_str(),
                      (int)te->position.x, (int)te->position.y,
                      te->currentTarget->getName().c_str(),
-                     (int)te->localPosition.x, (int)te->localPosition.y
-
+                     (int)te->localPosition.x, (int)te->localPosition.y,
+                     (int)te->mouseButton
                     );
 
 

+ 0 - 1
examples/HelloWorld/src/example.cpp

@@ -1,6 +1,5 @@
 #include "oxygine-framework.h"
 #include <functional>
-#include "res/SingleResAnim.h"
 using namespace oxygine;
 
 //it is our resources

+ 31 - 1
oxygine/SDL/android/lib/src/org/oxygine/lib/HttpRequests.java

@@ -104,7 +104,8 @@ class HttpRequest extends AsyncTask<RequestDetails, Integer, String> {
             else
                 connection = (HttpURLConnection) url.openConnection();
 
-
+            connection.setInstanceFollowRedirects(true);
+            
             if (details.postData != null) {
                 connection.setDoOutput(true);
                 //connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
@@ -114,6 +115,35 @@ class HttpRequest extends AsyncTask<RequestDetails, Integer, String> {
 
             //connection.connect();
 
+            /*
+
+            boolean redirect = false;
+
+            int status = conn.getResponseCode();
+            if (status != HttpURLConnection.HTTP_OK) {
+                if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER)
+                    redirect = true;
+            }
+
+            if (redirect) {
+
+                // get redirect url from "location" header field
+                String newUrl = conn.getHeaderField("Location");
+
+                // get the cookie if need, for login
+                String cookies = conn.getHeaderField("Set-Cookie");
+
+                // open the new connnection again
+                conn = (HttpURLConnection) new URL(newUrl).openConnection();
+                conn.setRequestProperty("Cookie", cookies);
+                conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
+                conn.addRequestProperty("User-Agent", "Mozilla");
+                conn.addRequestProperty("Referer", "google.com");
+
+                System.out.println("Redirect to URL : " + newUrl);
+            }
+            */
+
             // expect HTTP 200 OK, so we don't mistakenly save error report
             // instead of the file
             if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {

+ 0 - 8
oxygine/SDL/ios/oxygine/oxygine_ios.xcodeproj/project.pbxproj

@@ -115,8 +115,6 @@
 		C3E86FFF16EBC8EB00052915 /* Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F5616EBC8EB00052915 /* Actor.h */; };
 		C3E8700016EBC8EB00052915 /* AnimationFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F5716EBC8EB00052915 /* AnimationFrame.cpp */; };
 		C3E8700116EBC8EB00052915 /* AnimationFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F5816EBC8EB00052915 /* AnimationFrame.h */; };
-		C3E8700216EBC8EB00052915 /* Blocking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F5916EBC8EB00052915 /* Blocking.cpp */; };
-		C3E8700316EBC8EB00052915 /* Blocking.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F5A16EBC8EB00052915 /* Blocking.h */; };
 		C3E8700416EBC8EB00052915 /* Box9Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F5B16EBC8EB00052915 /* Box9Sprite.cpp */; };
 		C3E8700516EBC8EB00052915 /* Box9Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = C3E86F5C16EBC8EB00052915 /* Box9Sprite.h */; };
 		C3E8700616EBC8EB00052915 /* Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3E86F5D16EBC8EB00052915 /* Button.cpp */; };
@@ -357,8 +355,6 @@
 		C3E86F5616EBC8EB00052915 /* Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Actor.h; path = ../../../src/Actor.h; sourceTree = "<group>"; };
 		C3E86F5716EBC8EB00052915 /* AnimationFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationFrame.cpp; path = ../../../src/AnimationFrame.cpp; sourceTree = "<group>"; };
 		C3E86F5816EBC8EB00052915 /* AnimationFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationFrame.h; path = ../../../src/AnimationFrame.h; sourceTree = "<group>"; };
-		C3E86F5916EBC8EB00052915 /* Blocking.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Blocking.cpp; path = ../../../src/Blocking.cpp; sourceTree = "<group>"; };
-		C3E86F5A16EBC8EB00052915 /* Blocking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Blocking.h; path = ../../../src/Blocking.h; sourceTree = "<group>"; };
 		C3E86F5B16EBC8EB00052915 /* Box9Sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Box9Sprite.cpp; path = ../../../src/Box9Sprite.cpp; sourceTree = "<group>"; };
 		C3E86F5C16EBC8EB00052915 /* Box9Sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Box9Sprite.h; path = ../../../src/Box9Sprite.h; sourceTree = "<group>"; };
 		C3E86F5D16EBC8EB00052915 /* Button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Button.cpp; path = ../../../src/Button.cpp; sourceTree = "<group>"; };
@@ -584,7 +580,6 @@
 				C3E86F5516EBC8EB00052915 /* Actor.cpp */,
 				C3E86F5716EBC8EB00052915 /* AnimationFrame.cpp */,
 				9223E3101A5193E000B2770B /* AsyncTask.cpp */,
-				C3E86F5916EBC8EB00052915 /* Blocking.cpp */,
 				C3E86F5B16EBC8EB00052915 /* Box9Sprite.cpp */,
 				C3E86F5D16EBC8EB00052915 /* Button.cpp */,
 				C3E86F5F16EBC8EB00052915 /* ClipRectActor.cpp */,
@@ -625,7 +620,6 @@
 				C3E86F5616EBC8EB00052915 /* Actor.h */,
 				C3E86F5816EBC8EB00052915 /* AnimationFrame.h */,
 				9223E3111A5193E000B2770B /* AsyncTask.h */,
-				C3E86F5A16EBC8EB00052915 /* Blocking.h */,
 				C3E86F5C16EBC8EB00052915 /* Box9Sprite.h */,
 				C3E86F5E16EBC8EB00052915 /* Button.h */,
 				C3E86F6016EBC8EB00052915 /* ClipRectActor.h */,
@@ -894,7 +888,6 @@
 				C3E86FFF16EBC8EB00052915 /* Actor.h in Headers */,
 				9250AFB31C9B14950060A168 /* TweenOutline.h in Headers */,
 				C3E8700116EBC8EB00052915 /* AnimationFrame.h in Headers */,
-				C3E8700316EBC8EB00052915 /* Blocking.h in Headers */,
 				929AF5671C88AA4000D276ED /* ThreadLoader.h in Headers */,
 				9225533A1CAFA4EF00333A1E /* TweenGlow.h in Headers */,
 				C3E8700516EBC8EB00052915 /* Box9Sprite.h in Headers */,
@@ -1077,7 +1070,6 @@
 				C3E86FFE16EBC8EB00052915 /* Actor.cpp in Sources */,
 				922553391CAFA4EF00333A1E /* TweenGlow.cpp in Sources */,
 				C3E8700016EBC8EB00052915 /* AnimationFrame.cpp in Sources */,
-				C3E8700216EBC8EB00052915 /* Blocking.cpp in Sources */,
 				C3E8700416EBC8EB00052915 /* Box9Sprite.cpp in Sources */,
 				C3E8700616EBC8EB00052915 /* Button.cpp in Sources */,
 				0472E37717F8A2D30016A832 /* ioapi_mem.c in Sources */,

+ 0 - 8
oxygine/SDL/macosx/oxygine_macosx/oxygine_macosx.xcodeproj/project.pbxproj

@@ -17,8 +17,6 @@
 		049B56661871F21E00EF3C66 /* Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55921871F21D00EF3C66 /* Actor.h */; };
 		049B56671871F21E00EF3C66 /* AnimationFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55931871F21D00EF3C66 /* AnimationFrame.cpp */; };
 		049B56681871F21E00EF3C66 /* AnimationFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55941871F21D00EF3C66 /* AnimationFrame.h */; };
-		049B56691871F21E00EF3C66 /* blocking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55951871F21D00EF3C66 /* blocking.cpp */; };
-		049B566A1871F21E00EF3C66 /* blocking.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55961871F21D00EF3C66 /* blocking.h */; };
 		049B566B1871F21E00EF3C66 /* Box9Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55971871F21D00EF3C66 /* Box9Sprite.cpp */; };
 		049B566C1871F21E00EF3C66 /* Box9Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 049B55981871F21D00EF3C66 /* Box9Sprite.h */; };
 		049B566D1871F21E00EF3C66 /* Button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 049B55991871F21D00EF3C66 /* Button.cpp */; };
@@ -258,8 +256,6 @@
 		049B55921871F21D00EF3C66 /* Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Actor.h; path = ../../../src/Actor.h; sourceTree = "<group>"; };
 		049B55931871F21D00EF3C66 /* AnimationFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationFrame.cpp; path = ../../../src/AnimationFrame.cpp; sourceTree = "<group>"; };
 		049B55941871F21D00EF3C66 /* AnimationFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationFrame.h; path = ../../../src/AnimationFrame.h; sourceTree = "<group>"; };
-		049B55951871F21D00EF3C66 /* blocking.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = blocking.cpp; path = ../../../src/blocking.cpp; sourceTree = "<group>"; };
-		049B55961871F21D00EF3C66 /* blocking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = blocking.h; path = ../../../src/blocking.h; sourceTree = "<group>"; };
 		049B55971871F21D00EF3C66 /* Box9Sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Box9Sprite.cpp; path = ../../../src/Box9Sprite.cpp; sourceTree = "<group>"; };
 		049B55981871F21D00EF3C66 /* Box9Sprite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Box9Sprite.h; path = ../../../src/Box9Sprite.h; sourceTree = "<group>"; };
 		049B55991871F21D00EF3C66 /* Button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Button.cpp; path = ../../../src/Button.cpp; sourceTree = "<group>"; };
@@ -531,7 +527,6 @@
 				049B55911871F21D00EF3C66 /* Actor.cpp */,
 				049B55931871F21D00EF3C66 /* AnimationFrame.cpp */,
 				92CE26711A58ABDC003901D6 /* AsyncTask.cpp */,
-				049B55951871F21D00EF3C66 /* blocking.cpp */,
 				049B55971871F21D00EF3C66 /* Box9Sprite.cpp */,
 				049B55991871F21D00EF3C66 /* Button.cpp */,
 				049B559B1871F21D00EF3C66 /* ClipRectActor.cpp */,
@@ -571,7 +566,6 @@
 				049B55921871F21D00EF3C66 /* Actor.h */,
 				049B55941871F21D00EF3C66 /* AnimationFrame.h */,
 				92CE26721A58ABDC003901D6 /* AsyncTask.h */,
-				049B55961871F21D00EF3C66 /* blocking.h */,
 				049B55981871F21D00EF3C66 /* Box9Sprite.h */,
 				049B559A1871F21D00EF3C66 /* Button.h */,
 				049B559C1871F21D00EF3C66 /* ClipRectActor.h */,
@@ -989,7 +983,6 @@
 				049B57181871F21E00EF3C66 /* AtlasTool.h in Headers */,
 				049B56EA1871F21E00EF3C66 /* oxygine-framework.h in Headers */,
 				049B571F1871F21E00EF3C66 /* VisualStyle.h in Headers */,
-				049B566A1871F21E00EF3C66 /* blocking.h in Headers */,
 				AD14D5621D72B19600182666 /* Image.h in Headers */,
 				923663591A47561500EB65B3 /* Serializable.h in Headers */,
 				049B56741871F21E00EF3C66 /* closure_impl.h in Headers */,
@@ -1133,7 +1126,6 @@
 				049B56BA1871F21E00EF3C66 /* ZipFileSystem.cpp in Sources */,
 				CEC2CFF61C47274C00450163 /* Material.cpp in Sources */,
 				049B56861871F21E00EF3C66 /* VideoDriverGL.cpp in Sources */,
-				049B56691871F21E00EF3C66 /* blocking.cpp in Sources */,
 				049B56AC1871F21E00EF3C66 /* STDFileSystem.cpp in Sources */,
 				049B56C21871F21E00EF3C66 /* TreeInspector.cpp in Sources */,
 				92CE266C1A58AADB003901D6 /* HttpRequestCocoaTask.mm in Sources */,

+ 0 - 2
oxygine/SDL/win32/oxygine.vcxproj

@@ -115,7 +115,6 @@
     <ClCompile Include="..\..\src\Actor.cpp" />
     <ClCompile Include="..\..\src\AnimationFrame.cpp" />
     <ClCompile Include="..\..\src\AsyncTask.cpp" />
-    <ClCompile Include="..\..\src\Blocking.cpp" />
     <ClCompile Include="..\..\src\Box9Sprite.cpp" />
     <ClCompile Include="..\..\src\Button.cpp" />
     <ClCompile Include="..\..\src\ClipRectActor.cpp" />
@@ -219,7 +218,6 @@
     <ClInclude Include="..\..\src\Actor.h" />
     <ClInclude Include="..\..\src\AnimationFrame.h" />
     <ClInclude Include="..\..\src\AsyncTask.h" />
-    <ClInclude Include="..\..\src\Blocking.h" />
     <ClInclude Include="..\..\src\Box9Sprite.h" />
     <ClInclude Include="..\..\src\Button.h" />
     <ClInclude Include="..\..\src\ClipRectActor.h" />

+ 0 - 6
oxygine/SDL/win32/oxygine.vcxproj.filters

@@ -201,9 +201,6 @@
     <ClCompile Include="..\..\src\AnimationFrame.cpp">
       <Filter>src</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\Blocking.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\Box9Sprite.cpp">
       <Filter>src</Filter>
     </ClCompile>
@@ -569,9 +566,6 @@
     <ClInclude Include="..\..\src\AnimationFrame.h">
       <Filter>src</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\Blocking.h">
-      <Filter>src</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\Box9Sprite.h">
       <Filter>src</Filter>
     </ClInclude>

+ 32 - 51
oxygine/src/Actor.cpp

@@ -32,16 +32,15 @@ namespace oxygine
         _zOrder(0),
         _scale(1, 1),
         _rotation(0),
-        _flags(flag_visible | flag_touchEnabled | flag_touchChildrenEnabled | flag_childrenRelative | flag_fastTransform),
+        _flags(flag_visible | flag_touchEnabled | flag_touchChildrenEnabled | flag_fastTransform),
         _parent(0),
         _alpha(255),
-        _pressed(0),
-        _overred(0),
         _stage(0),
         _material(0)
     {
         _transform.identity();
         _transformInvert.identity();
+        _pressedOvered = 0;
     }
 
     void Actor::copyFrom(const Actor& src, cloneOptions opt)
@@ -58,8 +57,8 @@ namespace oxygine
         _flags = src._flags;
         _parent = 0;
         _alpha = src._alpha;
-        _overred = 0;
-        _pressed = 0;
+
+        _pressedOvered = 0;
 
         _transform = src._transform;
         _transformInvert = src._transformInvert;
@@ -124,8 +123,7 @@ namespace oxygine
         _stage->removeEventListeners(this);
         _stage = 0;
 
-        _pressed = 0;
-        _overred = 0;
+        _pressedOvered = 0;
 
         spActor actor = _children._first;
         while (actor)
@@ -276,9 +274,9 @@ namespace oxygine
         return stream.str();
     }
 
-    pointer_index Actor::getPressed() const
+    pointer_index Actor::getPressed(MouseButton b) const
     {
-        return _pressed;
+        return _pressedButton[b];
     }
 
     pointer_index Actor::getOvered() const
@@ -286,10 +284,11 @@ namespace oxygine
         return _overred;
     }
 
-    void Actor::setNotPressed()
+    void Actor::setNotPressed(MouseButton b)
     {
-        _pressed = 0;
-        _getStage()->removeEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
+        _pressedButton[b] = 0;
+        if (_pressedOvered == _overred)//!_pressed[0] && !_pressed[1] && !_pressed[2])
+            _getStage()->removeEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
 
         updateStatePressed();
     }
@@ -297,10 +296,10 @@ namespace oxygine
     void Actor::_onGlobalTouchUpEvent(Event* ev)
     {
         TouchEvent* te = safeCast<TouchEvent*>(ev);
-        if (te->index != _pressed)
+        if (te->index != _pressedButton[te->mouseButton])
             return;
 
-        setNotPressed();
+        setNotPressed(te->mouseButton);
 
         TouchEvent up = *te;
         up.bubbles = false;
@@ -351,11 +350,12 @@ namespace oxygine
         if (event->type == TouchEvent::TOUCH_DOWN)
         {
             TouchEvent* te = safeCast<TouchEvent*>(event);
-            if (!_pressed)
+            if (!_pressedButton[te->mouseButton])
             {
-                _pressed = te->index;
-                _getStage()->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
+                if (_pressedOvered == _overred)//!_pressed[0] && !_pressed[1] && !_pressed[2])
+                    _getStage()->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &Actor::_onGlobalTouchUpEvent));
 
+                _pressedButton[te->mouseButton] = te->index;
                 updateStatePressed();
             }
         }
@@ -365,14 +365,14 @@ namespace oxygine
         if (event->type == TouchEvent::TOUCH_UP)
         {
             TouchEvent* te = safeCast<TouchEvent*>(event);
-            if (_pressed == te->index)
+            if (_pressedButton[te->mouseButton] == te->index)
             {
                 click = *te;
                 click.type = TouchEvent::CLICK;
                 click.bubbles = false;
                 //will be dispatched later after UP
 
-                setNotPressed();
+                setNotPressed(te->mouseButton);
             }
         }
 
@@ -730,23 +730,21 @@ namespace oxygine
                      _pos.x, _pos.y);
         }
 
-        if (_flags & flag_childrenRelative)
+        Vector2 offset;
+        if (_flags & flag_anchorInPixels)
         {
-            Vector2 offset;
-            if (_flags & flag_anchorInPixels)
-            {
-                offset.x = -_anchor.x;
-                offset.y = -_anchor.y;
-            }
-            else
-            {
-                offset.x = -float(_size.x * _anchor.x);
-                offset.y = -float(_size.y * _anchor.y);//todo, what to do? (per pixel quality)
-            }
-
-            tr.translate(offset);
+            offset.x = -_anchor.x;
+            offset.y = -_anchor.y;
+        }
+        else
+        {
+            offset.x = -float(_size.x * _anchor.x);
+            offset.y = -float(_size.y * _anchor.y);//todo, what to do? (per pixel quality)
         }
 
+        tr.translate(offset);
+
+
         _transform = tr;
         _flags &= ~flag_transformDirty;
 
@@ -1135,26 +1133,9 @@ namespace oxygine
         rs.material->render(this, rs);
     }
 
-    RectF Actor::calcDestRectF(const RectF& destRect_, const Vector2& size) const
-    {
-        RectF destRect = destRect_;
-        if (!(_flags & flag_childrenRelative))
-        {
-            Vector2 a;
-
-            if ((_flags & flag_anchorInPixels))
-                a = Vector2(_anchor.x, _anchor.y);
-            else
-                a = Vector2(_anchor.x * size.x, _anchor.y * size.y);
-
-            destRect.pos -= a;
-        }
-        return destRect;
-    }
-
     RectF Actor::getDestRect() const
     {
-        return calcDestRectF(RectF(Vector2(0, 0), getSize()), getSize());
+        return RectF(Vector2(0, 0), getSize());
     }
 
     spTween Actor::_addTween(spTween tween, bool rel)

+ 25 - 18
oxygine/src/Actor.h

@@ -15,7 +15,6 @@
 namespace oxygine
 {
     class Event;
-    typedef char pointer_index;
 
     typedef unsigned int dumpOptions;
 
@@ -145,12 +144,11 @@ namespace oxygine
         const spClock&      getClock() const;
         virtual RectF       getDestRect() const;
         /**returns touch id if actor is pressed down*/
-        pointer_index       getPressed() const;
+        pointer_index       getPressed(MouseButton b = MouseButton_Touch) const;
         /**returns touch id if actor is moused overred*/
         pointer_index       getOvered() const;
         bool                getTouchEnabled() const { return (_flags & flag_touchEnabled) != 0; }
         bool                getTouchChildrenEnabled() const { return (_flags & flag_touchChildrenEnabled) != 0; }
-        bool                getChildrenRelative() const {return (_flags & flag_childrenRelative) != 0;;}
         UpdateCallback      getCallbackDoUpdate() const {return _cbDoUpdate;}
         Material*           getMaterial() { return _material; }
         //RenderCallback        getCallbackDoRender() const {return _cbDoRender;}
@@ -193,8 +191,6 @@ namespace oxygine
         void setRotation(float angle);
         /**Sets rotation angle in degrees. Converts internally to radians. (use setRotation!)*/
         void setRotationDegrees(float angle);
-        /**This option is connected with Anchor. By default value is True*/
-        void setChildrenRelative(bool r) {_flags &= ~flag_childrenRelative; if (r) _flags |= flag_childrenRelative;}
 
         /**Sets Size of Actor. Size doesn't scale contents of Actor. Size only affects event handling and rendering if you change Anchor*/
         void setSize(const Vector2&);
@@ -328,7 +324,7 @@ namespace oxygine
         /**Returns Stage where Actor attached to. Used for multi stage (window) mode*/
         Stage*              _getStage();
 
-        void setNotPressed();
+        void setNotPressed(MouseButton b);
 
         bool internalRender(RenderState& rs, const RenderState& parentRS);
 
@@ -357,9 +353,11 @@ namespace oxygine
         static unsigned short& _getFlags(Actor* actor) { return actor->_flags; }
 
         void _onGlobalTouchUpEvent(Event*);
+        void _onGlobalTouchUpEvent1(Event*);
+        void _onGlobalTouchUpEvent2(Event*);
         void _onGlobalTouchMoveEvent(Event*);
 
-        RectF calcDestRectF(const RectF& destRect, const Vector2& size) const;
+        const Vector2& _getSize() const { return _size; }
         void _setSize(const Vector2&);
         virtual void sizeChanged(const Vector2& size);
         Actor*  _getDescendant(const std::string& name);
@@ -385,13 +383,12 @@ namespace oxygine
             flag_anchorInPixels         = 1,
             flag_visible                = 1 << 1,
             flag_touchEnabled           = 1 << 2,
-            flag_childrenRelative       = 1 << 3,
-            flag_transformDirty         = 1 << 4,
-            flag_transformInvertDirty   = 1 << 5,
-            flag_touchChildrenEnabled   = 1 << 6,
-            flag_cull                   = 1 << 7,
-            flag_fastTransform          = 1 << 8,
-            flag_reserved               = 1 << 9,
+            flag_transformDirty         = 1 << 3,
+            flag_transformInvertDirty   = 1 << 4,
+            flag_touchChildrenEnabled   = 1 << 5,
+            flag_cull                   = 1 << 6,
+            flag_fastTransform          = 1 << 7,
+            flag_reserved               = 1 << 8,
             flag_last                   = flag_reserved
         };
 
@@ -407,17 +404,27 @@ namespace oxygine
 
         children _children;
 
-        pointer_index _pressed;
-        pointer_index _overred;
+        union
+        {
+            struct
+            {
+                pointer_index _pressedButton[MouseButton_Num];
+                pointer_index _overred;
+            };
+            OXYGINE_DEPRECATED
+            pointer_index _pressed;//for compatibility, deprecated
+            int32_t _pressedOvered;
+        };
+
 
     private:
-        short   _zOrder;
 
         Vector2 _pos;
         Vector2 _anchor;
         Vector2 _scale;
         Vector2 _size;
         float   _rotation;
+        short   _zOrder;
     };
 
     Vector2 convert_local2stage(spActor child, const Vector2& pos, spActor root = 0);
@@ -453,4 +460,4 @@ namespace oxygine
 }
 
 
-EDITOR_INCLUDE(Actor);
+EDITOR_INCLUDE(Actor);

+ 2 - 0
oxygine/src/AnimationFrame.cpp

@@ -82,6 +82,8 @@ namespace oxygine
 
     AnimationFrame::AnimationFrame(spNativeTexture t)
     {
+        _row = _column = 0;
+        _resAnim = 0;
         _diffuse.base = t;
         _diffuse.premultiplied = true;
         _srcRect = RectF(0, 0, 1, 1);

+ 1 - 0
oxygine/src/AnimationFrame.h

@@ -61,6 +61,7 @@ namespace oxygine
         void            setResAnim(ResAnim* rs) {_resAnim = rs;}
         void            setDiffuse(const Diffuse& d) { _diffuse = d; }
         void            setSize(const Vector2& size) {_frameSize = size;}
+        void            setSize(float w, float h) { setSize(Vector2(w, h)); }
         void            setHitTestData(const HitTestData& ad) { _hittest = ad; }
         void            setRow(int v) {_row = v;}
         void            setColumn(int v) {_column = v;}

+ 1 - 1
oxygine/src/Box9Sprite.h

@@ -66,4 +66,4 @@ namespace oxygine
 }
 
 
-EDITOR_INCLUDE(Box9Sprite);
+EDITOR_INCLUDE(Box9Sprite);

+ 15 - 4
oxygine/src/Button.cpp

@@ -34,15 +34,26 @@ namespace oxygine
     void Button::_mouseEvent(Event* event)
     {
         TouchEvent* me = safeCast<TouchEvent*>(event);
-
-        switch (event->type)
+        if (event->type == TouchEvent::CLICK)
         {
-            case TouchEvent::CLICK:
+            if (me->mouseButton == MouseButton_Left)
             {
                 event->phase = Event::phase_target;
                 event->target = this;
             }
-            break;
+            else
+            {
+                event->stopImmediatePropagation();
+            }
+
+            return;
+        }
+
+        if (me->mouseButton != MouseButton_Left)
+            return;
+
+        switch (event->type)
+        {
             case TouchEvent::OVER:
             {
                 if (!_btnOvered)

+ 1 - 1
oxygine/src/Button.h

@@ -46,4 +46,4 @@ namespace oxygine
     };
 }
 
-EDITOR_INCLUDE(Button);
+EDITOR_INCLUDE(Button);

+ 5 - 0
oxygine/src/ColorRectSprite.cpp

@@ -25,6 +25,11 @@ namespace oxygine
         rs.material->doRender(this, rs);
     }
 
+    void ColorRectSprite::sizeChanged(const Vector2& size)
+    {
+        Actor::sizeChanged(size);
+    }
+
     void ColorRectSprite::serialize(serializedata* data)
     {
         VStyleActor::serialize(data);

+ 5 - 0
oxygine/src/ColorRectSprite.h

@@ -19,6 +19,11 @@ namespace oxygine
 
         void doRender(const RenderState& rs);
 
+        RectF getDestRect() const OVERRIDE { return Actor::getDestRect(); }
+
+    protected:
+        void sizeChanged(const Vector2& size) OVERRIDE;
+
     private:
     };
 }

+ 8 - 0
oxygine/src/EventDispatcher.h

@@ -6,17 +6,25 @@
 
 namespace oxygine
 {
+
     typedef int eventType;
     class Event;
 
 #define makefourcc(a,b,c,d) ( ((unsigned int)a) | (((unsigned int)b)<< 8) | (((unsigned int)c)<<16) | (((unsigned int)d)<<24))
 
+#ifdef OX_HAS_CPP11
+    inline int error_eventID_should_be_size_of_4_chars(int x) { return x; }
+    constexpr size_t constStringLength(const char* str) { return (*str == 0) ? 0 : constStringLength(str + 1) + 1; }
+    constexpr int EventIDc11(const char* str) { return constStringLength(str) == 4 ? makefourcc(str[0], str[1], str[2], str[3]) : error_eventID_should_be_size_of_4_chars(0); }
+#endif
+
     //eventID('_', '_', '_', '_')
 #define eventID(a,b,c,d) makefourcc(a,b,c,d)
 
     /*sysEventID is used for system Oxygine events, use 'eventID' for custom game events*/
 #define sysEventID(b,c,d) makefourcc(0xA,b,c,d)
 
+#define  EventID(str) EventIDc11(str)
 
     typedef Closure<void (Event* ev)> EventCallback;
 

+ 6 - 13
oxygine/src/Font.cpp

@@ -32,14 +32,11 @@ namespace oxygine
         _sdf = sdf;
         _size = realSize;
         _baselineDistance = baselineDistance;
-        _lineHeight = lineHeight;
-        //_glyphs.reserve(200);
     }
 
     void Font::addGlyph(const glyph& gl)
     {
         _glyphs.insert(gl);
-        //_glyphs.push_back(gl);
     }
 
     bool glyphFindPred(const glyph& g, int code)
@@ -52,10 +49,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 +63,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);
         }
 
@@ -98,11 +96,6 @@ namespace oxygine
         return _scale;
     }
 
-    int Font::getLineHeight() const
-    {
-        return _lineHeight;
-    }
-
     bool Font::isSDF() const
     {
         return _sdf;

+ 12 - 7
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:
@@ -52,18 +58,18 @@ namespace oxygine
         void sortGlyphs() {}
 
         void setScale(float scale) { _scale = scale; }
+        void setBaselineDistance(int d) { _baselineDistance = d; }
 
-        const glyph*    getGlyph(int code) const;
+        const glyph*    getGlyph(int code, const glyphOptions& opt) const;
         int             getBaselineDistance() const;
         int             getSize() const;
         float           getScale() const;
-        int             getLineHeight() const;
         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;
@@ -77,6 +83,5 @@ namespace oxygine
 
         int _size;
         int _baselineDistance;
-        int _lineHeight;
     };
 }

+ 10 - 0
oxygine/src/Image.cpp

@@ -805,6 +805,16 @@ namespace oxygine
         return lock(lock_read | lock_write, &rect);
     }
 
+    ImageData Image::lock(int x, int y, int w, int h)
+    {
+        return lock(Rect(x, y, w, h));
+    }
+
+    ImageData Image::lock(int x, int y)
+    {
+        return lock(Rect(x, y, _image.w - x, _image.h - y));
+    }
+
     void Image::unlock()
     {
 

+ 3 - 0
oxygine/src/Image.h

@@ -46,6 +46,9 @@ namespace oxygine
         ImageData   lock(lock_flags f = 0, const Rect* pRect = 0);
         ImageData   lock(const Rect* pRect);
         ImageData   lock(const Rect& pRect);
+        ImageData   lock(int x, int y, int w, int h);
+        ImageData   lock(int x, int y);
+
         void        unlock();
         void        toPOT(Image& dest);
 

+ 15 - 1
oxygine/src/Input.cpp

@@ -17,6 +17,9 @@ namespace oxygine
 
     void Input::sendPointerButtonEvent(spStage stage, MouseButton button, float x, float y, float pressure, int type, PointerState* ps)
     {
+        if (!_multiTouch && ps->getIndex() != 1 && ps != &_pointerMouse)
+            return;
+
         Vector2 p(x, y);
 
         TouchEvent me(type, true, p);
@@ -43,6 +46,10 @@ namespace oxygine
 
     void Input::sendPointerMotionEvent(spStage stage, float x, float y, float pressure, PointerState* ps)
     {
+
+        if (!_multiTouch && ps->getIndex() != 1 && ps != &_pointerMouse)
+            return;
+
         TouchEvent me(TouchEvent::MOVE, true, Vector2(x, y));
         me.index = ps->getIndex();
         me.pressure = pressure;
@@ -69,6 +76,7 @@ namespace oxygine
         for (int i = 0; i < MAX_TOUCHES; ++i)
             _pointers[i].init(i + 1);
         memset(_ids, 0, sizeof(_ids));
+        _multiTouch = true;
     }
 
     Input::~Input()
@@ -80,8 +88,14 @@ namespace oxygine
     {
     }
 
-    PointerState* Input::getTouchByIndex(int index)
+    void Input::multiTouchEnabled(bool en)
+    {
+        _multiTouch = en;
+    }
+
+    PointerState* Input::getTouchByIndex(pointer_index index_)
     {
+        int index = index_;
         if (index == MAX_TOUCHES + 1)
             return &_pointerMouse;
         index -= 1;

+ 7 - 3
oxygine/src/Input.h

@@ -22,8 +22,10 @@ namespace oxygine
 
         void cleanup();
 
-        /**id should be in range [1, MAX_TOUCHES]*/
-        PointerState* getTouchByIndex(int index);
+        void multiTouchEnabled(bool en);
+
+        /**index should be in range [1, MAX_TOUCHES]*/
+        PointerState* getTouchByIndex(pointer_index index);
 
 #ifndef __S3E__
         int touchID2index(int64 id);
@@ -41,5 +43,7 @@ namespace oxygine
         void sendPointerButtonEvent(spStage, MouseButton button, float x, float y, float pressure, int type, PointerState*);
         void sendPointerMotionEvent(spStage, float x, float y, float pressure, PointerState*);
         void sendPointerWheelEvent(spStage, int scroll, PointerState*);
+
+        bool _multiTouch;
     };
-}
+}

+ 1 - 1
oxygine/src/MaskedSprite.h

@@ -32,4 +32,4 @@ namespace oxygine
     };
 }
 
-EDITOR_INCLUDE(MaskedSprite);
+EDITOR_INCLUDE(MaskedSprite);

+ 3 - 3
oxygine/src/PointerState.cpp

@@ -2,14 +2,14 @@
 #include "Actor.h"
 namespace oxygine
 {
-    PointerState::PointerState(): _index(0)
+    PointerState::PointerState(): _index(1)
     {
         init(_index);
     }
 
-    void PointerState::init(int pointerIndex)
+    void PointerState::init(pointer_index index)
     {
-        _index = pointerIndex;
+        _index = index;
         _pressed = 0;
         _position.setZero();
     }

+ 7 - 5
oxygine/src/PointerState.h

@@ -13,7 +13,9 @@ namespace oxygine
         MouseButton_Touch = 0,
         MouseButton_Left = 0,
         MouseButton_Middle = 1,
-        MouseButton_Right = 2
+        MouseButton_Right = 2,
+        MouseButton_Num = 3
+
     };
 
     class PointerState
@@ -21,17 +23,17 @@ namespace oxygine
     public:
         PointerState();
 
-        void init(int pointerIndex);
+        void init(pointer_index pointerIndex);
 
         bool            isPressed(MouseButton mb = MouseButton_Touch) const;
-        int             getIndex() const {return _index;}
+        pointer_index   getIndex() const {return _index;}
         const Vector2&  getPosition() const {return _position;}
 
     private:
         friend class Input;
 
-        int _index;
-        int _pressed;
         Vector2 _position;
+        int _pressed;
+        pointer_index _index;
     };
 }

+ 4 - 9
oxygine/src/ProgressBar.cpp

@@ -42,7 +42,10 @@ namespace oxygine
 
     ProgressBar::ProgressBar(): _progress(1.0f), _direction(dir_0)
     {
-
+        AnimationFrame f(STDRenderer::white);
+        f.setSize(200, 60);
+        f.setDestRect(RectF(0, 0, 200, 60));
+        setAnimFrame(f);
     }
 
     ProgressBar::~ProgressBar()
@@ -101,8 +104,6 @@ namespace oxygine
 
     void ProgressBar::doRender(const RenderState& rs)
     {
-        if (_progress == 0)
-            return;
         if (((_direction != __dir_radial_ccw) && (_direction != dir_radial_cw)) || (_progress == 1.0f))
         {
             inherited::doRender(rs);
@@ -348,12 +349,6 @@ namespace oxygine
 
         return stream.str();
     }
-
-    RectF ProgressBar::getDestRect() const
-    {
-        return calcDestRectF(_frame.getDestRect(), _frame.getSize());
-    }
-
     void ProgressBar::setProgress(float f)
     {
         _progress = scalar::clamp(f, 0.0f, 1.0f);

+ 0 - 1
oxygine/src/ProgressBar.h

@@ -46,7 +46,6 @@ namespace oxygine
     private:
         void doRender(const RenderState& rs);
 
-        RectF getDestRect() const OVERRIDE;
         virtual void _update();
 
         void animFrameChanged(const AnimationFrame& f);

+ 2 - 1
oxygine/src/SlidingActor.cpp

@@ -325,7 +325,8 @@ namespace oxygine
                         spActor act = safeSpCast<Actor>(_holded);
                         while (act && act.get() != _content.get())
                         {
-                            act->setNotPressed();
+                            for (int i = 0; i < MouseButton_Num; ++i)
+                                act->setNotPressed((MouseButton)i);
                             act = act->getParent();
                         }
 

+ 19 - 6
oxygine/src/Sprite.cpp

@@ -9,7 +9,7 @@
 
 namespace oxygine
 {
-    Sprite::Sprite()
+    Sprite::Sprite(): _localScale(1.0f, 1.0f)
     {
 
     }
@@ -29,6 +29,7 @@ namespace oxygine
         inherited::copyFrom(src, opt);
 
         _frame = src._frame;
+        _localScale = src._localScale;
         animFrameChanged(_frame);
 
         _vstyle = src._vstyle;
@@ -61,6 +62,9 @@ namespace oxygine
         if (_flags & flag_manageResAnim)
             stream << "manageResAnim=true";
 
+        if (_localScale != Vector2(1.0f, 1.0f))
+            stream << " localScale=(" << _localScale.x << "," << _localScale.y << ")";
+
         stream << Actor::dump(options);
         return stream.str();
     }
@@ -209,7 +213,8 @@ namespace oxygine
             _frame = frame.getFlipped(flipY, flipX);
         else
             _frame = frame;
-        setSize(_frame.getSize());
+        _setSize(_frame.getSize().mult(_localScale));
+
 
         animFrameChanged(_frame);
     }
@@ -219,12 +224,20 @@ namespace oxygine
 
     }
 
-    RectF Sprite::getDestRect() const
+    void Sprite::sizeChanged(const Vector2& size)
     {
-        if (_frame.getDiffuse().base)
-            return calcDestRectF(_frame.getDestRect(), _frame.getSize());
+        Actor::sizeChanged(size);
+        const Vector2& sz = _frame.getSize();
+        _localScale.x = size.x / sz.x;
+        _localScale.y = size.y / sz.y;
+    }
 
-        return Actor::getDestRect();
+    RectF Sprite::getDestRect() const
+    {
+        RectF r = _frame.getDestRect();
+        r.pos = r.pos.mult(_localScale);
+        r.size = r.size.mult(_localScale);
+        return r;
     }
 
 

+ 2 - 0
oxygine/src/Sprite.h

@@ -66,7 +66,9 @@ namespace oxygine
         };
         virtual void changeAnimFrame(const AnimationFrame& f);
         virtual void animFrameChanged(const AnimationFrame& f);
+        void sizeChanged(const Vector2& size) OVERRIDE;
 
+        Vector2 _localScale;
         AnimationFrame _frame;
     };
 }

+ 2 - 2
oxygine/src/Stage.cpp

@@ -117,9 +117,9 @@ namespace oxygine
 
     RectF Stage::getDestRect() const
     {
+        OX_ASSERT(0);
         Vector2 s = getSize() + getPosition();
-        RectF r = calcDestRectF(RectF(-getPosition(), s), s);
-        return r;
+        return RectF(-getPosition(), s);
     }
 
     /*

+ 13 - 0
oxygine/src/TextField.cpp

@@ -85,6 +85,12 @@ namespace oxygine
         needRebuild();
     }
 
+    void TextField::setBaselineScale(float s)
+    {
+        _style.baselineScale = s;
+        needRebuild();
+    }
+
     void TextField::setKerning(int kerning)
     {
         _style.kerning = kerning;
@@ -250,6 +256,11 @@ namespace oxygine
         return _style.weight;
     }
 
+    float TextField::getBaselineScale() const
+    {
+        return _style.baselineScale;
+    }
+
     text::Symbol* TextField::getSymbolAt(int pos) const
     {
         return const_cast<TextField*>(this)->getRootNode()->getSymbol(pos);
@@ -414,6 +425,7 @@ namespace oxygine
         setAttr(node, "valign", _style.vAlign, def.vAlign);
         setAttr(node, "halign", _style.hAlign, def.hAlign);
         setAttr(node, "multiline", _style.multiline, def.multiline);
+        setAttr(node, "baselineScale", _style.baselineScale, def.baselineScale);
         setAttr(node, "breakLongWords", _style.breakLongWords, def.breakLongWords);
         if (_style.font)
             node.append_attribute("font").set_value(_style.font->getName().c_str());
@@ -434,6 +446,7 @@ namespace oxygine
         _style.fontSize = node.attribute("fontsize2scale").as_int(def.fontSize);
         _style.linesOffset = node.attribute("linesOffset").as_int(def.linesOffset);
         _style.kerning = node.attribute("kerning").as_int(def.kerning);
+        _style.baselineScale = node.attribute("baselineScale").as_float(def.baselineScale);
         const char* fnt = node.attribute("font").as_string(0);
         if (fnt && *fnt)
         {

+ 3 - 0
oxygine/src/TextField.h

@@ -46,6 +46,7 @@ namespace oxygine
         const Color&                getOutlineColor() const;
         float                       getOutline() const;
         float                       getWeight() const;
+        float                       getBaselineScale() const;
 
 
         bool getBounds(RectF&) const OVERRIDE;
@@ -61,6 +62,8 @@ namespace oxygine
         void setBreakLongWords(bool val);
         /**Overwrites TextStyle linesOffset*/
         void setLinesOffset(int offset);
+        /**Overwrites TextStyle baselineScale*/
+        void setBaselineScale(float scale);
         /**Overwrites TextStyle kerning*/
         void setKerning(int kerning);
         /**Overwrites TextStyle scale2Size. deprecated, use setFontSize*/

+ 8 - 1
oxygine/src/TextStyle.h

@@ -40,7 +40,9 @@ namespace oxygine
             breakLongWords(false),
             outline(0.0f),
             outlineColor(Color::Black),
-            weight(0.5f) {}
+            weight(0.5f),
+            baselineScale(1.0f),
+            options(0) {}
 
         const ResFont* font;
 
@@ -49,6 +51,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;
@@ -64,6 +67,7 @@ namespace oxygine
         float outline;//works only with SD fonts, disabled by default = 0.0f, 0.5 - max outline
         Color outlineColor;//works only with SD fonts
         float weight;//works only with SD fonts, font weight, default = 0.5f,  0.0 - bold, 1.0 - thin
+        float baselineScale;//baseline distance multiplier
 
 
 
@@ -81,6 +85,8 @@ namespace oxygine
         TextStyle alignMiddle() const { TextStyle st = *this; st.vAlign = VALIGN_MIDDLE; st.hAlign = HALIGN_MIDDLE; return st; }
 
         TextStyle withHOffset(int offset) const { TextStyle st = *this; st.linesOffset = offset; return st; }
+        TextStyle withBaselineScale(float s) const { TextStyle st = *this; st.baselineScale = s; return st; }
+
         TextStyle withKerning(int kerning) const { TextStyle st = *this; st.kerning = kerning; return st; }
         TextStyle withMultiline(bool multiline = true) const { TextStyle st = *this; st.multiline = multiline; return st; }
         TextStyle withColor(const Color& color) const { TextStyle st = *this; st.color = color; return st; }
@@ -90,6 +96,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);

+ 0 - 1
oxygine/src/TouchEvent.h

@@ -3,7 +3,6 @@
 #undef OUT
 namespace oxygine
 {
-    typedef char pointer_index;
     class PointerState;
 
     class TouchEvent : public Event

+ 0 - 153
oxygine/src/blocking.cpp

@@ -1,153 +0,0 @@
-#include "blocking.h"
-#include "Clock.h"
-#include "Tween.h"
-#include "Stage.h"
-
-#if _MSC_VER
-#define __func__ __FUNCTION__
-#endif
-
-namespace oxygine
-{
-    namespace blocking
-    {
-        std::list<coroutine::handle> blocked;
-
-        void schedule(coroutine::handle fiber)
-        {
-            blocked.push_back(fiber);
-        }
-
-        void resumeAll()
-        {
-            std::list<coroutine::handle> __blocked(blocked);
-            blocked.clear();
-            for (std::list<coroutine::handle>::iterator i = __blocked.begin(); i != __blocked.end(); ++i)
-            {
-                coroutine::handle y = *i;
-                coroutine::resume(y);
-                if (coroutine::isdead(y))
-                {
-                    coroutine::terminate(y);
-                }
-            }
-        }
-
-        int default_resume()
-        {
-            schedule(coroutine::current());
-            coroutine::resume();
-            return 0;
-        }
-
-        yieldCallback _mainLoopFunc = default_resume;
-        void setYieldCallback(yieldCallback f)
-        {
-            _mainLoopFunc = f;
-        }
-
-        int yield()
-        {
-            OX_ASSERT(_mainLoopFunc);
-#if OXYGINE_NO_YEILD
-            log::error("%s not supported", __func__);
-            return 0;
-#endif
-            return _mainLoopFunc();
-        }
-
-        void waitValue(bool& variable, bool value)
-        {
-#if OXYGINE_NO_YEILD
-            log::error("%s not supported", __func__);
-            return;
-#endif
-            while (variable != value)
-            {
-                yield();
-            }
-        }
-
-        void waitTween(spTween tween)
-        {
-#if OXYGINE_NO_YEILD
-            log::error("%s not supported", __func__);
-            return;
-#endif
-            if (tween->getDelay() == 0)//todo, workaround, fix assert for tweens with delay
-            {
-                OX_ASSERT(tween->isStarted());
-            }
-
-            while (!tween->isDone())
-            {
-                yield();
-            }
-        }
-
-        void waitTime(spClock clock, timeMS time)
-        {
-#if OXYGINE_NO_YEILD
-            log::error("%s not supported", __func__);
-            return;
-#endif
-
-            timeMS start = clock->getTime();
-            while (clock->getTime() - start < time)
-            {
-                yield();
-            }
-        }
-
-        void waitTime(timeMS time)
-        {
-#if OXYGINE_NO_YEILD
-            log::error("%s not supported", __func__);
-            return;
-#endif
-            timeMS start = getTimeMS();
-            while (getTimeMS() - start < time)
-            {
-                yield();
-            }
-        }
-
-
-        class clickWait
-        {
-        public:
-            bool _clicked;
-            timeMS _timeOut;
-
-            void click(Event* ev)
-            {
-                _clicked = true;
-            }
-
-            clickWait(spActor button, timeMS timeOut): _clicked(false), _timeOut(timeOut)
-            {
-                spClock clock = getStage()->getClock();
-                timeMS start = clock->getTime();
-                button->addEventListener(TouchEvent::CLICK, CLOSURE(this, &clickWait::click));
-                do
-                {
-                    yield();
-                    if (timeOut > 0 && (clock->getTime() - start > timeOut))
-                        break;
-                }
-                while (!_clicked);
-
-                button->removeEventListeners(this);
-            }
-        };
-
-        void waitClick(spActor button, timeMS timeOut)
-        {
-#if OXYGINE_NO_YEILD
-            log::error("%s not supported", __func__);
-            return;
-#endif
-            clickWait w(button, timeOut);
-        }
-    }
-}

+ 0 - 41
oxygine/src/blocking.h

@@ -1,41 +0,0 @@
-#pragma once
-#include "oxygine_include.h"
-#include "Actor.h"
-#include "core/coroutines.h"
-
-namespace oxygine
-{
-
-    DECLARE_SMART(Tween, spTween);
-    DECLARE_SMART(Clock, spClock);
-    DECLARE_SMART(Button, spButton);
-    namespace blocking
-    {
-        typedef int (*yieldCallback)();
-
-        /** optional
-            use default coroutines for yield or run your callback internally?
-        */
-#if !OXYGINE_NO_YEILD
-        void setYieldCallback(yieldCallback f);
-
-        /**
-            returns value from yieldCallback
-        */
-        int yield();
-
-        // schedule a coroutine to be resumed later
-        void schedule(coroutine::handle fiber);
-
-        // resume all scheduled coroutines
-        void resumeAll();
-
-        // wait for variable to become equal to value
-        void waitValue(bool& variable, bool value);
-        void waitTween(spTween);
-        void waitTime(spClock clock, timeMS time);
-        void waitTime(timeMS time);
-        void waitClick(spActor, timeMS timeOut = 0);
-#endif
-    }
-}

+ 12 - 0
oxygine/src/core/ImageData.cpp

@@ -142,6 +142,8 @@ namespace oxygine
 
     ImageData ImageData::getRect(const Rect& r) const
     {
+        OX_ASSERT(r.getX() >= 0 && r.getX() <= w);
+        OX_ASSERT(r.getY() >= 0 && r.getY() <= h);
         OX_ASSERT(r.getX() + r.getWidth() <= w);
         OX_ASSERT(r.getY() + r.getHeight() <= h);
 
@@ -151,6 +153,16 @@ namespace oxygine
         return buffer;
     }
 
+    ImageData ImageData::getRect(int x, int y, int w, int h) const
+    {
+        return getRect(Rect(x, y, w, h));
+    }
+
+    ImageData ImageData::getRect(int x, int y) const
+    {
+        return getRect(x, y, w - x, h - y);
+    }
+
     unsigned char* ImageData::getPixelPtr(int x, int y) const
     {
         return (unsigned char*)data + x * bytespp + y * pitch;

+ 2 - 0
oxygine/src/core/ImageData.h

@@ -60,6 +60,8 @@ namespace oxygine
         ~ImageData();
 
         ImageData getRect(const Rect& r) const;
+        ImageData getRect(int x, int y, int w, int h) const;
+        ImageData getRect(int x, int y) const;
         unsigned char* getPixelPtr(int x, int y) const;
 
     public:

+ 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);
+        }
     }
 }

+ 64 - 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,58 @@ 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_one_invSrcAlpha
+        {
+        public:
+            template<class Src, class Dest>
+            void operator()(const Src& srcPixelFormat, Dest& destPixelFormat, const unsigned char* srcData, unsigned char* destData) const
+            {
+                Pixel s;
+                srcPixelFormat.getPixel(srcData, s);
+
+                Pixel d;
+                destPixelFormat.getPixel(destData, d);
+
+#define M(v) std::min(v, 255);
+                unsigned char a = s.a;
+                unsigned char ia = 255 - a;
+                Pixel r;
+                r.r = M((d.r * ia) / 255 + (s.r * a) / 255);
+                r.g = M((d.g * ia) / 255 + (s.g * a) / 255);
+                r.b = M((d.b * ia) / 255 + (s.b * a) / 255);
+                r.a = M((d.a * ia) / 255 + (s.a * a) / 255);
+#undef  M
+
+                destPixelFormat.setPixel(destData, r);
+            }
+        };
+
+
         class op_blend_srcAlpha_invSrcAlpha
         {
         public:
@@ -127,7 +184,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);

+ 2 - 1
oxygine/src/core/ios/ios.h

@@ -15,4 +15,5 @@ namespace oxygine
     bool nsImageLoad(Image& mt, void* pData, int nDatalen, bool premultiplied, TextureFormat format);
 
     void iosGetMemoryUsage(size_t& a);
-}
+    void iosNavigate(const char*);
+}

+ 11 - 1
oxygine/src/core/ios/ios.mm

@@ -2,10 +2,12 @@
 
 #if TARGET_OS_IPHONE
 #import <UIKit/UIImage.h>
+#import <UIKit/UIApplication.h>
 #else
 #import <AppKit/AppKit.h>
 #endif
 
+
 #include "ios.h"
 #include "Image.h"
 
@@ -152,4 +154,12 @@ namespace oxygine
             a = 0;
         }
     }
-}
+    
+    void iosNavigate(const char *url_)
+    {
+#if TARGET_OS_IPHONE
+        NSURL *url = [NSURL URLWithString: [NSString stringWithUTF8String:url_]];
+        [[UIApplication sharedApplication] openURL:url];
+#endif
+    }
+}

+ 10 - 3
oxygine/src/core/oxygine.cpp

@@ -51,6 +51,7 @@
 #include "core/android/jniUtils.h"
 #elif __APPLE__
 #include <TargetConditionals.h>
+#include "ios/ios.h"
 #endif
 
 #ifdef OXYGINE_SDL
@@ -182,6 +183,9 @@ namespace oxygine
 
     namespace core
     {
+        static bool active = true;
+        static bool focus = true;
+
         void focusLost()
         {
             if (!LOST_RESET_CONTEXT)
@@ -260,11 +264,14 @@ namespace oxygine
 
             init0();
 
-
             log::messageln("initialize oxygine");
             if (desc_ptr)
                 desc = *desc_ptr;
 
+
+            focus = true;
+            active = true;
+
 #ifdef __S3E__
             log::messageln("S3E build");
             if (!IwGLInit())
@@ -473,8 +480,6 @@ namespace oxygine
         }
 #endif
 
-        bool active = true;
-        bool focus = true;
 
 
         bool isActive()
@@ -850,6 +855,8 @@ namespace oxygine
                 var url = Pointer_stringify($0);
                 window.open(url, '_blank');
             }, str);
+#elif __APPLE__
+            iosNavigate(str);
 #else
             OX_ASSERT(!"execute not implemented");
 #endif

+ 3 - 2
oxygine/src/core/s3e/HttpRequestTaskS3E.cpp

@@ -2,14 +2,15 @@
 
 namespace oxygine
 {
-    spHttpRequestTask HttpRequestTask::create()
+    static HttpRequestTask* createS3E()
     {
         return new HttpRequestTaskS3E;
     }
 
+
     void HttpRequestTask::init()
     {
-
+        setCustomRequests(createS3E);
     }
 
     void HttpRequestTask::release()

+ 1 - 1
oxygine/src/dev_tools/TreeInspectorPreview.cpp

@@ -54,7 +54,7 @@ namespace oxygine
 
         Material::setCurrent(0);
 
-        setSize(30, 30);
+        //setSize(30, 30);
 
         RectF itemRect = _videoCache._bounds;
         if (itemRect.isEmpty())

+ 0 - 1
oxygine/src/oxygine-framework.h

@@ -7,7 +7,6 @@
 #include "oxygine_include.h"
 #include "Actor.h"
 #include "AnimationFrame.h"
-#include "blocking.h"
 #include "Box9Sprite.h"
 #include "Button.h"
 #include "ClipRectActor.h"

+ 10 - 2
oxygine/src/oxygine_include.h

@@ -110,7 +110,7 @@ namespace oxygine { namespace log { void error(const char* format, ...); } }
 
 #define OXYGINE_RENDERER 4
 
-#define OXYGINE_VERSION 4
+#define OXYGINE_VERSION 5
 
 #ifdef __GNUC__
 #   define OXYGINE_DEPRECATED __attribute__((deprecated))
@@ -139,14 +139,21 @@ typedef signed long long int64;
 #   endif
 #endif
 
+#ifdef OXYGINE_QT
+#define INHERITED(CLASS) private: typedef Editor##CLASS inherited
+#else
 #define INHERITED(CLASS) private: typedef CLASS inherited
+#endif
 
 #ifndef EDITOR_INCLUDE
 #define EDITOR_INCLUDE(CLASS)
-//namespace oxygine {typedef CLASS _##CLASS;}
 #endif
 
 
+#if !defined(__S3E__) && ( (defined(_MSC_VER) && (_MSC_VER > 1800)) || (__cplusplus > 199711L))
+#define OX_HAS_CPP11
+#endif
+
 namespace oxygine
 {
     enum error_policy
@@ -160,6 +167,7 @@ namespace oxygine
     void handleErrorPolicy(error_policy ep, const char* format, ...);
 
     typedef int timeMS;
+    typedef unsigned char pointer_index;
 
     /** returns local app time in milliseconds (1sec = 1000ms). Counting starts from zero*/
     timeMS          getTimeMS();

+ 20 - 5
oxygine/src/res/CreateResourceContext.cpp

@@ -66,13 +66,28 @@ namespace oxygine
         //_alphaTracking = true;
     }
 
+    const char* isRelative(const char* str)
+    {
+        const char* str_ = str;
+        if (*str == '.')
+        {
+            ++str;
+            if (!*str || *str == '\\' || *str == '/')
+                return str;
+        }
+
+        return 0;
+    }
+
     std::string XmlWalker::connectPath(const char* currentPath, const char* str)
     {
         std::string s;
-        if (str[0] == '.' && (str[1] == '/' || str[1] == '\\'))
+
+        const char* rl = isRelative(str);
+        if (rl)
         {
             s = currentPath;
-            s += str + 2;
+            s += rl;
             return s;
         }
         return str;
@@ -82,10 +97,10 @@ namespace oxygine
     std::string XmlWalker::getPath(const char* attrName) const
     {
         const char* str = _root.attribute(attrName).as_string();
-        if (str[0] == '.' && (str[1] == '/' || str[1] == '\\'))
+        const char* rl = isRelative(str);
+        if (rl)
         {
-            str += 2;
-            return *_xmlFolder + str;
+            return *_xmlFolder + rl;
         }
 
         return _path + str;

+ 8 - 0
oxygine/src/res/ResAnim.cpp

@@ -2,6 +2,7 @@
 #include "Image.h"
 #include "core/NativeTexture.h"
 #include "core/VideoDriver.h"
+#include "Resources.h"
 
 namespace oxygine
 {
@@ -108,6 +109,13 @@ namespace oxygine
     }
 
 
+    const Resources* ResAnim::getResources() const
+    {
+        const Resource* parent = getParent()->getParent();
+        const Resources* p = safeCast<const Resources*>(parent);
+        return p;
+    }
+
     const AnimationFrame& ResAnim::getFrame(int col, int row) const
     {
         int i = row * _columns + col;

+ 1 - 0
oxygine/src/res/ResAnim.h

@@ -36,6 +36,7 @@ namespace oxygine
         int                     getRows() const {return (int)_frames.size() / _columns;}
         int                     getTotalFrames() const {return (int)_frames.size();}
         int                     getFrameRate() const { return _framerate; }
+        const Resources*        getResources() const;
         const AnimationFrame&   getFrame(int col, int row) const;
         /**returns frame by index ignoring cols and rows*/
         const AnimationFrame&   getFrame(int index) const;

+ 2 - 1
oxygine/src/res/ResAtlas.h

@@ -30,8 +30,9 @@ namespace oxygine
         ~ResAtlas();
 
         void addAtlas(TextureFormat tf, const std::string& base, const std::string& alpha, int w, int h);
+
         const atlas& getAtlas(int i) const {return _atlasses[i];}
-        int getNum() const { return (int)_atlasses.size(); }
+        int          getNum() const { return (int)_atlasses.size(); }
 
     protected:
         void _restore(Restorable* r, void* user);

+ 21 - 3
oxygine/src/res/ResFontBM.cpp

@@ -348,8 +348,6 @@ namespace oxygine
             }
         }
 
-
-
         // chars blocks
         for (int i = 0; i < numChars; i++)
         {
@@ -409,12 +407,14 @@ 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);
         }
 
         _font->sortGlyphs();
+        _finalize();
     }
     /////////////////////////////////////////////////////////
 
@@ -436,6 +436,23 @@ namespace oxygine
         _pages.push_back(p);
     }
 
+    void ResFontBM::_finalize()
+    {
+        glyphOptions opt = 0;
+        const glyph* g = _font->getGlyph(0xA0, opt);
+        if (g)
+            return;
+
+        g = _font->getGlyph(' ', opt);
+        if (!g)
+            return;
+
+        glyph p = *g;
+        p.ch = 0xA0;
+        _font->addGlyph(p);
+
+    }
+
     void ResFontBM::_createFont(CreateResourceContext* context, bool sd, bool bmc, int downsample)
     {
         _sdf = sd;
@@ -526,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())
@@ -585,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);
@@ -593,6 +610,7 @@ namespace oxygine
         }
 
         font->sortGlyphs();
+        _finalize();
     }
 
     void ResFontBM::_unload()

+ 1 - 1
oxygine/src/res/ResFontBM.h

@@ -15,7 +15,6 @@ namespace oxygine
 
     class ResFontBM: public ResFont
     {
-        INHERITED(ResFont);
     public:
         static Resource* create(CreateResourceContext& context);
         static Resource* createBM(CreateResourceContext& context);
@@ -49,6 +48,7 @@ namespace oxygine
         void _restore(Restorable*, void*);
         void _createFont(CreateResourceContext* context, bool sd, bool bmc, int downsample);
         void _createFontFromTxt(CreateResourceContext* context, char* fontData, const std::string& fontPath, int downsample);
+        void _finalize();
 
         typedef std::vector<page> pages;
         pages _pages;

+ 1 - 2
oxygine/src/res/Resource.h

@@ -62,5 +62,4 @@ namespace oxygine
 }
 
 
-EDITOR_INCLUDE(Resource);
-
+EDITOR_INCLUDE(Resource);

+ 12 - 1
oxygine/src/res/Resources.cpp

@@ -317,7 +317,18 @@ namespace oxygine
         if (accessByShortenID)
         {
             std::string shortName = path::extractFileName(name);
-            _resourcesMap[shortName] = r;
+            if (shortName != name)
+            {
+#ifdef OX_DEBUG
+                OX_ASSERT(_resourcesMap.find(shortName) == _resourcesMap.end());
+                if (_resourcesMap.find(shortName) != _resourcesMap.end())
+                {
+                    log::error("short resource name '%s' conflicts with '%s'", r->getName().c_str(), _resourcesMap[shortName]->getName().c_str());
+                }
+#endif
+
+                _resourcesMap[shortName] = r;
+            }
         }
     }
 

+ 1 - 1
oxygine/src/text_utils/Aligner.cpp

@@ -102,7 +102,7 @@ namespace oxygine
 
         int Aligner::getLineSkip() const
         {
-            return _font->getBaselineDistance() + getStyle().linesOffset;
+            return _font->getBaselineDistance() * getStyle().baselineScale + getStyle().linesOffset;
         }
 
         void Aligner::_alignLine(line& ln)

+ 3 - 2
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())
                 {
@@ -176,7 +177,7 @@ namespace oxygine
                         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;

+ 8 - 2
tools/resbuild/xml_processor.py

@@ -43,24 +43,30 @@ class XmlWalker:
 
     def getPath(self, attr):
         path = self.root.getAttribute(attr)
+
         if path.startswith("./") or path.startswith(".\\"):
             return self.xml_folder + path[2:len(path)]
 
+        if path == ".":
+            return self.xml_folder
+
         return self.path + path
 
     def setSrcFullPath(self, path):
         return self.src + path
 
+
     def checkSetAttributes(self):
         self._checkSetAttributes(self.root)
 
     def _checkSetAttributes(self, node):
         path = node.getAttribute("path")
         if path:
-            if 0:
-                path = ""
             if path.startswith("./") or path.startswith(".\\"):
                 path = self.xml_folder + path[2:len(path)]
+            elif path == ".":
+                path = self.xml_folder
+
             self.path = path + "/"
 
         scale_factor = node.getAttribute("scale_factor")